Skip to content

Commit 6149ff2

Browse files
committed
Fix a bug with break
1 parent dfa0ae9 commit 6149ff2

File tree

2 files changed

+34
-8
lines changed

2 files changed

+34
-8
lines changed

liquid_interpreter/interpreter.ml

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ and interpret_block settings ctx str = function
123123
| [ cmd ] -> interpret settings ctx str cmd
124124
| hd :: tl ->
125125
let nctx, nstr = interpret settings ctx str hd in
126-
if has_notifier "break" nctx then (notifier "break" ctx, str)
127-
else if has_notifier "continue" nctx then (notifier "continue" ctx, str)
126+
if has_notifier "break" nctx then (nctx, nstr)
127+
else if has_notifier "continue" nctx then (nctx, nstr)
128128
else interpret_block settings nctx nstr tl
129129
| _ -> (ctx, str)
130130

@@ -139,7 +139,13 @@ and interpret_test settings ctx str ~cond ~body ~else_body =
139139
else interpret_else settings ctx str else_body
140140
in
141141

142-
(rewind rctx pre_state, rstr)
142+
let break_exists = has_notifier "break" rctx in
143+
let continue_exists = has_notifier "continue" rctx in
144+
let result_ctx = rewind rctx pre_state in
145+
let result_ctx = if break_exists then notifier "break" result_ctx else result_ctx in
146+
let result_ctx = if continue_exists then notifier "continue" result_ctx else result_ctx in
147+
148+
(result_ctx, rstr)
143149

144150
and interpret_for settings ctx str ~alias ~iterable ~params ~body ~else_body =
145151
let uiter = Values.unwrap ctx iterable in
@@ -152,7 +158,27 @@ and interpret_for settings ctx str ~alias ~iterable ~params ~body ~else_body =
152158
let inner_ctx, rendered = interpret_block settings loop_ctx "" b in
153159
let r_str = acc_str ^ rendered in
154160
if has_notifier "break" inner_ctx then
155-
Done (rewind inner_ctx pre_state, r_str)
161+
Done (rewind inner_ctx pre_state, acc_str)
162+
else if has_notifier "continue" inner_ctx then
163+
let find_int k =
164+
match Ctx.find Settings.forloop acc_ctx with
165+
| Object obj -> (
166+
match Object.find_opt k obj with
167+
| Some (Number n) -> Float.to_int n
168+
| _ -> raise (Failure "Failed to find int"))
169+
| _ -> raise (Failure "Failed to find forloop object")
170+
in
171+
let index = find_int "index" in
172+
let length = find_int "length" in
173+
let nacc =
174+
Interpreter_objects.make_forloop_ctx inner_ctx index length
175+
in
176+
177+
(* Remove the continue notifier for the next iteration *)
178+
let next_ctx = Ctx.remove (nlit "continue") nacc in
179+
180+
if last then Forward (rewind next_ctx pre_state, r_str)
181+
else Forward (next_ctx, r_str)
156182
else
157183
let find_int k =
158184
match Ctx.find Settings.forloop acc_ctx with

test/test_for_loops.ml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -440,10 +440,10 @@ let suite =
440440
; test_case "forloop.rindex" `Quick test_forloop_rindex
441441
; test_case "forloop.rindex0" `Quick test_forloop_rindex0
442442
; (* Break and continue - TODO: break/continue not implemented yet *)
443-
(* test_case "for loop break" `Quick test_for_loop_break; *)
444-
(* test_case "for loop continue" `Quick test_for_loop_continue; *)
445-
(* test_case "for loop multiple breaks" `Quick test_for_loop_multiple_breaks; *)
446-
(* test_case "for loop multiple continues" `Quick test_for_loop_multiple_continues; *)
443+
test_case "for loop break" `Quick test_for_loop_break;
444+
test_case "for loop continue" `Quick test_for_loop_continue;
445+
test_case "for loop multiple breaks" `Quick test_for_loop_multiple_breaks;
446+
test_case "for loop multiple continues" `Quick test_for_loop_multiple_continues;
447447

448448
(* Nested loops *)
449449
test_case "nested for loops" `Quick test_nested_for_loops

0 commit comments

Comments
 (0)