aboutsummaryrefslogtreecommitdiff
path: root/src/sexp/step.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/sexp/step.rs')
-rw-r--r--src/sexp/step.rs29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/sexp/step.rs b/src/sexp/step.rs
index fd6be9e..97675fa 100644
--- a/src/sexp/step.rs
+++ b/src/sexp/step.rs
@@ -349,6 +349,35 @@ impl SExp {
None => panic!("unreachable as per match guard arm"),
},
+ // case expressions
+ SCons(op, l) if scons(op.clone(), l.clone()).check_case().is_some() => {
+ let (scrutinee, patarms) = scons(op, l).check_case().unwrap();
+
+ let scrutinee = match scrutinee {
+ SCons(q, v) if *q == Atom(Quote) || *q == Atom(Vector) => *v,
+ t => t,
+ };
+
+ for patarm in patarms {
+ let (pat, arm) = match patarm {
+ SCons(pat, arm) => Ok((*pat, *arm)),
+ _ => Err("unreachable after type checking".to_string())
+ }?;
+ let mut arm = match arm {
+ SCons(x, n) if *n == Atom(Nil) => *x,
+ t => t,
+ };
+
+ if let Some(ctx) = scrutinee.matches_pat(&pat) {
+ for (name, value) in ctx {
+ arm = arm.subst(&name, &value);
+ }
+ return Ok(arm);
+ }
+ }
+ Err("This should be unreachable after type checking".to_string())
+ },
+
// op value and a1 .. an values, and b0, b1 .. bn not values
// ---------------------------------------------------------