added closures

This commit is contained in:
Moritz Gmeiner 2024-08-28 23:58:55 +02:00
commit b425a59db5
5 changed files with 59 additions and 28 deletions

View file

@ -6,8 +6,7 @@ module Hashtbl = struct
let contains tbl key = find_opt tbl key |> Option.is_some
end
type env_table = (string, lox_value) Hashtbl.t
type environment = { globals : env_table ref; locals : env_table list }
type environment = Value.environment
module Env = struct
type t = environment

View file

@ -140,7 +140,7 @@ let rec interpret_expr (env : environment) (expr_node : expr_node) : lox_value i
RuntimeError.make pos msg |> error
else
match fn args with Ok value -> Ok value | Error s -> RuntimeError.make pos s |> error)
| Function { name; arity; arg_names; body } -> (
| Function { name; env; arity; arg_names; body } -> (
let args_len = List.length args in
if args_len <> arity then
let msg =
@ -149,7 +149,8 @@ let rec interpret_expr (env : environment) (expr_node : expr_node) : lox_value i
in
RuntimeError.make pos msg |> error
else
let env = Env.push_frame env in
(* let env = Env.push_frame env in *)
let env = Env.enter env in
let () =
List.iter2 (fun name value -> assert (Env.define env name value)) arg_names args
in
@ -190,7 +191,7 @@ and interpret_stmt (env : environment) (stmt_node : stmt_node) : unit interprete
in
RuntimeError.make pos msg |> error
| FunDecl { name; arg_names; body } ->
let fn = make_lox_function name arg_names body in
let fn = make_lox_function name env arg_names body in
let success = Env.define env name fn in
if success then Ok ()
else

View file

@ -419,7 +419,6 @@ and fun_declaration (state : state) : stmt_result =
let* () = consume state RightParen in
let* body = with_is_in_fun block state in
make_fun_decl pos name arg_names body |> Result.ok
(* make_nil pos |> make_expr_stmt pos |> Result.ok *)
and declaration (state : state) : stmt_result =
match peek_tt state with

View file

@ -1,12 +1,12 @@
type lox_function = {
name : string;
env : environment;
arity : int;
(* env : Environment.environment; [@printer fun fmt _ -> fprintf fmt "<env>"] *)
arg_names : string list;
body : Stmt.stmt_node; [@printer fun fmt _ -> fprintf fmt "<body>"]
}
type native_function = {
and native_function = {
name : string;
arity : int;
fn : lox_value list -> (lox_value, string) result;
@ -20,6 +20,9 @@ and lox_value =
| Bool of bool
| Nil
and env_table = (string, lox_value) Hashtbl.t
and environment = { globals : env_table ref; locals : env_table list }
let string_of_lox_value lox_value =
match lox_value with
| Function { name; arity; _ } -> Printf.sprintf "<fn %s/%d>" name arity
@ -40,7 +43,7 @@ let type_string_of_lox_value lox_value =
let lox_value_to_bool lox_value = match lox_value with Bool b -> b | Nil -> false | _ -> true
let make_lox_function (name : string) (arg_names : string list) (body : Stmt.stmt_node) : lox_value
=
let make_lox_function (name : string) (env : environment) (arg_names : string list)
(body : Stmt.stmt_node) : lox_value =
let arity = List.length arg_names in
Function { name; arity; arg_names; body }
Function { name; env; arity; arg_names; body }