aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Kronqvist <joel.kronqvist@iki.fi>2025-08-15 11:27:34 +0300
committerJoel Kronqvist <joel.kronqvist@iki.fi>2025-08-15 11:27:34 +0300
commit322f541d6922422e5a4aa29f50c6534517ee85be (patch)
treebc7180f4c1b21318a757fce046465f12cad9de74
parent6f0c1b4a28b42f9c498e968964fffb511c9c9f36 (diff)
downloadmyslip-322f541d6922422e5a4aa29f50c6534517ee85be.tar.gz
myslip-322f541d6922422e5a4aa29f50c6534517ee85be.zip
fix: subst not respecting fn and case binds
-rw-r--r--src/sexp/subst.rs29
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(),