aboutsummaryrefslogtreecommitdiff
path: root/src/sexp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sexp')
-rw-r--r--src/sexp/case.rs18
-rw-r--r--src/sexp/step.rs16
2 files changed, 21 insertions, 13 deletions
diff --git a/src/sexp/case.rs b/src/sexp/case.rs
index 40310e4..0c3d82d 100644
--- a/src/sexp/case.rs
+++ b/src/sexp/case.rs
@@ -1,5 +1,5 @@
-use crate::sexp::{SExp, SExp::*, SLeaf::*};
+use crate::sexp::{SExp, SLeaf, SExp::*, SLeaf::*, util::*};
impl SExp {
/**
@@ -20,7 +20,7 @@ impl SExp {
* scons(1, scons(scons(2, scons(3, Nil)), Nil))
* .matches_pat(&var("x")),
* Some(vec![(
- * "x".to_string(),
+ * Var("x".to_string()),
* scons(1, scons(scons(2, scons(3, Nil)), Nil))
* )])
* );
@@ -34,8 +34,8 @@ impl SExp {
* scons(1, scons(scons(2, scons(3, Nil)), Nil))
* .matches_pat(&scons(var("x"), scons(var("y"), Nil))),
* Some(vec![
- * ("x".to_string(), Atom(Int(1))),
- * ("y".to_string(), scons(2, scons(3, Nil)))
+ * (Var("x".to_string()), Atom(Int(1))),
+ * (Var("y".to_string()), scons(2, scons(3, Nil)))
* ])
* );
* ```
@@ -47,24 +47,24 @@ impl SExp {
* scons(1, scons(2, scons(3, Nil)))
* .matches_pat(&scons(var("x"), scons(RestPat("y".to_string()), Nil))),
* Some(vec![
- * ("x".to_string(), Atom(Int(1))),
- * ("y".to_string(), scons(2, scons(3, Nil)))
+ * (Var("x".to_string()), Atom(Int(1))),
+ * (RestPat("y".to_string()), scons(2, scons(3, Nil)))
* ])
* );
* ```
*/
- pub fn matches_pat(&self, pat: &SExp) -> Option<Vec<(String, SExp)>> {
+ pub fn matches_pat(&self, pat: &SExp) -> Option<Vec<(SLeaf, SExp)>> {
match (self, pat) {
(a, b) if a == b => Some(vec![]),
- (a, Atom(Var(name))) => Some(vec![(name.clone(), a.clone())]),
+ (a, Atom(Var(name))) => Some(vec![(Var(name.to_string()), a.clone())]),
(SCons(a1, a2), SCons(b1, b2)) => {
let lefthand = a1.matches_pat(b1);
let checkres = (*b2).check_res_pat();
let righthand = match checkres {
- Some(name) => Some(vec![(name, *a2.clone())]),
+ Some(name) => Some(vec![(RestPat(name.clone()), *a2.clone())]),
None => a2.matches_pat(b2),
};
lefthand.zip(righthand)
diff --git a/src/sexp/step.rs b/src/sexp/step.rs
index 99925ac..9077401 100644
--- a/src/sexp/step.rs
+++ b/src/sexp/step.rs
@@ -352,9 +352,10 @@ impl SExp {
return Ok(SExp::back_to_case(scrutinee.step()?, patarms));
}
- let scrutinee = match scrutinee {
- SCons(q, v) if *q == Atom(Quote) || *q == Atom(Vector) => *v,
- t => t,
+ let (scrutinee, rest_pat_struct) = match scrutinee {
+ SCons(q, v) if *q == Atom(Quote) => (*v, Some(Quote)),
+ SCons(q, v) if *q == Atom(Vector) => (*v, Some(Vector)),
+ t => (t, None),
};
for patarm in patarms {
@@ -369,7 +370,14 @@ impl SExp {
if let Some(ctx) = scrutinee.matches_pat(&pat) {
for (name, value) in ctx {
- arm = arm.subst(&name, &value);
+ arm = match name {
+ Var(name) => arm.subst(&name, &value),
+ RestPat(name) => match rest_pat_struct.clone() {
+ Some(kw) => arm.subst(&name, &scons(kw, value)),
+ None => arm.subst(&name, &value)
+ },
+ _ => panic!("unreachable")
+ };
}
return Ok(arm);
}