框架中部分实现的解释
SymbolPass::var_def
fn var_def(&mut self, v: &'a VarDef<'a>) {
v.ty.set(self.ty(&v.syn_ty, false));
if v.ty.get() == Ty::void() { self.issue(v.loc, VoidVar(v.name)) }
let ok = if let Some((sym, owner)) = self.scopes.lookup(v.name) {
// 在类中定义变量可能产生两种错误,分别为:OverrideVar(与父类定义的变量重名)和ConflictDeclaration(重名的所有其它情形))
// 在函数参数和局部变量中定义时,只要发现旧的定义是参数或局部变量中定义的,就一定是一个ConflictDeclaration
// 这是因为decaf并不允许块级别的variable shadowing(我个人觉得这并不合理,如果允许,写程序会更方便一些,像rust一样的同一个语句块也可以shadow就更方便了)
// 上面说的这些在新语法中都未必成立,所以你可以酌情考虑利用这段代码,但不保证不需要修改
match (self.scopes.cur_owner(), owner) {
(ScopeOwner::Class(c1), ScopeOwner::Class(c2)) if Ref(c1) != Ref(c2) && sym.is_var() =>
self.issue(sym.loc(), OverrideVar(v.name)),
(ScopeOwner::Class(_), ScopeOwner::Class(_)) | (_, ScopeOwner::Param(_)) | (_, ScopeOwner::Local(_)) =>
self.issue(v.loc, ConflictDeclaration { prev: sym.loc(), name: v.name }),
_ => true,
}
} else { true };
if ok {
v.owner.set(Some(self.scopes.cur_owner()));
self.scopes.declare(Symbol::Var(v));
}
}TypeCk::cur_var_def
符号表的输出
Last updated
Was this helpful?