diff options
author | Joel Kronqvist <joel.kronqvist@iki.fi> | 2025-08-15 11:27:34 +0300 |
---|---|---|
committer | Joel Kronqvist <joel.kronqvist@iki.fi> | 2025-08-15 11:27:34 +0300 |
commit | 322f541d6922422e5a4aa29f50c6534517ee85be (patch) | |
tree | bc7180f4c1b21318a757fce046465f12cad9de74 | |
parent | 6f0c1b4a28b42f9c498e968964fffb511c9c9f36 (diff) | |
download | myslip-322f541d6922422e5a4aa29f50c6534517ee85be.tar.gz myslip-322f541d6922422e5a4aa29f50c6534517ee85be.zip |
fix: subst not respecting fn and case binds
-rw-r--r-- | src/sexp/subst.rs | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/src/sexp/subst.rs b/src/sexp/subst.rs index 4cfa48d..d09732f 100644 --- a/src/sexp/subst.rs +++ b/src/sexp/subst.rs @@ -23,6 +23,35 @@ impl SExp { return SCons(a, b); } } + if scons(a.clone(), b.clone()).is_fun() { + let arglist = b.clone().parts()[0].clone(); + let arglist = arglist.parts().into_iter().map(|exp| match exp { + Atom(Var(s)) => s, + _ => todo!(), + }).collect::<Vec<String>>(); + if arglist.contains(&name.to_string()) { + return SCons(a, b); + } + } + if let Some((scrut, pavec)) = scons(a.clone(), b.clone()) + .get_case_scrut_pats_and_arms() + { + let scrut = scrut.subst(name, value); + let mut res = vec![]; + for (pat, arm) in pavec { + if pat + .get_vars_bound_by_pattern() + .contains(&name.to_string()) + { + res.push(scons(pat, arm)); + } + else + { + res.push(scons(pat, arm.subst(name, value))); + } + } + return SExp::back_to_case(scrut, res); + } scons((*a).subst(name, value), (*b).subst(name, value)) }, Atom(Var(x)) if x == name => value.clone(), |