diff options
Diffstat (limited to 'src/sexp/step.rs')
-rw-r--r-- | src/sexp/step.rs | 34 |
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) |