diff options
author | Joel Kronqvist <joel.kronqvist@iki.fi> | 2025-08-12 20:15:30 +0300 |
---|---|---|
committer | Joel Kronqvist <joel.kronqvist@iki.fi> | 2025-08-12 20:15:30 +0300 |
commit | ec13c45c8ae0f63fa715178308547cfadd8f8c39 (patch) | |
tree | 94b69a54861437b525e3fc2832118413b94baed2 /src/sexp/step.rs | |
parent | a8a4c5b567ea6a58809dc8232ea5f1d3c93879b9 (diff) | |
download | myslip-ec13c45c8ae0f63fa715178308547cfadd8f8c39.tar.gz myslip-ec13c45c8ae0f63fa715178308547cfadd8f8c39.zip |
feat: pattern matching evaluation in step.rs
Diffstat (limited to 'src/sexp/step.rs')
-rw-r--r-- | src/sexp/step.rs | 29 |
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 // --------------------------------------------------------- |