diff --git a/lib/expr.ml b/lib/expr.ml index 5485060..7a3dc46 100644 --- a/lib/expr.ml +++ b/lib/expr.ml @@ -40,6 +40,7 @@ let rec show_expr ?(indent = 0) expr = ident_s ^ show_binary_op op ^ "\n" ^ show_indented left.expr ^ "\n" ^ show_indented right.expr | UnaryExpr { op; expr } -> ident_s ^ show_unary_op op ^ "\n" ^ show_indented expr.expr +let show_expr_node expr_node = show_expr expr_node.expr let make_expr_node (pos : Error.code_pos) (expr : expr) = { expr; pos } let make_string (pos : Error.code_pos) (s : string) = make_expr_node pos (Literal (String s)) let make_number (pos : Error.code_pos) (x : float) = make_expr_node pos (Literal (Number x)) diff --git a/lib/parser.ml b/lib/parser.ml index c419cb9..1b4c350 100644 --- a/lib/parser.ml +++ b/lib/parser.ml @@ -8,18 +8,10 @@ open Stmt type parse_result = (stmt_node list, parser_error list) result type stmt_result = (stmt_node, parser_error) result type expr_result = (expr_node, parser_error) result -type state = { tokens : token list; errors_rev : parser_error list } +type state = { tokens : token list } let is_at_end state = (List.hd !state.tokens).token_type == Eof - -let append_error msg pos state = - let e = ParserError.make pos msg in - { state with errors_rev = e :: state.errors_rev } - -let advance state = state := { !state with tokens = List.tl !state.tokens } -let peek state = List.hd !state.tokens -let peek_tt (state : state ref) : token_type = (peek state).token_type -let cur_pos state = (peek state).pos +let advance state = state := { tokens = List.tl !state.tokens } let next state = assert (not ((List.hd !state.tokens).token_type == Eof)); @@ -27,6 +19,10 @@ let next state = advance state; token +let peek state = List.hd !state.tokens +let peek_tt (state : state ref) : token_type = (peek state).token_type +let cur_pos state = (peek state).pos + let advance_if state tt = if peek_tt state == tt then ( advance state; @@ -187,6 +183,7 @@ let statement (state : state ref) : stmt_result = let stmt = make_print pos expr in Ok stmt | tt -> + advance state; let msg = Printf.sprintf "Statement stating with %s not yet implemented" (show_token_type tt) in @@ -200,17 +197,25 @@ let rec synchronise (state : state ref) = advance state; synchronise state -let rec parse (tokens : token list) : parse_result = - let state = ref { tokens; errors_rev = [] } in +let rec parse_impl (state : state ref) : parse_result = let result = statement state in match result with | Ok stmt when peek_tt state == Eof -> Ok [ stmt ] | Ok stmt -> - let* stmts = parse !state.tokens in + print_endline (show_stmt stmt.stmt); + let* stmts = parse_impl state in Ok (stmt :: stmts) | Error e -> ( synchronise state; if peek_tt state == Eof then Error [ e ] else - let tail_result = parse !state.tokens in + let tail_result = parse_impl state in match tail_result with Ok _ -> Error [ e ] | Error es -> Error (e :: es)) + +let parse (tokens : token list) : parse_result = + (* filter out all the comment tokens *) + let tokens = + List.filter (fun tok -> match tok.token_type with Comment _ -> false | _ -> true) tokens + in + let state = ref { tokens } in + parse_impl state diff --git a/lib/stmt.ml b/lib/stmt.ml index 9fbd7aa..90c8891 100644 --- a/lib/stmt.ml +++ b/lib/stmt.ml @@ -1,6 +1,9 @@ type stmt = Expr of Expr.expr_node | Print of Expr.expr_node and stmt_node = { stmt : stmt; pos : Error.code_pos } +let show_stmt stmt = + match stmt with Expr expr -> Expr.show_expr expr.expr | Print expr -> Expr.show_expr expr.expr + let make_expr_stmt (pos : Error.code_pos) (expr : Expr.expr_node) : stmt_node = let stmt = Expr expr in { stmt; pos }