refactor process to use visit method everywhere

This commit is contained in:
Scott Richmond 2024-12-11 19:11:40 -05:00
parent ecc7b26b66
commit 229470fee3
2 changed files with 14 additions and 30 deletions

View File

@ -182,9 +182,10 @@ pub fn run(src: &'static str) {
pub fn main() { pub fn main() {
let src = " let src = "
when { let guard = :nil
false -> :false match :foo with {
true -> :true :foo if guard -> :guarded
_ -> :unguarded
} }
"; ";
run(src); run(src);

View File

@ -60,12 +60,6 @@ impl<'src> Process<'src> {
self.locals.push((word, value.clone())); 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<T>(&self, x: T, y: T) -> Option<&Process<'src>> pub fn match_eq<T>(&self, x: T, y: T) -> Option<&Process<'src>>
where where
T: PartialEq, T: PartialEq,
@ -134,7 +128,7 @@ impl<'src> Process<'src> {
let list = Value::List(list); let list = Value::List(list);
self.match_pattern(&patt.0, &list); self.match_pattern(&patt.0, &list);
} else if self.match_pattern(&x[i].0, &y[i]).is_none() { } else if self.match_pattern(&x[i].0, &y[i]).is_none() {
self.pop_to(to); self.locals.truncate(to);
return None; return None;
} }
} }
@ -151,7 +145,7 @@ impl<'src> Process<'src> {
let list = Value::List(y.skip(i)); let list = Value::List(y.skip(i));
self.match_pattern(&patt.0, &list); self.match_pattern(&patt.0, &list);
} else if self.match_pattern(patt, y.get(i).unwrap()).is_none() { } else if self.match_pattern(patt, y.get(i).unwrap()).is_none() {
self.pop_to(to); self.locals.truncate(to);
return None; return None;
} }
} }
@ -172,7 +166,7 @@ impl<'src> Process<'src> {
PairPattern(key, patt) => { PairPattern(key, patt) => {
if let Some(val) = y.get(key) { if let Some(val) = y.get(key) {
if self.match_pattern(&patt.0, val).is_none() { if self.match_pattern(&patt.0, val).is_none() {
self.pop_to(to); self.locals.truncate(to);
return None; return None;
} else { } else {
matched.push(key); matched.push(key);
@ -210,31 +204,23 @@ impl<'src> Process<'src> {
clauses: &'src [Spanned<Ast>], clauses: &'src [Spanned<Ast>],
) -> LResult<'src> { ) -> LResult<'src> {
{ {
let parent = self.ast; let root = self.ast;
let to = self.locals.len(); let to = self.locals.len();
let mut clauses = clauses.iter(); let mut clauses = clauses.iter();
while let Some((Ast::MatchClause(patt, guard, body), _)) = clauses.next() { while let Some((Ast::MatchClause(patt, guard, body), _)) = clauses.next() {
if self.match_pattern(&patt.0, value).is_some() { if self.match_pattern(&patt.0, value).is_some() {
let pass_guard = match guard.as_ref() { let pass_guard = match guard.as_ref() {
None => true, None => true,
Some((ast, _)) => { Some(guard_expr) => self.visit(guard_expr)?.bool(),
self.ast = ast;
let guard_res = self.eval();
match &guard_res {
Err(_) => return guard_res,
Ok(val) => val.bool(),
}
}
}; };
if !pass_guard { if !pass_guard {
self.pop_to(to); self.locals.truncate(to);
continue; continue;
} }
self.ast = &body.0; let result = self.visit(body);
let res = self.eval(); self.locals.truncate(to);
self.pop_to(to); self.ast = root;
self.ast = parent; return result;
return res;
} }
} }
Err(LErr::new("no match".to_string())) Err(LErr::new("no match".to_string()))
@ -467,9 +453,6 @@ impl<'src> Process<'src> {
Fn(name, clauses, doc) => { Fn(name, clauses, doc) => {
let doc = doc.map(|s| s.to_string()); let doc = doc.map(|s| s.to_string());
let ptr: *const Ast = root_node; let ptr: *const Ast = root_node;
// dbg!(&root);
// dbg!(&ptr);
// dbg!(&self.fn_info);
let info = self.fn_info.get(&ptr).unwrap(); let info = self.fn_info.get(&ptr).unwrap();
let FnInfo::Defined(_, _, enclosing) = info else { let FnInfo::Defined(_, _, enclosing) = info else {
unreachable!() unreachable!()