shithub: martian9

ref: 10a9adc7d9a6caa80c7bce6fb6df64ddd79bf8dc
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 } -> 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")
;;