Fix bug with nested function scopes
This commit is contained in:
parent
e40782739d
commit
63ef1451d9
@ -11,6 +11,7 @@ enum NameType {
|
|||||||
//TODO eventually this needs to support closures
|
//TODO eventually this needs to support closures
|
||||||
Param(u8), //TODO handle implications of functions being limited to 255 params
|
Param(u8), //TODO handle implications of functions being limited to 255 params
|
||||||
LocalVariable(ItemId),
|
LocalVariable(ItemId),
|
||||||
|
LocalFunction(ItemId),
|
||||||
Import(Fqsn),
|
Import(Fqsn),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +68,13 @@ impl<'a> ScopeResolver<'a> {
|
|||||||
let fqsn = Fqsn { scopes: vec![lscope, ScopeSegment::Name(local_name.clone())] };
|
let fqsn = Fqsn { scopes: vec![lscope, ScopeSegment::Name(local_name.clone())] };
|
||||||
self.symbol_table.add_symbol(id, fqsn, spec);
|
self.symbol_table.add_symbol(id, fqsn, spec);
|
||||||
}
|
}
|
||||||
|
Some(NameType::LocalFunction(item_id)) => {
|
||||||
|
let def_id = self.symbol_table.id_to_def.get(item_id);
|
||||||
|
if let Some(def_id) = def_id {
|
||||||
|
let def_id = def_id.clone();
|
||||||
|
self.symbol_table.id_to_def.insert(*id, def_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some(NameType::LocalVariable(item_id)) => {
|
Some(NameType::LocalVariable(item_id)) => {
|
||||||
let def_id = self.symbol_table.id_to_def.get(item_id);
|
let def_id = self.symbol_table.id_to_def.get(item_id);
|
||||||
if let Some(def_id) = def_id {
|
if let Some(def_id) = def_id {
|
||||||
@ -139,6 +147,8 @@ impl<'a> ASTVisitor for ScopeResolver<'a> {
|
|||||||
new_scope.insert(param, NameType::Param(n as u8));
|
new_scope.insert(param, NameType::Param(n as u8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.lexical_scopes.insert(signature.name.clone(), NameType::LocalFunction(*id));
|
||||||
|
|
||||||
let mut new_resolver =
|
let mut new_resolver =
|
||||||
ScopeResolver { symbol_table: self.symbol_table, lexical_scopes: new_scope };
|
ScopeResolver { symbol_table: self.symbol_table, lexical_scopes: new_scope };
|
||||||
walk_block(&mut new_resolver, block);
|
walk_block(&mut new_resolver, block);
|
||||||
|
@ -78,6 +78,44 @@ fn scopes() {
|
|||||||
eval_assert(scope_ok, "20");
|
eval_assert(scope_ok, "20");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn eval_scopes_2() {
|
||||||
|
eval_assert(
|
||||||
|
r#"
|
||||||
|
fn trad() {
|
||||||
|
let a = 10
|
||||||
|
fn jinner() {
|
||||||
|
let b = 20
|
||||||
|
b
|
||||||
|
}
|
||||||
|
|
||||||
|
a + jinner()
|
||||||
|
}
|
||||||
|
trad()"#,
|
||||||
|
"30",
|
||||||
|
);
|
||||||
|
|
||||||
|
let err =
|
||||||
|
"No symbol found for name: QualifiedName { id: Id { idx: 4, t: PhantomData }, components: [\"a\"] }";
|
||||||
|
|
||||||
|
eval_assert_failure(
|
||||||
|
r#"
|
||||||
|
fn trad() {
|
||||||
|
let a = 10
|
||||||
|
fn inner() {
|
||||||
|
let b = 20
|
||||||
|
a + b
|
||||||
|
}
|
||||||
|
|
||||||
|
inner()
|
||||||
|
}
|
||||||
|
|
||||||
|
trad()
|
||||||
|
"#,
|
||||||
|
err,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn adt_output_1() {
|
fn adt_output_1() {
|
||||||
let source = r#"
|
let source = r#"
|
||||||
|
Loading…
Reference in New Issue
Block a user