cl-interpret: Use dyn dispatch for
iterators.
- This is a hack because the language has the syntax but no concept of iterators
This commit is contained in:
parent
145a24c5ff
commit
5db77db6b8
@ -753,16 +753,19 @@ impl Interpret for If {
|
|||||||
impl Interpret for For {
|
impl Interpret for For {
|
||||||
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
||||||
let Self { bind: name, cond, pass, fail } = self;
|
let Self { bind: name, cond, pass, fail } = self;
|
||||||
|
let cond = cond.interpret(env)?;
|
||||||
// TODO: A better iterator model
|
// TODO: A better iterator model
|
||||||
let mut bounds = match cond.interpret(env)? {
|
let mut bounds: Box<dyn Iterator<Item = ConValue>> = match &cond {
|
||||||
ConValue::RangeExc(a, b) => a..=b,
|
&ConValue::RangeExc(a, b) => Box::new((a..b).map(ConValue::Int)),
|
||||||
ConValue::RangeInc(a, b) => a..=b,
|
&ConValue::RangeInc(a, b) => Box::new((a..=b).map(ConValue::Int)),
|
||||||
|
ConValue::Array(a) => Box::new(a.iter().cloned()),
|
||||||
|
ConValue::String(s) => Box::new(s.chars().map(ConValue::Char)),
|
||||||
_ => Err(Error::TypeError)?,
|
_ => Err(Error::TypeError)?,
|
||||||
};
|
};
|
||||||
loop {
|
loop {
|
||||||
let mut env = env.frame("loop variable");
|
let mut env = env.frame("loop variable");
|
||||||
if let Some(loop_var) = bounds.next() {
|
if let Some(loop_var) = bounds.next() {
|
||||||
env.insert(*name, Some(loop_var.into()));
|
env.insert(*name, Some(loop_var));
|
||||||
match pass.interpret(&mut env) {
|
match pass.interpret(&mut env) {
|
||||||
Err(Error::Break(value)) => return Ok(value),
|
Err(Error::Break(value)) => return Ok(value),
|
||||||
Err(Error::Continue) => continue,
|
Err(Error::Continue) => continue,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user