ce/env.ml
2022-02-08 00:26:03 +09:00

94 lines
1.8 KiB
OCaml

type t = {
vars : (string, value) Hashtbl.t;
parent : t option;
}
and value =
| Int of int
| Float of float
| String of string
| Symbol of string
| Function of string list * expr
| External of string
| Nop (* return of system operations (will be deprecated) *)
and expr = Ast.t
module Type = struct
type t =
| Int
| Float
| String
| Symbol
| Function
| External
let to_string = function
| Int -> "int"
| Float -> "float"
| String -> "string"
| Symbol -> "symbol"
| Function -> "fun"
| External -> "external"
let supertype = function
| Int -> Some Float
| _ -> None
end
module Value = struct
type t = value
let to_string = function
| Int n -> string_of_int n
| Float n -> string_of_float n
| String s -> "\"" ^ s ^ "\""
| Symbol s -> "symbol " ^ 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
| Symbol _ -> Type.Symbol
| 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