diff --git a/compiler/cl-interpret/src/env.rs b/compiler/cl-interpret/src/env.rs index 6852989..7276a15 100644 --- a/compiler/cl-interpret/src/env.rs +++ b/compiler/cl-interpret/src/env.rs @@ -134,6 +134,18 @@ impl Environment { } Err(Error::NotDefined(id)) } + + pub(crate) fn get_local(&self, id: Sym) -> IResult { + for (frame, _) in self.frames.iter().rev() { + match frame.get(&id) { + Some(Some(var)) => return Ok(var.clone()), + Some(None) => return Err(Error::NotInitialized(id)), + _ => (), + } + } + Err(Error::NotInitialized(id)) + } + /// Inserts a new [ConValue] into this [Environment] pub fn insert(&mut self, id: Sym, value: Option) { if let Some((frame, _)) = self.frames.last_mut() { diff --git a/compiler/cl-interpret/src/function.rs b/compiler/cl-interpret/src/function.rs index df3491d..ea771bb 100644 --- a/compiler/cl-interpret/src/function.rs +++ b/compiler/cl-interpret/src/function.rs @@ -34,7 +34,7 @@ impl Function { pub fn upvars(&self) -> Ref { self.upvars.borrow() } - pub fn lift_upvars(&self, env: &mut Environment) { + pub fn lift_upvars(&self, env: &Environment) { let upvars = collect_upvars(&self.decl, env); if let Ok(mut self_upvars) = self.upvars.try_borrow_mut() { *self_upvars = upvars; diff --git a/compiler/cl-interpret/src/function/collect_upvars.rs b/compiler/cl-interpret/src/function/collect_upvars.rs index 69e4ccd..236a5fc 100644 --- a/compiler/cl-interpret/src/function/collect_upvars.rs +++ b/compiler/cl-interpret/src/function/collect_upvars.rs @@ -28,7 +28,7 @@ impl<'env> CollectUpvars<'env> { if blacklist.contains(name) || upvars.contains_key(name) { return; } - if let Ok(upvar) = env.get(*name) { + if let Ok(upvar) = env.get_local(*name) { upvars.insert(*name, Some(upvar)); } } @@ -61,7 +61,7 @@ impl<'a> Visit<'a> for CollectUpvars<'_> { self.visit_expr(init) } // a bound name can never be an upvar - self.blacklist.insert(*name); + self.bind_name(name); } fn visit_function(&mut self, f: &'a cl_ast::Function) {