moved for loop to separate Stmt and added continue

This commit is contained in:
Moritz Gmeiner 2024-08-27 17:15:35 +02:00
commit be28dad67e
6 changed files with 113 additions and 61 deletions

View file

@ -265,16 +265,11 @@ and while_loop (state : state ref) : stmt_result =
let* _ = consume state LeftParen in
let* cond = expression state in
let* _ = consume state RightParen in
(* let was_in_loop = !state.is_in_loop in
state := { !state with is_in_loop = true };
let body = statement state in
state := { !state with is_in_loop = was_in_loop };
let* body = body in *)
let* body = with_is_in_loop statement state in
make_while pos cond body |> Result.ok
and for_loop (state : state ref) : stmt_result =
let for_pos = cur_pos state in
let pos = cur_pos state in
let* _ = consume state For in
let* _ = consume state LeftParen in
let* init =
@ -287,10 +282,8 @@ and for_loop (state : state ref) : stmt_result =
in
let* cond =
match peek_tt state with
| Semicolon ->
let pos = cur_pos state in
Ok (make_bool pos true)
| _ -> expression state
| Semicolon -> Ok None
| _ -> expression state |> Result.map Option.some
in
(* expression has no final semicolon, so we need to consume it *)
let* _ = consume state Semicolon in
@ -300,24 +293,8 @@ and for_loop (state : state ref) : stmt_result =
| _ -> expression state |> Result.map Option.some
in
let* _ = consume state RightParen in
(* let was_in_loop = !state.is_in_loop in
state := { !state with is_in_loop = true };
let body = statement state in
state := { !state with is_in_loop = was_in_loop };
let* body = body in *)
let* body = with_is_in_loop statement state in
let body =
match update with
| Some update ->
let update_stmt = make_expr_stmt update.pos update in
make_block body.pos [ body; update_stmt ]
| None -> body
in
let loop = make_while for_pos cond body in
let outer_block =
match init with Some init -> make_block for_pos [ init; loop ] | None -> loop
in
Ok outer_block
make_for pos init cond update body |> Result.ok
and expr_stmt (state : state ref) : stmt_result =
let pos = cur_pos state in
@ -337,6 +314,14 @@ and statement (state : state ref) : stmt_result =
else
let msg = "Can use break only in loops" in
ParserError.make pos msg |> Result.error
| Continue ->
if !state.is_in_loop then (
advance state;
let* _ = consume state Semicolon in
make_continue pos |> Result.ok)
else
let msg = "Can use continue only in loops" in
ParserError.make pos msg |> Result.error
| Print ->
advance state;
let* expr = expression state in