aboutsummaryrefslogtreecommitdiff
path: root/ocaml/env.ml
blob: cb32360eb01b9e64eb5523114c376bf973332d85 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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")