staload Sym = "ats_symbol.sats"
staload Map = "ats_map_lin.sats"
staload "ats_symenv.sats"
staload "ats_reference.sats"
staload _ = "ats_reference.dats"
#define THIS_FILE "ats_symenv.dats"
typedef sym_t = $Sym.symbol_t
viewtypedef
symmap (itm:t@ype) = $Map.map_vt (sym_t, itm)
viewtypedef
symmaplst (itm:t@ype) = [n:nat] list_vt (symmap itm, n)
typedef
symenv (itm:t@ype) = '{
map= ref (symmap itm)
, maplst= ref (symmaplst itm)
, savedlst= ref (List_vt @(symmap itm, symmaplst itm))
, pervasive= ref (symmaplst itm)
}
assume symmap_t = symmap
assume symenv_t = symenv
fn{} prerr_interror () = prerr "INTERNAL ERROR (ats_symenv)"
implement{itm}
symmap_search (m, k) =
$Map.map_search<sym_t,itm> (m, k)
implement{itm}
symmap_ref_search (r_m, k) = let
val (vbox pf_m | p_m) = ref_get_view_ptr r_m
in
$Map.map_search<sym_t,itm> (!p_m, k)
end
implement{itm}
symmap_list_get (m) = $Map.map_list_inf m
implement{itm}
symmap_reflist_get (r_m) = let
val (vbox pf_m | p_m) = ref_get_view_ptr r_m
in
$Map.map_list_inf (!p_m)
end
implement{itm}
symmap_insert (m, k, i) = $Map.map_insert (m, k, i)
implement{itm}
symmap_remove (m, k) = $Map.map_remove (m, k)
implement{itm}
symmap_list_inf (m) = $Map.map_list_inf<sym_t,itm> (m)
implement symmap_make {itm} () =
$Map.map_make {sym_t,itm} ($Sym.compare_symbol_symbol)
implement{itm} symmap_free (map) = $Map.map_free (map)
fun{itm:t@ype}
symmaplst_free {n:nat} .<n>.
(ms: list_vt (symmap itm, n)):<> void =
case+ ms of
| ~list_vt_cons (m, ms) => (
symmap_free<itm> m; symmaplst_free<itm> ms
) | ~list_vt_nil () => ()
fun{itm:t@ype}
symmaplst_search {n:nat} .<n>. (
ms0: !list_vt (symmap itm, n), k: sym_t
) :<> Option_vt itm = begin case+ ms0 of
| list_vt_cons (!p_m, !p_ms) => let
val ans = $Map.map_search (!p_m, k) in case+ ans of
| Some_vt _ => ans where {
val () = fold@ ms0; val () = fold@ ans
} | ~None_vt () => ans where {
val ans = symmaplst_search<itm> (!p_ms, k)
val () = fold@ ms0
} end
| list_vt_nil () => (fold@ ms0; None_vt ())
end
implement
symenv_make {itm} () = '{
map= ref_make_elt (symmap_make {itm} ())
, maplst= ref_make_elt (list_vt_nil ())
, savedlst= ref_make_elt (list_vt_nil ())
, pervasive= ref_make_elt (list_vt_nil ())
}
implement{itm}
symenv_insert_fst (env, k, i) = let
val (vbox pf_m | p_m) = ref_get_view_ptr env.map in
$Map.map_insert (!p_m, k, i)
end
implement{itm}
symenv_remove_fst (env, k) = let
val (vbox pf_m | p_m) = ref_get_view_ptr env.map in
$Map.map_remove (!p_m, k)
end
implement{itm}
symenv_search_all (env, k) = let
val ans = let
val (vbox pf_m | p_m) = ref_get_view_ptr env.map in
$Map.map_search (!p_m, k)
end in
case+ ans of
| Some_vt _ => begin
let val () = fold@ ans in ans end
end | ~None_vt () => let
val (vbox pf_ms | p_ms) = ref_get_view_ptr env.maplst
in
symmaplst_search<itm> (!p_ms, k)
end end
implement{itm}
symenv_pervasive_search (env, k) = let
val (vbox pf_ms | p_ms) = ref_get_view_ptr env.pervasive
in
symmaplst_search<itm> (!p_ms, k)
end
fun{itm:t@ype}
symmaplst_replace {n:nat} .<n>. (
ms0: !list_vt (symmap itm, n), k: sym_t, i: itm
) :<> Option_vt itm = begin case+ ms0 of
| list_vt_cons (!p_m, !p_ms) => let
val ans = $Map.map_remove (!p_m, k) in case+ ans of
| ~Some_vt _ => None_vt () where {
val () = $Map.map_insert (!p_m, k, i)
val () = fold@ ms0
} | ~None_vt () => ans where {
val ans = symmaplst_replace<itm> (!p_ms, k, i)
val () = fold@ ms0
} end
| list_vt_nil () => (fold@ ms0; Some_vt i)
end
implement{itm}
symenv_pervasive_replace (env, k, i) = let
val (vbox pf_ms | p_ms) = ref_get_view_ptr env.pervasive
in
symmaplst_replace<itm> (!p_ms, k, i)
end
implement{itm}
symenv_pop (env) = let
fn abort (): symmap itm = begin
prerr_interror ();
prerr ": symenv_pop: env.maplst is empty"; prerr_newline ();
exit {symmap itm} (1)
end val m = let
val (pfbox | p_ms) = ref_get_view_ptr env.maplst
prval vbox pf_ms = pfbox
in
case+ !p_ms of
| ~list_vt_cons (m, ms) => begin
!p_ms := (ms: symmaplst itm); m
end | list_vt_nil () => begin
fold@ (!p_ms); $effmask_ref (abort ())
end end : symmap itm
val (vbox pf_m | p_m) = ref_get_view_ptr env.map
in
symmap_free<itm> (!p_m); !p_m := m
end
implement
symenv_push {itm} (env) = let
val m = let
val (vbox pf_m | p_m) = ref_get_view_ptr env.map
val m = !p_m
in
!p_m := symmap_make (); m
end : symmap itm
val (vbox pf_ms | p_ms) = ref_get_view_ptr env.maplst
in
!p_ms := list_vt_cons (m, !p_ms)
end
implement
symenv_swap
{itm} (env, r_m) = () where {
val (vbox pf1_m | p1_m) = ref_get_view_ptr env.map
viewtypedef elt = symmap_t itm
val () = $effmask_ref (ref_swap<elt> (r_m, !p1_m))
}
implement
symenv_save {itm} (env) = let
val m = let
val (vbox pf_m | p_m) = ref_get_view_ptr env.map
val m = !p_m
in
!p_m := symmap_make (); m
end : symmap itm
val ms = let
val (vbox pf_ms | p_ms) = ref_get_view_ptr env.maplst
val ms = !p_ms
in
!p_ms := list_vt_nil (); ms
end : symmaplst itm
val (vbox pf_saved | p_saved) = ref_get_view_ptr env.savedlst
in
!p_saved := list_vt_cons ( @(m, ms), !p_saved )
end
implement{itm}
symenv_restore (env) = let
viewtypedef mms = @(symmap itm, symmaplst itm)
fn abort (): mms = begin
prerr_interror ();
prerr ": symenv_restore: env.savedlst is empty"; prerr_newline ();
exit {mms} (1)
end val (m, ms) = let
val (vbox pf_saved | p_saved) = ref_get_view_ptr env.savedlst
in
case+ !p_saved of
| ~list_vt_cons (mms, rest) => begin
!p_saved := (rest: List_vt mms); mms
end | list_vt_nil () => begin
fold@ (!p_saved); $effmask_ref (abort ())
end end : mms val () = let
val (vbox pf_m | p_m) = ref_get_view_ptr env.map
in
symmap_free<itm> (!p_m); !p_m := m
end val () = let
val (vbox pf_ms | p_ms) = ref_get_view_ptr env.maplst
in
symmaplst_free<itm> (!p_ms); !p_ms := ms
end in
end
implement
symenv_top_get (env) = let
val r_m = env.map
val (vbox pf_m | p_m) = ref_get_view_ptr r_m
val m = !p_m
in
!p_m := symmap_make (); m
end
implement symenv_reftop_get (env) = env.map
implement{itm}
symenv_localjoin (env) = let
fn abort (): symmap itm = begin
prerr_interror ();
prerr ": symenv_localjoin: env.maplst is empty"; prerr_newline ();
exit {symmap itm} (1)
end val m1 = m where {
val (vbox pf_ms | p_ms) = ref_get_view_ptr env.maplst
val m = (case+ !p_ms of
| ~list_vt_cons (m, ms) => begin
!p_ms := (ms: symmaplst itm); m
end | list_vt_nil () => begin
fold@ (!p_ms); $effmask_ref (abort ())
end ) : symmap itm
} val () = symmap_free<itm> m1
val m2 = m where {
val (vbox pf_ms | p_ms) = ref_get_view_ptr env.maplst
val m = (case+ !p_ms of
| ~list_vt_cons (m, ms) => m where {
val () = !p_ms := (ms: symmaplst itm)
} | list_vt_nil () => begin
fold@ (!p_ms); $effmask_ref (abort ())
end ) : symmap itm
} val (vbox pf_m | p_m) = ref_get_view_ptr env.map
in
!p_m := $Map.map_join (m2, !p_m)
end
implement
symenv_pervasive_add (env, m) = let
val (pfbox | p_ms) = ref_get_view_ptr env.pervasive
prval vbox pf_ms = pfbox
in
!p_ms := list_vt_cons (m, !p_ms)
end