Merge pull request #3 from Chouser/ocaml
[jackhill/mal.git] / ocaml / env.ml
1 module T = Types.Types
2 module Data = Map.Make (String)
3
4 type env = {
5 outer : env option;
6 data : Types.mal_type Data.t ref;
7 }
8
9 let make outer = { outer = outer; data = ref Data.empty }
10
11 let set env sym value =
12 match sym with
13 | T.Symbol { T.value = key } -> env.data := Data.add key value !(env.data)
14 | _ -> raise (Invalid_argument "set requires a Symbol for its key")
15
16 let rec find env sym =
17 match sym with
18 | T.Symbol { T.value = key } ->
19 (if Data.mem key !(env.data) then
20 Some env
21 else
22 match env.outer with
23 | Some outer -> find outer sym
24 | None -> None)
25 | _ -> raise (Invalid_argument "find requires a Symbol for its key")
26
27 let get env sym =
28 match sym with
29 | T.Symbol { T.value = key } ->
30 (match find env sym with
31 | Some found_env -> Data.find key !(found_env.data)
32 | None -> raise (Invalid_argument ("'" ^ key ^ "' not found")))
33 | _ -> raise (Invalid_argument "get requires a Symbol for its key")