Add name-scanning pass to compiler
Compile::discover_locals now takes a Vec<SpExpr> instead of a single SpExpr. It is also called before the compiler starts building the list of instructions so that all names in the scope are available at compile-time. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -1,8 +1,5 @@
|
|||||||
[ :x x x ] :dup
|
[ :x x x ] :dup
|
||||||
|
|
||||||
# This a dumb little workaround to allow for recursion so factorial inside of
|
|
||||||
# the function definition will look in the correct scope
|
|
||||||
0 :factorial
|
|
||||||
[
|
[
|
||||||
dup!
|
dup!
|
||||||
[dup! 1 -! factorial! *!]
|
[dup! 1 -! factorial! *!]
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ impl<'s> Compile<'s> {
|
|||||||
// Local scopes are implicit. If a variable is assigned to at
|
// Local scopes are implicit. If a variable is assigned to at
|
||||||
// all in the current scope, it's considered to be a local.
|
// all in the current scope, it's considered to be a local.
|
||||||
let mut code = Vec::new();
|
let mut code = Vec::new();
|
||||||
|
self.discover_locals(&expr_list);
|
||||||
for expr in expr_list {
|
for expr in expr_list {
|
||||||
self.discover_locals(&expr);
|
|
||||||
code.extend(self.compile_expr(&expr));
|
code.extend(self.compile_expr(&expr));
|
||||||
}
|
}
|
||||||
code
|
code
|
||||||
@@ -102,11 +102,13 @@ impl<'s> Compile<'s> {
|
|||||||
///
|
///
|
||||||
/// If any assignment for a local variable appears in the scope, it will be
|
/// If any assignment for a local variable appears in the scope, it will be
|
||||||
/// inserted.
|
/// inserted.
|
||||||
fn discover_locals(&mut self, expr: &SpExpr) {
|
fn discover_locals(&mut self, exprs: &Vec<SpExpr>) {
|
||||||
|
for expr in exprs.iter() {
|
||||||
if let Expr::Atom(atom) = expr.inner() {
|
if let Expr::Atom(atom) = expr.inner() {
|
||||||
if let Atom::Assign(text) = atom.inner() {
|
if let Atom::Assign(text) = atom.inner() {
|
||||||
self.scope_stack.insert_local(text);
|
self.scope_stack.insert_local(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user