aboutsummaryrefslogtreecommitdiff
path: root/src/sexp/step.rs
diff options
context:
space:
mode:
authorJoel Kronqvist <joel.kronqvist@iki.fi>2025-08-06 16:23:18 +0300
committerJoel Kronqvist <joel.kronqvist@iki.fi>2025-08-06 16:23:18 +0300
commit313c044b4a878a425aaca6554576f5154ace8ff9 (patch)
tree706bf5e34678622111a23c7045f667c1acbe7c6d /src/sexp/step.rs
parent23b2028bdce46d02209fc2df70fc5468a8beffa8 (diff)
downloadmyslip-313c044b4a878a425aaca6554576f5154ace8ff9.tar.gz
myslip-313c044b4a878a425aaca6554576f5154ace8ff9.zip
Implemented let-bindings
Diffstat (limited to 'src/sexp/step.rs')
-rw-r--r--src/sexp/step.rs34
1 files changed, 33 insertions, 1 deletions
diff --git a/src/sexp/step.rs b/src/sexp/step.rs
index e031fca..816582c 100644
--- a/src/sexp/step.rs
+++ b/src/sexp/step.rs
@@ -240,6 +240,8 @@ impl SExp {
/// ```
///
/// **Let-bindings**
+ ///
+ /// Basic operation:
/// ```rust
/// use myslip::sexp::{SExp::*, SLeaf::*, util::*};
///
@@ -261,7 +263,27 @@ impl SExp {
/// ).step(),
/// Ok(scons(
/// scons(Let, scons(var("x"), scons(5, Nil))), scons(
- /// scons(Add, scons(var("x"), scons(1, Nil))), Nil
+ /// scons(Add, scons(var("x"), scons(4, Nil))), Nil
+ /// )
+ /// ))
+ /// );
+ /// ```
+ ///
+ /// Shadowing:
+ /// ```rust
+ /// use myslip::sexp::{SExp::*, SLeaf::*, util::*};
+ ///
+ /// assert_eq!(
+ /// scons(
+ /// scons(Let, scons(var("x"), scons(4, Nil))),
+ /// scons(
+ /// scons(Let, scons(var("x"), scons(5, Nil))),
+ /// scons(scons(Add, scons(var("x"), scons(4, Nil))), Nil)
+ /// )
+ /// ).step(),
+ /// Ok(scons(
+ /// scons(Let, scons(var("x"), scons(5, Nil))), scons(
+ /// scons(Add, scons(var("x"), scons(4, Nil))), Nil
/// )
/// ))
/// );
@@ -278,6 +300,16 @@ impl SExp {
SCons(op, l) if !(*op).is_value() => Ok(scons(op.step()?, l)),
+ // let binds
+ SCons(op, l) if op.clone().check_let().is_some() => match (*op).check_let() {
+ Some((varname, val)) => Ok(match *l {
+ SCons(a, b) if *b == Atom(Nil) => *a,
+ t => t,
+ }.subst(&varname, &val)),
+ None => panic!("unreachable as per match guard arm"),
+ },
+
+
// op value and a1 .. an values, and b0, b1 .. bn not values
// ---------------------------------------------------------
// (op a1 ... an b) -> (op a1 ... an b0.step() b1 .. bn)