shithub: martian9

ref: 8b4ebe50739d76ce9591716e394ca68194f22245
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; T.meta = _ } ->
    (* 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; T.meta = _ } ->
    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; T.meta = _ } ->
    (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")
;;

(* let string_of_env env =
 *   let string = ref "" in
 *   (match env with
 *   | { outer; data = data } ->
 *      Data.iter (fun k v -> string := !string ^ "[" ^ k ^ "|" ^ v ^ "]") !data;
 *   | _ -> ());
 *   !string *)