better
This commit is contained in:
parent
134c5abd0f
commit
c954e5af13
|
@ -19,6 +19,17 @@ impl<'a> Scope<'a> {
|
||||||
fn assigned(&mut self, id: Ident) {
|
fn assigned(&mut self, id: Ident) {
|
||||||
self.idents.push((id, Cell::default()));
|
self.idents.push((id, Cell::default()));
|
||||||
}
|
}
|
||||||
|
fn find(&self, id: &Ident) -> &Cell<u16> {
|
||||||
|
let mut cur = Some(self);
|
||||||
|
while let Some(scope) = cur {
|
||||||
|
let Some((_, count)) = scope.idents.iter().rev().find(|i| i.0 == *id) else {
|
||||||
|
cur = scope.parent;
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
panic!("undefined variable");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile(mut e: Expr) {
|
pub fn compile(mut e: Expr) {
|
||||||
|
@ -41,31 +52,19 @@ fn analyze(scope: &mut Scope, e: &mut Expr) {
|
||||||
}
|
}
|
||||||
Expr::Literal(Literal::Ident(id), _) => {
|
Expr::Literal(Literal::Ident(id), _) => {
|
||||||
// lookup literal
|
// lookup literal
|
||||||
let mut cur = &*scope;
|
let count = scope.find(id);
|
||||||
loop {
|
|
||||||
let Some((_, count)) = cur.idents.iter().find(|i| i.0 == *id) else {
|
|
||||||
if let Some(parent) = cur.parent {
|
|
||||||
cur = parent;
|
|
||||||
} else {
|
|
||||||
panic!("undefined variable");
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
count.update(|c| c + 1);
|
count.update(|c| c + 1);
|
||||||
let count = count.get();
|
println!("ref {id} #{}", count.get());
|
||||||
println!("ref {id} #{count}");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// ignore
|
// ignore
|
||||||
Expr::Literal(_, _) => {}
|
Expr::Literal(_, _) => {}
|
||||||
// for recursion..
|
// for recursion..
|
||||||
Expr::Block(a) => {
|
Expr::Block(a) => {
|
||||||
// blocks have their own scope
|
// blocks have their own scope
|
||||||
let mut scope2 = Scope::with_parent(Some(scope));
|
let mut scope = Scope::with_parent(Some(scope));
|
||||||
// analyze the contents in the new scope
|
// analyze the contents in the new scope
|
||||||
for e in &mut a.exprs {
|
for e in &mut a.exprs {
|
||||||
analyze(&mut scope2, e);
|
analyze(&mut scope, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expr::Func(a, b) => {
|
Expr::Func(a, b) => {
|
||||||
|
|
Loading…
Reference in New Issue