Add local variable collection to compilation
* Upon entering a new body, the local scope variables are collected. * VM instruction PushLocal now uses a `Local` value instead of a `Sym` value * Compilation of a new AST body will implicitly create a new scope Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -213,7 +213,10 @@ impl<'c, 't> CompileBody<'c, 't> {
|
||||
}
|
||||
|
||||
pub fn compile(&mut self, body: &'c Body) -> Result<Thunk> {
|
||||
self.visit_body(body)
|
||||
self.compile.push_scope_layer();
|
||||
let thunk = self.visit_body(body)?;
|
||||
self.compile.pop_scope_layer();
|
||||
Ok(thunk)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,6 +231,7 @@ impl Visit for CompileBody<'_, '_> {
|
||||
type Out = Result<Thunk>;
|
||||
|
||||
fn visit_body(&mut self, body: &Body) -> Self::Out {
|
||||
self.compile.collect_locals(body);
|
||||
let mut thunk = Thunk::Nop;
|
||||
|
||||
for stmt in body.body.iter() {
|
||||
@@ -342,14 +346,10 @@ impl Visit for CompileBody<'_, '_> {
|
||||
fn visit_atom(&mut self, atom: &Atom) -> Self::Out {
|
||||
let thunk = match atom {
|
||||
Atom::Ident(ident) => {
|
||||
// TODO : set up lexical name stack
|
||||
// - think about how lexical names in function defs need to be captured, so no
|
||||
// references get prematurely GC'd
|
||||
// - Python uses LOAD_CLOSURE and CREATE_FUNCTION ops, but is this necessary if we
|
||||
// know the names being closed over at runtime? Hm.
|
||||
|
||||
let sym = global_sym(ident.to_string());
|
||||
let local = self.compile.lookup_scope(sym).unwrap();
|
||||
// get local
|
||||
Inst::PushLocal(global_sym(ident.to_string())).into()
|
||||
Inst::PushLocal(local).into()
|
||||
}
|
||||
Atom::Sym(sym) => {
|
||||
// push symbol
|
||||
|
||||
Reference in New Issue
Block a user