refactor process to use visit
method everywhere
This commit is contained in:
parent
ecc7b26b66
commit
229470fee3
|
@ -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);
|
||||
|
|
|
@ -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!()
|
||||
|
|
Loading…
Reference in New Issue
Block a user