diff --git a/lib/interpreter/interpret.ml b/lib/interpreter/interpret.ml index 08242ef..e0b6214 100644 --- a/lib/interpreter/interpret.ml +++ b/lib/interpreter/interpret.ml @@ -684,7 +684,7 @@ and interpret_expr globals (expr : Compiler.Optimizer.expr) = in (globals, either) (* for in { } *) - | ForInLoop { iterator_name; iteratee; block; pos } -> + | ForInLoop { iterator_name; iteratee; block; pos } -> ( let globals = { globals with @@ -700,23 +700,33 @@ and interpret_expr globals (expr : Compiler.Optimizer.expr) = (Runtime.to_class_name iteratee) |> fail ~globals pos in - ( globals, - Dynarray.fold_left - (fun prev element -> - if Either.is_second prev then prev - else - let temp_globals = - { - globals with - identifiers = Identifiers.push_empty globals.identifiers; - } - in - Identifiers.bind temp_globals.identifiers iterator_name element - |> option_value - ~message:(internal_failure_msg ~globals ~pos __LOC__); - interpret_block temp_globals block) - (First Runtime.Null) iteratee_array ) - >>= fun _ ret_val -> (globals, First ret_val) + let globals, either = + ( globals, + Dynarray.fold_left + (fun prev element -> + if Either.is_second prev then prev + else + let temp_globals = + { + globals with + identifiers = Identifiers.push_empty globals.identifiers; + } + in + Identifiers.bind temp_globals.identifiers iterator_name element + |> option_value + ~message:(internal_failure_msg ~globals ~pos __LOC__); + interpret_block temp_globals block) + (First Runtime.Null) iteratee_array ) + in + match either with + | First ret_val -> (globals, First ret_val) + | Second breaking_type -> ( + match breaking_type with + | Break v -> (globals, First v) + | Continue v -> (globals, First v) + | Error _ -> (globals, either) + | Exit _ -> (globals, either) + | Return _ -> (globals, either))) | WithExpr (assignments, block, pos) -> let module M = (val globals.l) in let post_block_hook = ref None in diff --git a/test/green_specs/regression_continue_decl.sloth b/test/green_specs/regression_continue_decl.sloth new file mode 100644 index 0000000..1527e88 --- /dev/null +++ b/test/green_specs/regression_continue_decl.sloth @@ -0,0 +1,142 @@ +### Program +let l = ["hi", ""] +let res = for file in l { + continue 42 +} + +assert(res == 42) + +# This was never broken, let's ensure it never does +for let i = 0; i < l.length; i = i + 1 { + if l[i] == "" { + continue + } +} + +### Processes +() + +### Ast +((StmtDecl + (ExprStmt + (LetExpr + l + (List + ((String + ((FullString + hi + )) + ) + (String + ((FullString + "" + )) + )) + ) + ))) + (StmtDecl + (ExprStmt + (LetExpr + res + (ForInLoop + (iterator_name + file) + (iteratee + (IdRef + l + )) + (block + ((BreakingStmt + Continue + ((Num + 42 + )) + ))) + (pos + )) + ))) + (StmtDecl + (ExprStmt + (FuncInvoc + (IdRef + assert + ) + ((Equality + (IdRef + res + ) + (Num + 42 + ) + true + )) + ))) + (StmtDecl + (ExprStmt + (ForLoop + (LetExpr + i + (Num + 0 + ) + ) + (Binary + (IdRef + i + ) + (ObjDeref + (IdRef + l + ) + length + ) + Less + ) + (AssignExpr + i + (Binary + (IdRef + i + ) + (Num + 1 + ) + Plus + ) + ) + ((ExprStmt + (IfExpr + (IfCont + (conditional + (Equality + (Subscript + (IdRef + l + ) + (IdRef + i + ) + ) + (String + ((FullString + "" + )) + ) + true + )) + (block + ((BreakingStmt + Continue + () + ))) + (continuation + ()) + (pos + )) + ))) + )))) + +### Stdout + + +### Failure