Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 28 additions & 18 deletions lib/interpreter/interpret.ml
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ and interpret_expr globals (expr : Compiler.Optimizer.expr) =
in
(globals, either)
(* for <iterator_name> in <iteratee> { <block> } *)
| ForInLoop { iterator_name; iteratee; block; pos } ->
| ForInLoop { iterator_name; iteratee; block; pos } -> (
let globals =
{
globals with
Expand All @@ -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
Expand Down
142 changes: 142 additions & 0 deletions test/green_specs/regression_continue_decl.sloth
Original file line number Diff line number Diff line change
@@ -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
<opaque>))
<opaque>)
(String
((FullString
""
<opaque>))
<opaque>))
<opaque>)
<opaque>)))
(StmtDecl
(ExprStmt
(LetExpr
res
(ForInLoop
(iterator_name
file)
(iteratee
(IdRef
l
<opaque>))
(block
((BreakingStmt
Continue
((Num
42
<opaque>))
<opaque>)))
(pos
<opaque>))
<opaque>)))
(StmtDecl
(ExprStmt
(FuncInvoc
(IdRef
assert
<opaque>)
((Equality
(IdRef
res
<opaque>)
(Num
42
<opaque>)
true
<opaque>))
<opaque>)))
(StmtDecl
(ExprStmt
(ForLoop
(LetExpr
i
(Num
0
<opaque>)
<opaque>)
(Binary
(IdRef
i
<opaque>)
(ObjDeref
(IdRef
l
<opaque>)
length
<opaque>)
Less
<opaque>)
(AssignExpr
i
(Binary
(IdRef
i
<opaque>)
(Num
1
<opaque>)
Plus
<opaque>)
<opaque>)
((ExprStmt
(IfExpr
(IfCont
(conditional
(Equality
(Subscript
(IdRef
l
<opaque>)
(IdRef
i
<opaque>)
<opaque>)
(String
((FullString
""
<opaque>))
<opaque>)
true
<opaque>))
(block
((BreakingStmt
Continue
()
<opaque>)))
(continuation
())
(pos
<opaque>))
<opaque>)))
<opaque>))))

### Stdout


### Failure