%{^
#include "ats_counter.cats" /* only needed for [ATS/Geizella] */
%}
staload Cnt = "ats_counter.sats"
staload Stamp = "ats_stamp.sats"
staload Sym = "ats_symbol.sats"
staload "ats_staexp2.sats"
typedef s2var_struct = @{
s2var_sym= sym_t , s2var_srt= s2rt , s2var_tmplev= int , s2var_sVarset= s2Varset_t , s2var_stamp= stamp_t }
local
assume s2var_t = [l:addr] (vbox (s2var_struct @ l) | ptr l)
val s2var_name_counter = $Cnt.counter_make ()
fn s2var_name_make (): sym_t = let
val n = $Cnt.counter_get_and_inc s2var_name_counter
in
$Sym.symbol_make_string ($Cnt.tostring_prefix_count ("$", n))
end
fn s2var_name_make_prefix (pre: string): sym_t = let
val n = $Cnt.counter_get_and_inc s2var_name_counter
in
$Sym.symbol_make_string (pre + $Cnt.tostring_prefix_count ("$", n))
end
in
implement s2var_make_id_srt (id, s2t) = let
val stamp = $Stamp.s2var_stamp_make ()
val (pf_gc, pf | p) = ptr_alloc_tsz {s2var_struct} (sizeof<s2var_struct>)
prval () = free_gc_elim {s2var_struct} (pf_gc)
val () = begin
p->s2var_sym := id;
p->s2var_srt := s2t;
p->s2var_tmplev := 0;
p->s2var_sVarset := s2Varset_nil;
p->s2var_stamp := stamp
end
val (pfbox | ()) = vbox_make_view_ptr (pf | p)
in
(pfbox | p)
end
implement s2var_make_srt (s2t) = let
val id = s2var_name_make ()
in
s2var_make_id_srt (id, s2t)
end
implement s2var_copy (s2v0) = let
val id0 = s2var_sym_get s2v0
val s2t0 = s2var_srt_get s2v0
val id_new = s2var_name_make_prefix ($Sym.symbol_name id0)
in
s2var_make_id_srt (id_new, s2t0)
end
implement s2var_sym_get (s2v) =
let val (vbox pf | p) = s2v in p->s2var_sym end
implement s2var_srt_get (s2v) =
let val (vbox pf | p) = s2v in p->s2var_srt end
implement s2var_tmplev_get (s2v) =
let val (vbox pf | p) = s2v in p->s2var_tmplev end
implement s2var_tmplev_set (s2v, lev) =
let val (vbox pf | p) = s2v in p->s2var_tmplev := lev end
implement s2var_sVarset_get (s2v) =
let val (vbox pf | p) = s2v in p->s2var_sVarset end
implement s2var_sVarset_set (s2v, sVs) =
let val (vbox pf | p) = s2v in p->s2var_sVarset := sVs end
implement
s2varlst_sVarset_set (s2vs, sVs) = let
fun loop (s2vs: s2varlst, sVs: s2Varset_t): void =
case+ s2vs of
| list_cons (s2v, s2vs) => (
s2var_sVarset_set (s2v, sVs); loop (s2vs, sVs)
) | list_nil () => ()
in
loop (s2vs, sVs)
end
implement s2var_stamp_get (s2v) =
let val (vbox pf | p) = s2v in p->s2var_stamp end
fn lt_s2var_s2var
(s2v1: s2var_t, s2v2: s2var_t): bool = let
val stamp1 =
let val (vbox pf1 | p1) = s2v1 in p1->s2var_stamp end
val stamp2 =
let val (vbox pf2 | p2) = s2v2 in p2->s2var_stamp end
in
$Stamp.lt_stamp_stamp (stamp1, stamp2)
end
fn lte_s2var_s2var
(s2v1: s2var_t, s2v2: s2var_t): bool = let
val stamp1 =
let val (vbox pf1 | p1) = s2v1 in p1->s2var_stamp end
val stamp2 =
let val (vbox pf2 | p2) = s2v2 in p2->s2var_stamp end
in
$Stamp.lte_stamp_stamp (stamp1, stamp2)
end
fn _eq_s2var_s2var
(s2v1: s2var_t, s2v2: s2var_t): bool = let
val stamp1 =
let val (vbox pf1 | p1) = s2v1 in p1->s2var_stamp end
val stamp2 =
let val (vbox pf2 | p2) = s2v2 in p2->s2var_stamp end
in
$Stamp.eq_stamp_stamp (stamp1, stamp2)
end
implement eq_s2var_s2var (s2v1, s2v2) =
$effmask_all ( _eq_s2var_s2var (s2v1, s2v2) )
fn _neq_s2var_s2var
(s2v1: s2var_t, s2v2: s2var_t): bool = let
val stamp1 =
let val (vbox pf1 | p1) = s2v1 in p1->s2var_stamp end
val stamp2 =
let val (vbox pf2 | p2) = s2v2 in p2->s2var_stamp end
in
$Stamp.neq_stamp_stamp (stamp1, stamp2)
end
implement neq_s2var_s2var (s2v1, s2v2) =
$effmask_all ( _neq_s2var_s2var (s2v1, s2v2) )
fn _compare_s2var_s2var
(s2v1: s2var_t, s2v2: s2var_t): Sgn = let
val stamp1 =
let val (vbox pf1 | p1) = s2v1 in p1->s2var_stamp end
val stamp2 =
let val (vbox pf2 | p2) = s2v2 in p2->s2var_stamp end
in
$Stamp.compare_stamp_stamp (stamp1, stamp2)
end
implement compare_s2var_s2var (s2v1, s2v2) =
$effmask_all ( _compare_s2var_s2var (s2v1, s2v2) )
implement s2var_is_boxed (s2v) =
s2rt_is_boxed (s2var_srt_get s2v)
implement s2var_is_unboxed (s2v) = ~(s2var_is_boxed s2v)
end
implement fprint_s2var (pf | out, s2v) = let
val () = $Sym.fprint_symbol (pf | out, s2var_sym_get s2v)
val () = fprint_string (pf | out, "(")
val () = $Stamp.fprint_stamp (pf | out, s2var_stamp_get s2v)
val () = fprint_string (pf | out, ")")
in
end
implement fprint_s2varlst {m} (pf | out, s2vs) = let
fun aux (out: &FILE m, i: int, s2vs: s2varlst)
: void = begin case+ s2vs of
| list_cons (s2v, s2vs) => begin
if i > 0 then fprint1_string (pf | out, ", ");
fprint_s2var (pf | out, s2v); aux (out, i+1, s2vs)
end | list_nil () => ()
end in
aux (out, 0, s2vs)
end
implement print_s2var (s2v) = print_mac (fprint_s2var, s2v)
implement prerr_s2var (s2v) = prerr_mac (fprint_s2var, s2v)
implement print_s2varlst (s2vs) = print_mac (fprint_s2varlst, s2vs)
implement prerr_s2varlst (s2vs) = prerr_mac (fprint_s2varlst, s2vs)
local
staload Set = "ats_set_fun.sats"
staload _ = "ats_set_fun.dats"
assume s2varset_t = $Set.set_t (s2var_t)
fn cmp (s2v1: s2var_t, s2v2: s2var_t):<> Sgn =
$effmask_all (compare_s2var_s2var (s2v1, s2v2))
fn fprint_s2varset_ptr
{m:file_mode} {l:addr} (
pf_mod: file_mode_lte (m, w)
, pf_out: !FILE m @ l
| p: ptr l, svs: s2varset_t
) : void = let
typedef ptrint = (ptr l, int)
var pi: ptrint; val () = pi.0 := p; val () = pi.1 := 0
viewdef V = @(FILE m @ l, ptrint @ pi)
fn pr
(pf: !V | s2v: s2var_t, pi: !ptr pi): void = let
prval pf_out = pf.0
prval pf_at = pf.1; val p = pi->0; val i = pi->1
in
if i > 0 then fprint1_string (pf_mod | !p, ", ");
pi->1 := i + 1;
fprint_s2var (pf_mod | !p, s2v);
pf.0 := pf_out;
pf.1 := pf_at;
end prval pf = @(pf_out, view@ pi)
val () = $Set.set_foreach_main {V} {ptr pi} (pf | svs, pr, &pi)
in pf_out := pf.0; view@ pi := pf.1
end
in
implement fprint_s2varset (pf | out, svs) =
fprint_s2varset_ptr (pf, view@ out | &out, svs)
implement s2varset_nil = $Set.set_nil
implement s2varset_add (svs, s2v) = $Set.set_insert (svs, s2v, cmp)
implement s2varset_adds (svs, s2vs) = case+ s2vs of
| list_cons (s2v, s2vs) => s2varset_adds (s2varset_add (svs, s2v), s2vs)
| list_nil () => svs
implement s2varset_del (svs, s2v) = $Set.set_remove (svs, s2v, cmp)
implement s2varset_dels (svs, s2vs) = case+ s2vs of
| list_cons (s2v, s2vs) => s2varset_dels (s2varset_del (svs, s2v), s2vs)
| list_nil () => svs
implement s2varset_union (svs1, svs2) = $Set.set_union (svs1, svs2, cmp)
implement s2varset_ismem (svs, s2v) = $Set.set_member (svs, s2v, cmp)
end
local
typedef s2Varbound_struct = @{
s2Varbound_loc= loc_t, s2Varbound_val= s2exp
}
assume s2Varbound_t =
[l:addr] (vbox (s2Varbound_struct @ l) | ptr l)
in
implement s2Varbound_make (loc, s2e) = let
val (pf_gc, pf | p) = begin
ptr_alloc_tsz {s2Varbound_struct} (sizeof<s2Varbound_struct>)
end prval () = free_gc_elim {s2Varbound_struct} (pf_gc)
val () = (p->s2Varbound_loc := loc; p->s2Varbound_val := s2e)
val (pfbox | ()) = vbox_make_view_ptr (pf | p)
in
(pfbox | p)
end
implement s2Varbound_loc_get (s2Vb) =
let val (vbox pf | p) = s2Vb in p->s2Varbound_loc end
implement s2Varbound_val_get (s2Vb) =
let val (vbox pf | p) = s2Vb in p->s2Varbound_val end
end
typedef s2Var_struct = @{
s2Var_loc= loc_t , s2Var_cnt= count_t , s2Var_srt= s2rt , s2Var_svar= Option s2var_t , s2Var_equal= bool , s2Var_link= s2expopt , s2Var_lbs= s2Varboundlst , s2Var_ubs= s2Varboundlst , s2Var_sVarset = s2Varset_t , s2Var_stamp= stamp_t }
local
assume s2Var_t = [l:addr] (vbox (s2Var_struct @ l) | ptr l)
val s2Var_name_counter = $Cnt.counter_make ()
in
implement s2Var_make_srt (loc, s2t) = let
val cnt = $Cnt.counter_get_and_inc (s2Var_name_counter)
val stamp = $Stamp.s2Var_stamp_make ()
val (pf_gc, pf | p) = ptr_alloc_tsz {s2Var_struct} (sizeof<s2Var_struct>)
prval () = free_gc_elim {s2Var_struct} (pf_gc)
val () = begin
p->s2Var_loc := loc;
p->s2Var_cnt := cnt;
p->s2Var_svar := None ();
p->s2Var_srt := s2t;
p->s2Var_equal := false;
p->s2Var_link := None ();
p->s2Var_lbs := list_nil ();
p->s2Var_ubs := list_nil ();
p->s2Var_sVarset := s2Varset_nil;
p->s2Var_stamp := stamp
end
val (pfbox | ()) = vbox_make_view_ptr (pf | p)
in
(pfbox | p)
end
implement s2Var_make_var (loc, s2v) = let
val cnt = $Cnt.counter_get_and_inc (s2Var_name_counter)
val stamp = $Stamp.s2Var_stamp_make ()
val s2t = s2var_srt_get s2v
val (pf_gc, pf | p) = ptr_alloc_tsz {s2Var_struct} (sizeof<s2Var_struct>)
prval () = free_gc_elim {s2Var_struct} (pf_gc)
val () = begin
p->s2Var_loc := loc;
p->s2Var_cnt := cnt;
p->s2Var_svar := Some s2v;
p->s2Var_srt := s2t;
p->s2Var_equal := false;
p->s2Var_link := None ();
p->s2Var_lbs := list_nil ();
p->s2Var_ubs := list_nil ();
p->s2Var_sVarset := s2Varset_nil;
p->s2Var_stamp := stamp
end
val (pfbox | ()) = vbox_make_view_ptr (pf | p)
in
(pfbox | p)
end
implement s2Var_loc_get (s2V) =
let val (vbox pf | p) = s2V in p->s2Var_loc end
implement s2Var_cnt_get (s2V) =
let val (vbox pf | p) = s2V in p->s2Var_cnt end
implement s2Var_srt_get (s2V) =
let val (vbox pf | p) = s2V in p->s2Var_srt end
implement s2Var_srt_set (s2V, s2t) =
let val (vbox pf | p) = s2V in p->s2Var_srt := s2t end
implement s2Var_svar_get (s2V) =
let val (vbox pf | p) = s2V in p->s2Var_svar end
implement s2Var_link_get (s2V) =
let val (vbox pf | p) = s2V in p->s2Var_link end
implement s2Var_link_set (s2V, os2e) =
let val (vbox pf | p) = s2V in p->s2Var_link := os2e end
implement s2Var_lbs_get (s2V) =
let val (vbox pf | p) = s2V in p->s2Var_lbs end
implement s2Var_lbs_set (s2V, lbs) =
let val (vbox pf | p) = s2V in p->s2Var_lbs := lbs end
implement s2Var_ubs_get (s2V) =
let val (vbox pf | p) = s2V in p->s2Var_ubs end
implement s2Var_ubs_set (s2V, ubs) =
let val (vbox pf | p) = s2V in p->s2Var_ubs := ubs end
implement s2Var_sVarset_get (s2V) =
let val (vbox pf | p) = s2V in p->s2Var_sVarset end
implement s2Var_sVarset_set (s2V, sVs) =
let val (vbox pf | p) = s2V in p->s2Var_sVarset := sVs end
implement s2Var_stamp_get (s2V) =
let val (vbox pf | p) = s2V in p->s2Var_stamp end
implement
lt_s2Var_s2Var (s2V1, s2V2) = let
val stamp1 =
let val (vbox pf1 | p1) = s2V1 in p1->s2Var_stamp end
val stamp2 =
let val (vbox pf2 | p2) = s2V2 in p2->s2Var_stamp end
in
$Stamp.lt_stamp_stamp (stamp1, stamp2)
end
implement
lte_s2Var_s2Var (s2V1, s2V2) = let
val stamp1 =
let val (vbox pf1 | p1) = s2V1 in p1->s2Var_stamp end
val stamp2 =
let val (vbox pf2 | p2) = s2V2 in p2->s2Var_stamp end
in
$Stamp.lte_stamp_stamp (stamp1, stamp2)
end
implement
eq_s2Var_s2Var (s2V1, s2V2) = let
val stamp1 =
let val (vbox pf1 | p1) = s2V1 in p1->s2Var_stamp end
val stamp2 =
let val (vbox pf2 | p2) = s2V2 in p2->s2Var_stamp end
in
$Stamp.eq_stamp_stamp (stamp1, stamp2)
end
implement
neq_s2Var_s2Var (s2V1, s2V2) = let
val stamp1 =
let val (vbox pf1 | p1) = s2V1 in p1->s2Var_stamp end
val stamp2 =
let val (vbox pf2 | p2) = s2V2 in p2->s2Var_stamp end
in
$Stamp.neq_stamp_stamp (stamp1, stamp2)
end
implement
compare_s2Var_s2Var (s2V1, s2V2) = let
val stamp1 =
let val (vbox pf1 | p1) = s2V1 in p1->s2Var_stamp end
val stamp2 =
let val (vbox pf2 | p2) = s2V2 in p2->s2Var_stamp end
in
$Stamp.compare_stamp_stamp (stamp1, stamp2)
end
end
implement fprint_s2Var (pf | out, s2V) =
$Cnt.fprint_count (pf | out, s2Var_cnt_get s2V)
implement print_s2Var (s2V) = print_mac (fprint_s2Var, s2V)
implement prerr_s2Var (s2V) = prerr_mac (fprint_s2Var, s2V)
implement fprint_s2Varlst {m} (pf | out, s2Vs) = let
fun aux (out: &FILE m, i: int, s2Vs: s2Varlst)
: void = begin case+ s2Vs of
| list_cons (s2V, s2Vs) => begin
if i > 0 then fprint1_string (pf | out, ", ");
fprint_s2Var (pf | out, s2V); aux (out, i+1, s2Vs)
end | list_nil () => () end in
aux (out, 0, s2Vs)
end
implement print_s2Varlst (s2Vs) = print_mac (fprint_s2Varlst, s2Vs)
implement prerr_s2Varlst (s2Vs) = prerr_mac (fprint_s2Varlst, s2Vs)
local
staload Set = "ats_set_fun.sats"
staload _ = "ats_set_fun.dats"
assume s2Varset_t = $Set.set_t (s2Var_t)
fn cmp (s2V1: s2Var_t, s2V2: s2Var_t):<> Sgn =
$effmask_all (compare_s2Var_s2Var (s2V1, s2V2))
in
fn fprint_s2Varset_ptr
{m:file_mode} {l:addr} (
pf_mod: file_mode_lte (m, w)
, pf_out: !FILE m @ l
| p: ptr l
, sVs: s2Varset_t
) : void = let
typedef ptrint = (ptr l, int)
var pi: ptrint; val () = pi.0 := p; val () = pi.1 := 0
viewdef V = @(FILE m @ l, ptrint @ pi)
fn pr
(pf: !V | s2V: s2Var_t, pi: !ptr pi): void = let
prval pf_out = pf.0
prval pf_at = pf.1; val p = pi->0; val i = pi->1
in
if i > 0 then fprint1_string (pf_mod | !p, ", ");
pi->1 := i + 1;
fprint_s2Var (pf_mod | !p, s2V);
pf.0 := pf_out;
pf.1 := pf_at;
end prval pf = @(pf_out, view@ pi)
val () = $Set.set_foreach_main {V} {ptr pi} (pf | sVs, pr, &pi)
in pf_out := pf.0; view@ pi := pf.1
end
implement fprint_s2Varset (pf | out, sVs) =
fprint_s2Varset_ptr (pf, view@ out | &out, sVs)
implement s2Varset_nil = $Set.set_nil
implement
s2Varset_add (sVs, s2V) = $Set.set_insert (sVs, s2V, cmp)
implement s2Varset_adds (sVs, s2Vs) = case+ s2Vs of
| list_cons (s2V, s2Vs) => s2Varset_adds (s2Varset_add (sVs, s2V), s2Vs)
| list_nil () => sVs
implement
s2Varset_del (sVs, s2V) = $Set.set_remove (sVs, s2V, cmp)
implement s2Varset_dels (sVs, s2Vs) = case+ s2Vs of
| list_cons (s2V, s2Vs) => s2Varset_dels (s2Varset_del (sVs, s2V), s2Vs)
| list_nil () => sVs
implement s2Varset_union (sVs1, sVs2) = $Set.set_union (sVs1, sVs2, cmp)
implement s2Varset_ismem (sVs, s2V) = $Set.set_member (sVs, s2V, cmp)
end