shithub: martian9

ref: 89403fb391d40dee3ee3ca6b59a70d07d04de1c2
dir: /env.ml/

View raw version
module T = Types.Types
module Data = Map.Make (String)

exception Runtime_error of string

type env =
  { outer : env option
  ; data : Types.m9type Data.t ref
  }

let make outer = { outer; data = ref Data.empty }

let set env sym value =
  match sym with
  | T.Symbol { T.value = key } ->
    (* print_endline ("Env.set: " ^ key); *) env.data := Data.add key value !(env.data)
  | _ -> raise (Invalid_argument "set: not a symbol")
;;

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: not a symbol")
;;

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 (Runtime_error ("unknown symbol '" ^ key ^ "'")))
  | _ -> raise (Invalid_argument "get: not a symbol")
;;