parse loop and recur

This commit is contained in:
Scott Richmond 2024-11-21 16:57:52 -05:00
parent dbff31be40
commit 423f43b7fd
2 changed files with 22 additions and 2 deletions

View File

@ -25,10 +25,12 @@ pub enum Value<'src> {
// ref-counted, immutable, persistent
List(Vector<Self>),
// ref-counted, immutable, persistent
// dicts may only use keywords as keys
Dict(HashMap<&'src str, Self>),
Box(&'src str, Rc<RefCell<Self>>),
Fn(Rc<Fn<'src>>),
Base(Base<'src>),
Recur(Vec<Self>),
// Set(HashSet<Self>),
// Sets are hard
// Sets require Eq
@ -57,6 +59,7 @@ impl<'src> Clone for Value<'src> {
Value::Box(name, b) => Value::Box(name, b.clone()),
Value::Placeholder => Value::Placeholder,
Value::Base(b) => Value::Base(b.clone()),
Value::Recur(..) => unreachable!(),
}
}
}
@ -111,6 +114,7 @@ impl<'src> fmt::Display for Value<'src> {
};
write!(f, "base fn {}", name)
}
Value::Recur(..) => unreachable!(),
}
}
}

View File

@ -482,7 +482,23 @@ pub fn eval<'src, 'a>(
Ast::Pair(..) => {
unreachable!()
}
Ast::Loop(_, _) => todo!(),
Ast::Recur(_) => todo!(),
Ast::Loop(init, clauses) => {
let mut args = eval(&init.0, ctx)?;
loop {
let result = match_clauses(&args, clauses, ctx)?;
if let Value::Recur(recur_args) = result {
args = Value::Tuple(Rc::new(recur_args));
} else {
return Ok(result);
}
}
}
Ast::Recur(args) => {
let mut vect = Vec::new();
for arg in args {
vect.push(eval(&arg.0, ctx)?);
}
Ok(Value::Recur(vect))
}
}
}