mirror of
https://github.com/kanaka/mal.git
synced 2024-11-11 08:56:41 +03:00
34 lines
1021 B
OCaml
34 lines
1021 B
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 ("'" ^ key ^ "' not found")))
|
|
| _ -> raise (Invalid_argument "get requires a Symbol for its key")
|