mirror of
https://github.com/MorizzG/MLox.git
synced 2025-12-06 04:22:41 +00:00
moved for loop to separate Stmt and added continue
This commit is contained in:
parent
957783a926
commit
be28dad67e
6 changed files with 113 additions and 61 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue