shithub: martian9

ref: 4f535f4a39ed10d5aef7a2f568c02fa3b40775ff
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 dump env =
  let str = ref "" in
  Data.iter (fun k v -> str := !str ^ k ^ ": " ^ Printer.to_string v) !(env.data) ;
  !str

(* 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 *)