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() {
let src = "
when {
false -> :false
true -> :true
let guard = :nil
match :foo with {
:foo if guard -> :guarded
_ -> :unguarded
}
";
run(src);

View File

@ -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<T>(&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<Ast>],
) -> 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!()