Fix bug with loops

This commit is contained in:
Greg Shuflin 2021-11-02 01:16:08 -07:00
parent d4b00b008b
commit e2f39dd7b9
2 changed files with 28 additions and 2 deletions

View File

@ -56,7 +56,6 @@ impl<'a, 'b> Evaluator<'a, 'b> {
} }
fn block(&mut self, statements: Vec<Statement>) -> EvalResult<Primitive> { fn block(&mut self, statements: Vec<Statement>) -> EvalResult<Primitive> {
//TODO need to handle breaks, returns, etc.
let mut retval = None; let mut retval = None;
for stmt in statements.into_iter() { for stmt in statements.into_iter() {
match self.statement(stmt)? { match self.statement(stmt)? {
@ -69,6 +68,7 @@ impl<'a, 'b> Evaluator<'a, 'b> {
break; break;
} }
if let Some(_) = self.loop_control { if let Some(_) = self.loop_control {
println!("We here?");
break; break;
} }
} }
@ -142,6 +142,7 @@ impl<'a, 'b> Evaluator<'a, 'b> {
Expression::Assign { ref lval, box rval } => { Expression::Assign { ref lval, box rval } => {
let mem = lval.into(); let mem = lval.into();
let evaluated = self.expression(rval)?; let evaluated = self.expression(rval)?;
println!("Inserting {:?} into {:?}", evaluated, mem);
self.state.environments.insert(mem, MemoryValue::Primitive(evaluated)); self.state.environments.insert(mem, MemoryValue::Primitive(evaluated));
Primitive::unit() Primitive::unit()
} }
@ -206,6 +207,7 @@ impl<'a, 'b> Evaluator<'a, 'b> {
) -> EvalResult<Primitive> { ) -> EvalResult<Primitive> {
loop { loop {
let cond = self.expression(cond.clone())?; let cond = self.expression(cond.clone())?;
println!("COND: {:?}", cond);
match cond { match cond {
Primitive::Literal(Literal::Bool(true)) => (), Primitive::Literal(Literal::Bool(true)) => (),
Primitive::Literal(Literal::Bool(false)) => break, Primitive::Literal(Literal::Bool(false)) => break,
@ -214,7 +216,10 @@ impl<'a, 'b> Evaluator<'a, 'b> {
//TODO eventually loops shoudl be able to return something //TODO eventually loops shoudl be able to return something
let _output = self.block(statements.clone())?; let _output = self.block(statements.clone())?;
match self.loop_control { match self.loop_control {
None | Some(LoopControlFlow::Continue) => (), None => (),
Some(LoopControlFlow::Continue) => {
self.loop_control = None;
}
Some(LoopControlFlow::Break) => { Some(LoopControlFlow::Break) => {
break; break;
} }

View File

@ -467,3 +467,24 @@ count
"#; "#;
eval_assert(source, "500"); eval_assert(source, "500");
} }
#[test]
fn loops_2() {
let source = r#"
let mut a = 0
let mut acc = 0
while a < 10 {
acc = acc + 1
a = a + 1
// Without this continue, the output would be 20
if a == 5 then {
continue
}
acc = acc + 1
}
acc"#;
eval_assert(source, "19");
}