type lox_function = { name : string; arity : int; (* env : Environment.environment; [@printer fun fmt _ -> fprintf fmt ""] *) arg_names : string list; body : Stmt.stmt_node; [@printer fun fmt _ -> fprintf fmt ""] } type native_function = { name : string; arity : int; fn : lox_value list -> (lox_value, string) result; } and lox_value = | Function of lox_function | NativeFunction of native_function | String of string | Number of float | Bool of bool | Nil let string_of_lox_value lox_value = match lox_value with | Function { name; arity; _ } -> Printf.sprintf "" name arity | NativeFunction { name; arity; _ } -> Printf.sprintf "" name arity | String s -> s | Number x -> if Float.is_integer x then string_of_int (Int.of_float x) else string_of_float x | Bool b -> string_of_bool b | Nil -> "nil" let type_string_of_lox_value lox_value = match lox_value with | Function _ -> "Function" | NativeFunction _ -> "NativeFunction" | String _ -> "String" | Number _ -> "Number" | Bool _ -> "Bool" | Nil -> "Nil" 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 arity = List.length arg_names in Function { name; arity; arg_names; body }