mirror of
https://github.com/MorizzG/MLox.git
synced 2025-12-06 04:22:41 +00:00
started implementing expressions
Parser.parse now return list of statements or list of errors. parsing continues until EOF, even when errors are found; but after the first error the result can only be Error. Also implemented Print and Expr statements.
This commit is contained in:
parent
8656ac50ed
commit
ea0d7acbee
6 changed files with 119 additions and 57 deletions
|
|
@ -2,14 +2,15 @@ let ( let* ) = Result.bind
|
|||
|
||||
open Expr
|
||||
open Error
|
||||
open Stmt
|
||||
open Value
|
||||
|
||||
let value_of_literal (literal : literal) : Value.lox_value =
|
||||
match literal with String s -> String s | Number x -> Number x | Bool b -> Bool b | Nil -> Nil
|
||||
|
||||
let rec interpret_expr (expr : expr_node) : (lox_value, interpreter_error) result =
|
||||
let pos = expr.pos in
|
||||
match expr.expr with
|
||||
let rec interpret_expr (expr : expr_node) : (lox_value, runtime_error) result =
|
||||
let { pos; expr } = expr in
|
||||
match expr with
|
||||
| Literal literal -> Ok (value_of_literal literal)
|
||||
| BinaryExpr { op; left; right } -> (
|
||||
let* left = interpret_expr left in
|
||||
|
|
@ -19,21 +20,28 @@ let rec interpret_expr (expr : expr_node) : (lox_value, interpreter_error) resul
|
|||
| Number x, Plus, Number y -> Ok (Number (x +. y))
|
||||
| Number x, Minus, Number y -> Ok (Number (x -. y))
|
||||
| Number x, Mul, Number y -> Ok (Number (x *. y))
|
||||
| Number x, Div, Number y -> Ok (Number (x /. y))
|
||||
| Number x, Equal, Number y -> Ok (Bool (x = y))
|
||||
| Number x, Div, Number y ->
|
||||
if y <> 0. then Ok (Number (x /. y))
|
||||
else
|
||||
let msg = "Division by 0" in
|
||||
Error { pos; msg }
|
||||
| Bool b, And, Bool c -> Ok (Bool (b && c))
|
||||
| Bool b, Or, Bool c -> Ok (Bool (b || c))
|
||||
| _, Equal, _ -> Ok (Bool (left = right))
|
||||
| Number x, Greater, Number y -> Ok (Bool (x > y))
|
||||
| Number x, GreaterEqual, Number y -> Ok (Bool (x >= y))
|
||||
| Number x, Less, Number y -> Ok (Bool (x < y))
|
||||
| Number x, LessEqual, Number y -> Ok (Bool (x <= y))
|
||||
| Bool b, And, Bool c -> Ok (Bool (b && c))
|
||||
| Bool b, Or, Bool c -> Ok (Bool (b || c))
|
||||
| _, Equal, _ -> Ok (Bool (left = right))
|
||||
| String a, Greater, String b -> Ok (Bool (a > b))
|
||||
| String a, GreaterEqual, String b -> Ok (Bool (a >= b))
|
||||
| String a, Less, String b -> Ok (Bool (a < b))
|
||||
| String a, LessEqual, String b -> Ok (Bool (a <= b))
|
||||
| _, _, _ ->
|
||||
let msg =
|
||||
Printf.sprintf "Invalid operands of type %s and %s to operator %s"
|
||||
(type_string_of_lox_value left) (type_string_of_lox_value right) (show_binary_op op)
|
||||
in
|
||||
Error (InterpreterError.make pos msg))
|
||||
Error { pos; msg })
|
||||
| UnaryExpr { op; expr } -> (
|
||||
let* expr = interpret_expr expr in
|
||||
match (op, expr) with
|
||||
|
|
@ -44,4 +52,16 @@ let rec interpret_expr (expr : expr_node) : (lox_value, interpreter_error) resul
|
|||
Printf.sprintf "Invalid operant of type %s to operator %s"
|
||||
(type_string_of_lox_value expr) (show_unary_op op)
|
||||
in
|
||||
Error (InterpreterError.make pos msg))
|
||||
Error (RuntimeError.make pos msg))
|
||||
|
||||
let interpret_stmt (stmt : stmt_node) : (unit, runtime_error) result =
|
||||
let { pos; stmt } = stmt in
|
||||
ignore pos;
|
||||
match stmt with
|
||||
| Print expr ->
|
||||
let* value = interpret_expr expr in
|
||||
print_endline (Value.string_of_lox_value value);
|
||||
Ok ()
|
||||
| Expr expr ->
|
||||
let* _ = interpret_expr expr in
|
||||
Ok ()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue