diff options
Diffstat (limited to 'src/sexp')
-rw-r--r-- | src/sexp/case.rs | 1 | ||||
-rw-r--r-- | src/sexp/step.rs | 23 | ||||
-rw-r--r-- | src/sexp/util.rs | 8 |
3 files changed, 32 insertions, 0 deletions
diff --git a/src/sexp/case.rs b/src/sexp/case.rs index d78f7ad..eb98446 100644 --- a/src/sexp/case.rs +++ b/src/sexp/case.rs @@ -54,6 +54,7 @@ impl SExp { * ``` */ pub fn matches_pat(&self, pat: &SExp) -> Option<Vec<(String, SExp)>> { + println!("matchin {self} against {pat}"); match (self, pat) { (a, b) if a == b => Some(vec![]), diff --git a/src/sexp/step.rs b/src/sexp/step.rs index 97675fa..bae47a5 100644 --- a/src/sexp/step.rs +++ b/src/sexp/step.rs @@ -286,6 +286,20 @@ impl SExp { /// ); /// ``` /// + /// **Pattern matching** + /// ```rust + /// use myslip::{sexp::{SExp::*, SLeaf::*, util::*}, r#type::{Type::*, util::*}}; + /// use myslip::parse::parsetree::parse_to_ast; + /// + /// let exp = "case (+ 1 2) (3 true) (_ false)"; + /// let exp = parse_to_ast(exp); + /// let exp = exp.and_then(|e| e.step()); + /// let expshould = parse_to_ast("case 3 (3 true) (_ false)"); + /// assert_eq!(exp, expshould); + /// let exp = exp.and_then(|e| e.step()); + /// assert_eq!(exp, Ok(Atom(True))); + /// ``` + /// /// Shadowing: /// ```rust /// use myslip::sexp::{SExp::*, SLeaf::*, util::*}; @@ -352,6 +366,10 @@ impl SExp { // case expressions SCons(op, l) if scons(op.clone(), l.clone()).check_case().is_some() => { let (scrutinee, patarms) = scons(op, l).check_case().unwrap(); + if !scrutinee.is_value() { + return Ok(SExp::back_to_case(scrutinee.step()?, patarms)); + // return scons(Case, scons(scrutinee.step()?)) + } let scrutinee = match scrutinee { SCons(q, v) if *q == Atom(Quote) || *q == Atom(Vector) => *v, @@ -627,6 +645,11 @@ impl SExp { } }, + // Nil in list + SCons(op, l) if *op == Atom(Nil) => { + Ok(scons(Vector, Nil)) + }, + // Print SCons(op, l) if *op == Atom(Print) => { println!("{}", *l); diff --git a/src/sexp/util.rs b/src/sexp/util.rs index 3de45d4..aa7ae18 100644 --- a/src/sexp/util.rs +++ b/src/sexp/util.rs @@ -94,4 +94,12 @@ impl SExp { _ => None, } } + + pub fn back_to_case(scrutinee: SExp, arms: Vec<SExp>) -> SExp { + let mut res = Atom(Nil); + for arm in arms.into_iter().rev() { + res = scons(arm, res); + } + scons(Case, scons(scrutinee, res)) + } } |