From 229470fee3bf0946f9150f2460cd04cf3d603bbb Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Wed, 11 Dec 2024 19:11:40 -0500 Subject: [PATCH] refactor process to use `visit` method everywhere --- src/main.rs | 7 ++++--- src/process.rs | 37 ++++++++++--------------------------- 2 files changed, 14 insertions(+), 30 deletions(-) diff --git a/src/main.rs b/src/main.rs index 07ffbd7..9f8b18d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -182,9 +182,10 @@ pub fn run(src: &'static str) { pub fn main() { let src = " -when { - false -> :false - true -> :true +let guard = :nil +match :foo with { + :foo if guard -> :guarded + _ -> :unguarded } "; run(src); diff --git a/src/process.rs b/src/process.rs index 39a618e..8a9cf7d 100644 --- a/src/process.rs +++ b/src/process.rs @@ -60,12 +60,6 @@ impl<'src> Process<'src> { self.locals.push((word, value.clone())); } - pub fn pop_to(&mut self, n: usize) { - while self.locals.len() > n { - self.locals.pop(); - } - } - pub fn match_eq(&self, x: T, y: T) -> Option<&Process<'src>> where T: PartialEq, @@ -134,7 +128,7 @@ impl<'src> Process<'src> { let list = Value::List(list); self.match_pattern(&patt.0, &list); } else if self.match_pattern(&x[i].0, &y[i]).is_none() { - self.pop_to(to); + self.locals.truncate(to); return None; } } @@ -151,7 +145,7 @@ impl<'src> Process<'src> { let list = Value::List(y.skip(i)); self.match_pattern(&patt.0, &list); } else if self.match_pattern(patt, y.get(i).unwrap()).is_none() { - self.pop_to(to); + self.locals.truncate(to); return None; } } @@ -172,7 +166,7 @@ impl<'src> Process<'src> { PairPattern(key, patt) => { if let Some(val) = y.get(key) { if self.match_pattern(&patt.0, val).is_none() { - self.pop_to(to); + self.locals.truncate(to); return None; } else { matched.push(key); @@ -210,31 +204,23 @@ impl<'src> Process<'src> { clauses: &'src [Spanned], ) -> LResult<'src> { { - let parent = self.ast; + let root = self.ast; let to = self.locals.len(); let mut clauses = clauses.iter(); while let Some((Ast::MatchClause(patt, guard, body), _)) = clauses.next() { if self.match_pattern(&patt.0, value).is_some() { let pass_guard = match guard.as_ref() { None => true, - Some((ast, _)) => { - self.ast = ast; - let guard_res = self.eval(); - match &guard_res { - Err(_) => return guard_res, - Ok(val) => val.bool(), - } - } + Some(guard_expr) => self.visit(guard_expr)?.bool(), }; if !pass_guard { - self.pop_to(to); + self.locals.truncate(to); continue; } - self.ast = &body.0; - let res = self.eval(); - self.pop_to(to); - self.ast = parent; - return res; + let result = self.visit(body); + self.locals.truncate(to); + self.ast = root; + return result; } } Err(LErr::new("no match".to_string())) @@ -467,9 +453,6 @@ impl<'src> Process<'src> { Fn(name, clauses, doc) => { let doc = doc.map(|s| s.to_string()); let ptr: *const Ast = root_node; - // dbg!(&root); - // dbg!(&ptr); - // dbg!(&self.fn_info); let info = self.fn_info.get(&ptr).unwrap(); let FnInfo::Defined(_, _, enclosing) = info else { unreachable!()