implemented calls

This commit is contained in:
Moritz Gmeiner 2024-08-27 20:32:05 +02:00
commit be931b7214
6 changed files with 115 additions and 55 deletions

View file

@ -75,13 +75,34 @@ let rec interpret_expr (env : environment) (expr_node : expr_node) :
match (op, lox_value_to_bool left) with
| And, false | Or, true -> Ok left (* short circuit *)
| _ -> interpret_expr env right)
| Call { callee; args } -> (
let* callee = interpret_expr env callee in
let f (acc : (lox_value list, runtime_error) result) (arg : expr_node) :
(lox_value list, runtime_error) result =
match acc with
| Ok acc ->
let* arg = interpret_expr env arg in
Ok (arg :: acc)
| Error e -> Error e
in
let* args = List.fold_left f (Ok []) args in
let args = List.rev args in
let args_s =
List.fold_left (fun acc value -> acc ^ " " ^ string_of_lox_value value) "" args
in
Printf.eprintf "Called %s with args%s\n%!" (string_of_lox_value callee) args_s;
match callee with
| _ ->
let msg = Printf.sprintf "%s object is not callable" (type_string_of_lox_value callee) in
RuntimeError.make pos msg |> Result.error)
let rec interpret_stmt (env : environment) (stmt_node : stmt_node) : (unit, runtime_error) result =
let { pos; stmt } = stmt_node in
ignore pos;
match stmt with
| Expr expr ->
let* _ = interpret_expr env expr in
let* value = interpret_expr env expr in
ignore value;
Ok ()
| Break -> RuntimeError.break () |> Result.error
| Continue -> RuntimeError.continue () |> Result.error
@ -101,7 +122,7 @@ let rec interpret_stmt (env : environment) (stmt_node : stmt_node) : (unit, runt
let rec _interpret stmts =
match stmts with
| stmt :: tail ->
let* _ = interpret_stmt env stmt in
let* () = interpret_stmt env stmt in
_interpret tail
| [] -> Ok ()
in
@ -123,7 +144,7 @@ let rec interpret_stmt (env : environment) (stmt_node : stmt_node) : (unit, runt
else Ok ()
| For { init; cond; update; body } ->
let env = Env.enter env in
let* _ = init |> Option.map (interpret_stmt env) |> Option.value ~default:(Ok ()) in
let* () = init |> Option.map (interpret_stmt env) |> Option.value ~default:(Ok ()) in
let eval_cond () =
cond
|> Option.map (interpret_expr env)
@ -139,7 +160,8 @@ let rec interpret_stmt (env : environment) (stmt_node : stmt_node) : (unit, runt
let result = interpret_stmt env body in
match result with
| Ok () | Error Continue ->
let* _ = do_update () in
let* value = do_update () in
ignore value;
loop ()
| Error Break -> Ok ()
| Error e -> Error e