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

View File

@ -482,7 +482,23 @@ pub fn eval<'src, 'a>(
Ast::Pair(..) => { Ast::Pair(..) => {
unreachable!() unreachable!()
} }
Ast::Loop(_, _) => todo!(), Ast::Loop(init, clauses) => {
Ast::Recur(_) => todo!(), 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))
}
} }
} }