type t = { vars : (string, value) Hashtbl.t; parent : t option; } and value = | Int of int | Float of float | String of string | Function of string list * expr | External of string | Nop (* return of system operations (will be deprecated) *) and expr = Ast.t module Value = struct module Type = Ast.Type type t = value let to_string = function | Int n -> string_of_int n | Float n -> string_of_float n | String s -> "\"" ^ s ^ "\"" | Function (vars, _) -> Printf.sprintf "function with %d arguments" @@ List.length vars | External f -> "external " ^ f | Nop -> "nop" let typeof = function | Int _ -> Type.Int | Float _ -> Type.Float | String _ -> Type.String | Function _ -> Type.Function | External _ -> Type.External | Nop -> failwith "Value.typeof" let promote = function | Int n -> Float (float n) | _ -> failwith "Value.promote" end let init_global () = { vars = Hashtbl.create 100; parent = None; } let make parent = { vars = Hashtbl.create 100; parent = Some parent; } exception Not_found let rec get e name = match Hashtbl.find_opt e.vars name with | None -> begin match e.parent with | None -> raise Not_found | Some p -> get p name end | Some value -> value let get_opt e name = try Some (get e name) with Not_found -> None let set e name value = Hashtbl.replace e.vars name value let add_seq e seq = Hashtbl.add_seq e.vars seq