variables defined using def in a let statement now escape local scope

test added as well.
This commit is contained in:
Ava Apples Affine 2023-03-17 12:01:43 -07:00
parent 3848d3bcfa
commit 2dfe73de6b
Signed by: affine
GPG key ID: 3A4645B8CF806069
3 changed files with 37 additions and 0 deletions

View file

@ -111,6 +111,7 @@ Since the call to some-func is the final form, its value is returned.";
pub fn let_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
let mut localsyms = syms.clone();
let mut locals = vec![];
let locals_form: &Seg;
let eval_forms: &Seg;
if let Ctr::Seg(ref locals_form_list) = *ast.car {
@ -156,6 +157,7 @@ pub fn let_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
&Seg::from_mono(Box::new(*var_val_res.unwrap().clone())),
None),
);
locals.push(name.clone());
}
} else if let Ctr::None = *var_form.car {
// nothing to declare
@ -201,6 +203,17 @@ pub fn let_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
return Err("evaluation failure".to_string());
}
// we need to get any var declared from within the let eval forms
// those need to exist in the outside context
for i in localsyms.iter() {
if !locals.contains(i.0) && !syms.contains_key(i.0) {
syms.insert(
i.0.clone(),
i.1.clone(),
);
}
}
Ok((*result).clone())
}

View file

@ -79,6 +79,10 @@ impl SymTable {
self.0.get(arg)
}
pub fn contains_key(&self, arg: &String) -> bool {
self.0.contains_key(arg)
}
pub fn insert(&mut self, k: String, v: Symbol) -> Option<Symbol> {
self.0.insert(k, v)
}