From d26b8d4aef7c9d6a907219d26bb4251b2abec3f6 Mon Sep 17 00:00:00 2001 From: Christopher Fujino Date: Mon, 20 Jul 2026 18:32:25 -0700 Subject: [PATCH 1/2] wip; fixed one, broke one --- lib/interpreter/interpret.ml | 2 +- .../regression_continue_decl.sloth | 68 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 test/green_specs/regression_continue_decl.sloth diff --git a/lib/interpreter/interpret.ml b/lib/interpreter/interpret.ml index 08242ef..f0a51a7 100644 --- a/lib/interpreter/interpret.ml +++ b/lib/interpreter/interpret.ml @@ -670,7 +670,7 @@ and interpret_expr globals (expr : Compiler.Optimizer.expr) = | Break break_val -> (* Done with loop, return break_val *) (globals, First break_val) - | Continue v -> recurse v + | Continue v -> (globals, First v) | Error _ | Exit _ -> (globals, either))) | None -> Printf.sprintf diff --git a/test/green_specs/regression_continue_decl.sloth b/test/green_specs/regression_continue_decl.sloth new file mode 100644 index 0000000..77c68c9 --- /dev/null +++ b/test/green_specs/regression_continue_decl.sloth @@ -0,0 +1,68 @@ +### Program +let l = [""] +#for file in l { +# continue +#} +for let i = 0; i < l.length; i = i + 1 { + continue +} + +### Processes +() + +### Ast +((StmtDecl + (ExprStmt + (LetExpr + l + (List + ((String + ((FullString + "" + )) + )) + ) + ))) + (StmtDecl + (ExprStmt + (ForLoop + (LetExpr + i + (Num + 0 + ) + ) + (Binary + (IdRef + i + ) + (ObjDeref + (IdRef + l + ) + length + ) + Less + ) + (AssignExpr + i + (Binary + (IdRef + i + ) + (Num + 1 + ) + Plus + ) + ) + ((BreakingStmt + Continue + () + )) + )))) + +### Stdout + + +### Failure From fdd888154ac0c9112d881864c99c165b2be00f41 Mon Sep 17 00:00:00 2001 From: Christopher Fujino Date: Mon, 20 Jul 2026 18:57:46 -0700 Subject: [PATCH 2/2] fix for-in --- lib/interpreter/interpret.ml | 48 ++++++---- .../regression_continue_decl.sloth | 96 ++++++++++++++++--- 2 files changed, 114 insertions(+), 30 deletions(-) diff --git a/lib/interpreter/interpret.ml b/lib/interpreter/interpret.ml index f0a51a7..e0b6214 100644 --- a/lib/interpreter/interpret.ml +++ b/lib/interpreter/interpret.ml @@ -670,7 +670,7 @@ and interpret_expr globals (expr : Compiler.Optimizer.expr) = | Break break_val -> (* Done with loop, return break_val *) (globals, First break_val) - | Continue v -> (globals, First v) + | Continue v -> recurse v | Error _ | Exit _ -> (globals, either))) | None -> Printf.sprintf @@ -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 index 77c68c9..1527e88 100644 --- a/test/green_specs/regression_continue_decl.sloth +++ b/test/green_specs/regression_continue_decl.sloth @@ -1,10 +1,16 @@ ### Program -let l = [""] -#for file in l { -# continue -#} +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 { - continue + if l[i] == "" { + continue + } } ### Processes @@ -18,11 +24,53 @@ for let i = 0; i < l.length; i = i + 1 { (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 @@ -56,10 +104,36 @@ for let i = 0; i < l.length; i = i + 1 { Plus ) ) - ((BreakingStmt - Continue - () - )) + ((ExprStmt + (IfExpr + (IfCont + (conditional + (Equality + (Subscript + (IdRef + l + ) + (IdRef + i + ) + ) + (String + ((FullString + "" + )) + ) + true + )) + (block + ((BreakingStmt + Continue + () + ))) + (continuation + ()) + (pos + )) + ))) )))) ### Stdout