diff --git a/lib/value.ml b/lib/value.ml
index 3fe9dde..e55f588 100644
--- a/lib/value.ml
+++ b/lib/value.ml
@@ -1,8 +1,28 @@
-type lox_value = String of string | Number of float | Bool of bool | Nil
+type lox_function = {
+ name : string;
+ arity : int;
+ arg_names : string list;
+ body : Stmt.stmt_node; [@printer fun fmt _ -> fprintf fmt "
"]
+}
+[@@deriving show { with_path = false }]
+
+type native_function = {
+ name : string;
+ arity : int;
+ fn : lox_value list -> (lox_value, string) result;
+}
+[@@deriving show { with_path = false }]
+
+and function_ = NativeFunction of native_function | LoxFunction of lox_function
+[@@deriving show { with_path = false }]
+
+and lox_value = Function of function_ | String of string | Number of float | Bool of bool | Nil
[@@deriving show { with_path = false }]
let string_of_lox_value lox_value =
match lox_value with
+ | Function (NativeFunction { name; arity; _ }) -> Printf.sprintf "" name arity
+ | Function (LoxFunction { 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
@@ -10,10 +30,17 @@ let string_of_lox_value lox_value =
let type_string_of_lox_value lox_value =
match lox_value with
+ | Function (NativeFunction _) -> "NativeFunction"
+ | Function (LoxFunction _) -> "Function"
| String _ -> "String"
| Number _ -> "Number"
| Bool _ -> "Bool"
| Nil -> "Nil"
-let lox_value_to_bool lox_value =
- match lox_value with String _ -> true | Number _ -> true | Bool b -> b | Nil -> false
+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
+ let fn = LoxFunction { name; arity; arg_names; body } in
+ Function fn