2015-01-26 07:30:37 +03:00
|
|
|
module T = Types.Types
|
2015-01-23 16:17:35 +03:00
|
|
|
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
|
2015-01-26 07:30:37 +03:00
|
|
|
| T.Symbol { T.value = key } -> env.data := Data.add key value !(env.data)
|
2015-01-23 16:17:35 +03:00
|
|
|
| _ -> raise (Invalid_argument "set requires a Symbol for its key")
|
|
|
|
|
|
|
|
let rec find env sym =
|
|
|
|
match sym with
|
2015-01-26 07:30:37 +03:00
|
|
|
| T.Symbol { T.value = key } ->
|
2015-01-23 16:17:35 +03:00
|
|
|
(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
|
2015-01-26 07:30:37 +03:00
|
|
|
| T.Symbol { T.value = key } ->
|
2015-01-23 16:17:35 +03:00
|
|
|
(match find env sym with
|
|
|
|
| Some found_env -> Data.find key !(found_env.data)
|
2015-01-30 07:29:54 +03:00
|
|
|
| None -> raise (Invalid_argument ("'" ^ key ^ "' not found")))
|
2015-01-23 16:17:35 +03:00
|
|
|
| _ -> raise (Invalid_argument "get requires a Symbol for its key")
|