mirror of
https://github.com/kanaka/mal.git
synced 2024-09-20 01:57:09 +03:00
a878f3bb77
T.Map is now a real OCaml binary-tree map, and supports arbitrary mal value types for both keys and values. Metadata support is provided in the data objects, but not yet in the printer, reader, or core library.
34 lines
1.0 KiB
OCaml
34 lines
1.0 KiB
OCaml
module T = Types.Types
|
|
module Data = Map.Make (String)
|
|
|
|
type env = {
|
|
outer : env option;
|
|
data : Types.mal_type Data.t ref;
|
|
}
|
|
|
|
let make outer = { outer = outer; data = ref Data.empty }
|
|
|
|
let set env sym value =
|
|
match sym with
|
|
| T.Symbol { T.value = key } -> env.data := Data.add key value !(env.data)
|
|
| _ -> raise (Invalid_argument "set requires a Symbol for its key")
|
|
|
|
let rec find env sym =
|
|
match sym with
|
|
| T.Symbol { T.value = key } ->
|
|
(if Data.mem key !(env.data) then
|
|
Some env
|
|
else
|
|
match env.outer with
|
|
| Some outer -> find outer sym
|
|
| None -> None)
|
|
| _ -> raise (Invalid_argument "find requires a Symbol for its key")
|
|
|
|
let get env sym =
|
|
match sym with
|
|
| T.Symbol { T.value = key } ->
|
|
(match find env sym with
|
|
| Some found_env -> Data.find key !(found_env.data)
|
|
| None -> raise (Invalid_argument ("Symbol '" ^ key ^ "' not found")))
|
|
| _ -> raise (Invalid_argument "get requires a Symbol for its key")
|