mirror of
https://github.com/MorizzG/MLox.git
synced 2025-12-06 04:22:41 +00:00
51 lines
2.1 KiB
OCaml
51 lines
2.1 KiB
OCaml
open Expr
|
|
|
|
type stmt =
|
|
| Expr of expr_node
|
|
| Print of expr_node
|
|
| VarDecl of { name : string; init : expr_node option }
|
|
| Block of stmt_node list
|
|
| If of { cond : expr_node; then_ : stmt_node; else_ : stmt_node option }
|
|
|
|
and stmt_node = { stmt : stmt; pos : Error.code_pos }
|
|
|
|
let rec show_stmt ?(indent = 0) stmt =
|
|
let indent_s = String.make indent ' ' in
|
|
let show_expr_ind ?(depth = 2) = show_expr ~indent:(indent + depth) in
|
|
let show_stmt_ind ?(depth = 2) = show_stmt ~indent:(indent + depth) in
|
|
match stmt with
|
|
| Expr expr -> indent_s ^ "Expr\n" ^ show_expr_ind expr.expr
|
|
| Print expr -> indent_s ^ "Print\n" ^ show_expr_ind expr.expr
|
|
| VarDecl { name; init } -> (
|
|
indent_s ^ "Var " ^ name
|
|
^ match init with Some init -> " = \n" ^ show_expr_ind init.expr | None -> "")
|
|
| Block stmts ->
|
|
let stmts_s =
|
|
List.fold_left (fun acc stmt -> acc ^ show_stmt_ind stmt.stmt ^ "\n") "" stmts
|
|
in
|
|
"Block" ^ stmts_s ^ "End"
|
|
| If { cond; then_; else_ } ->
|
|
let cond_s = show_expr_ind cond.expr in
|
|
let then_s = show_stmt_ind ~depth:4 then_.stmt in
|
|
let else_s = Option.map (fun stmt -> show_stmt_ind ~depth:4 stmt.stmt) else_ in
|
|
indent_s ^ "If\n" ^ cond_s ^ "\n" ^ indent_s ^ " Then\n" ^ then_s
|
|
^ if Option.is_some else_s then "\n" ^ indent_s ^ " Else\n" ^ Option.get else_s else ""
|
|
|
|
let show_stmt_node stmt_node = show_stmt stmt_node.stmt
|
|
let make_stmt_node (pos : Error.code_pos) (stmt : stmt) : stmt_node = { stmt; pos }
|
|
|
|
let make_expr_stmt (pos : Error.code_pos) (expr : expr_node) : stmt_node =
|
|
Expr expr |> make_stmt_node pos
|
|
|
|
let make_print (pos : Error.code_pos) (expr : expr_node) : stmt_node =
|
|
Print expr |> make_stmt_node pos
|
|
|
|
let make_var_decl (pos : Error.code_pos) (name : string) (init : expr_node option) =
|
|
VarDecl { name; init } |> make_stmt_node pos
|
|
|
|
let make_block (pos : Error.code_pos) (stmts : stmt_node list) : stmt_node =
|
|
Block stmts |> make_stmt_node pos
|
|
|
|
let make_if (pos : Error.code_pos) (cond : expr_node) (then_ : stmt_node) (else_ : stmt_node option)
|
|
=
|
|
If { cond; then_; else_ } |> make_stmt_node pos
|