Resolver - Superclass environments
This commit is contained in:
parent
d6f03f1429
commit
1a39e40325
1 changed files with 28 additions and 11 deletions
|
@ -38,7 +38,7 @@ enum SymKind {
|
||||||
Variable,
|
Variable,
|
||||||
Function,
|
Function,
|
||||||
Class,
|
Class,
|
||||||
This,
|
Special,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The type of a scope
|
/// The type of a scope
|
||||||
|
@ -168,17 +168,17 @@ impl<'a> ResolverState<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Declare and define the "this" value for the current scope.
|
/// Declare and define a special symbol (e.g. this) for the current scope.
|
||||||
fn define_this(&mut self) {
|
fn define_special(&mut self, name: &str) {
|
||||||
assert!(!self.scopes.is_empty());
|
assert!(!self.scopes.is_empty());
|
||||||
let idx = self.scopes.len() - 1;
|
let idx = self.scopes.len() - 1;
|
||||||
let scope = &mut self.scopes[idx];
|
let scope = &mut self.scopes[idx];
|
||||||
assert!(!scope.symbols.contains_key("this"));
|
assert!(!scope.symbols.contains_key(name));
|
||||||
scope.symbols.insert(
|
scope.symbols.insert(
|
||||||
"this".to_owned(),
|
name.to_owned(),
|
||||||
SymInfo {
|
SymInfo {
|
||||||
decl: None,
|
decl: None,
|
||||||
kind: SymKind::This,
|
kind: SymKind::Special,
|
||||||
state: SymState::Defined,
|
state: SymState::Defined,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -312,16 +312,30 @@ where
|
||||||
/// Process all method definitions in a class.
|
/// Process all method definitions in a class.
|
||||||
fn resolve_class<'a, 'b>(
|
fn resolve_class<'a, 'b>(
|
||||||
rs: &mut ResolverState<'a>,
|
rs: &mut ResolverState<'a>,
|
||||||
|
has_superclass: bool,
|
||||||
methods: &'b [ClassMemberDecl],
|
methods: &'b [ClassMemberDecl],
|
||||||
) -> ResolverResult
|
) -> ResolverResult
|
||||||
where
|
where
|
||||||
'b: 'a,
|
'b: 'a,
|
||||||
{
|
{
|
||||||
let mut uniqueness = HashSet::new();
|
let mut uniqueness = HashSet::new();
|
||||||
rs.define_this();
|
let mut rc = |rs: &mut ResolverState<'a>| {
|
||||||
methods
|
rs.define_special("this");
|
||||||
.iter()
|
methods
|
||||||
.try_for_each(|member| resolve_class_member(rs, member, &mut uniqueness))
|
.iter()
|
||||||
|
.try_for_each(|member| resolve_class_member(rs, member, &mut uniqueness))
|
||||||
|
};
|
||||||
|
if has_superclass {
|
||||||
|
rs.with_scope(
|
||||||
|
|rs| {
|
||||||
|
rs.define_special("super");
|
||||||
|
rc(rs)
|
||||||
|
},
|
||||||
|
rs.current_type(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
rc(rs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper trait used to visit the various AST nodes with the resolver.
|
/// Helper trait used to visit the various AST nodes with the resolver.
|
||||||
|
@ -387,7 +401,10 @@ impl VarResolver for StmtNode {
|
||||||
rs.resolve_use(superclass)?;
|
rs.resolve_use(superclass)?;
|
||||||
}
|
}
|
||||||
rs.define(&decl.name);
|
rs.define(&decl.name);
|
||||||
rs.with_scope(|rs| resolve_class(rs, &decl.members), rs.current_type())
|
rs.with_scope(
|
||||||
|
|rs| resolve_class(rs, decl.superclass.is_some(), &decl.members),
|
||||||
|
rs.current_type(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
StmtNode::If {
|
StmtNode::If {
|
||||||
|
|
Loading…
Reference in a new issue