(***********************************************************************)
(* *)
(* Applied Type System *)
(* *)
(* Hongwei Xi *)
(* *)
(***********************************************************************)
(*
** ATS - Unleashing the Potential of Types!
**
** Copyright (C) 2002-2008 Hongwei Xi, Boston University
**
** All rights reserved
**
** ATS is free software; you can redistribute it and/or modify it under
** the terms of the GNU LESSER GENERAL PUBLIC LICENSE as published by the
** Free Software Foundation; either version 2.1, or (at your option) any
** later version.
**
** ATS is distributed in the hope that it will be useful, but WITHOUT ANY
** WARRANTY; without even the implied warranty of MERCHANTABILITY or
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
** for more details.
**
** You should have received a copy of the GNU General Public License
** along with ATS; see the file COPYING. If not, please write to the
** Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
** 02110-1301, USA.
*)
(* ****** ****** *)
(* author: Hongwei Xi (hwxi AT cs DOT bu DOT edu) *)
(* ****** ****** *)
%{^
#include "prelude/CATS/array.cats"
%} // end of [%{^]
(* ****** ****** *)
#define ATS_DYNLOADFLAG 0 // loaded by [ats_main_prelude]
(* ****** ****** *)
#define i2sz size1_of_int1
(* ****** ****** *)
(* array pointers *)
(* ****** ****** *)
implement{a} array_ptr_get_elt_at (A, i) = A.[i]
implement{a} array_ptr_set_elt_at (A, i, x) = (A.[i] := x)
implement{a}
array_ptr_xch_elt_at (A, i, x) = let
var tmp: a // uninitialized
val (pf, fpf | p) = array_ptr_takeout_tsz (view@ A | &A, i, sizeof)
val () = (tmp := !p; !p := x); prval () = view@ A := fpf pf
in
x := tmp
end // end of [array_ptr_xch_elt_at]
implement{a}
array_ptr_exch (A, i, j) = let
var tmp: a // uninitialized
extern prfun __copy {l:addr} (pf: !a @ l): a @ l
val (pf, fpf | pi) = array_ptr_takeout_tsz (view@ A | &A, i, sizeof)
prval pfi = __copy (pf)
prval () = view@ A := fpf (pf)
val (pf, fpf | pj) = array_ptr_takeout_tsz (view@ A | &A, j, sizeof)
prval pfj = __copy (pf)
prval () = view@ A := fpf (pf)
val () = (tmp := !pi; !pi := !pj; !pj := tmp)
extern prfun __free {l:addr} (pf: a @ l): void
prval () = __free (pfi)
prval () = __free (pfj)
in
// nothing
end // end of [array_ptr_exch]
(* ****** ****** *)
//
// These functions are present solely for notational convenience:
//
implement{a}
array_ptr_get_elt_at__intsz (A, i) = let val i = i2sz i in A.[i] end
implement{a}
array_ptr_set_elt_at__intsz (A, i, x) = let val i = i2sz i in A.[i] := x end
implement{a}
array_ptr_xch_elt_at__intsz (A, i, x) = let
val i = i2sz i in array_ptr_xch_elt_at (A, i, x)
end // end of [array_ptr_xch_elt_at__intsz]
(* ****** ****** *)
implement{a}
array_ptr_alloc (asz) = array_ptr_alloc_tsz {a} (asz, sizeof)
(* ****** ****** *)
implement{a}
array_ptr_allocfree (asz) = array_ptr_allocfree_tsz {a} (asz, sizeof)
implement
array_ptr_allocfree_tsz {a} (asz, tsz) = let
val [l:addr] (pf_gc, pf_arr | p_arr) = array_ptr_alloc_tsz {a} (asz, tsz)
in #[l | (
pf_arr | p_arr
, lam (pf_arr | p_arr) = array_ptr_free {a} (pf_gc, pf_arr | p_arr)
) ] end // end of [array_ptr_allocfree_tsz]
(* ****** ****** *)
implement{a}
array_ptr_initialize_elt (A0, n0, x0) = let
fun loop {n:nat} {l:addr} ..
(pf: array_v (a?, n, l) | p: ptr l, n: size_t n, x0: a)
:<> (array_v (a, n, l) | void) =
if n > 0 then let
prval (pf1, pf2) = array_v_uncons {a?} (pf)
val () = !p := x0
val (pf2 | ans) = loop (pf2 | p+sizeof, n-1, x0)
in
(array_v_cons {a} (pf1, pf2) | ans)
end else let
prval () = array_v_unnil {a?} (pf)
in
(array_v_nil {a} () | ())
end // end of [if]
// end of [loop]
val (pf | ()) = loop (view@ A0 | &A0, n0, x0)
in
view@ A0 := pf
end // end of [array_ptr_initialize_elt]
(* ****** ****** *)
implement{a}
array_ptr_initialize_lst (A0, xs0) = let
fun loop {n:nat} {l:addr} .. (
pf: array_v (a?, n, l) | p: ptr l, xs: list (a, n)
) :<> (
array_v (a, n, l) | void
) = case+ xs of
| list_cons (x, xs) => let
prval (pf1, pf2) = array_v_uncons {a?} (pf)
val () = !p := x
val (pf2 | ans) = loop (pf2 | p+sizeof, xs)
in
(array_v_cons {a} (pf1, pf2) | ans)
end // end of [list_cons]
| list_nil () => let
prval () = array_v_unnil {a?} (pf) in (array_v_nil {a} () | ())
end // end of [list_nil]
// end of [loop]
val (pf | ()) = loop (view@ A0 | &A0, xs0)
in
view@ A0 := pf
end // end of [array_ptr_initialize_lst]
(* ****** ****** *)
implement{a}
array_ptr_initialize_lst_vt (A0, xs0) = let
fun loop {n:nat} {l:addr} .. (
pf: array_v (a?, n, l) | p: ptr l, xs: list_vt (a, n)
) :<> (
array_v (a, n, l) | void
) = case+ xs of
| ~list_vt_cons (x, xs) => let
prval (pf1, pf2) = array_v_uncons {a?} (pf)
val () = !p := x
val (pf2 | ans) = loop (pf2 | p+sizeof, xs)
in
(array_v_cons {a} (pf1, pf2) | ans)
end (* end of [lsit_vt_cons] *)
| ~list_vt_nil () => let
prval () = array_v_unnil {a?} (pf) in (array_v_nil {a} () | ())
end (* end of [list_vt_nil] *)
// end of [loop]
val (pf | ()) = loop (view@ A0 | &A0, xs0)
in
view@ A0 := pf
end // end of [array_ptr_initialize_lst_vt]
(* ****** ****** *)
implement
array_ptr_initialize_fun_tsz__main
{a} {v} {vt} {n} (pf | base, asz, f, tsz, env) = let
fun loop {i:nat | i <= n} {l:addr} .. (
pf: !v, pf_arr: !array_v (a?, n-i, l) >> array_v (a, n-i, l)
| p: ptr l, n: size_t n, i: size_t i
, f: (!v | sizeLt n, &(a?) >> a, !vt) -<> void, tsz: sizeof_t a, env: !vt
) :<> void =
if i < n then let
prval (pf1_at, pf2_arr) = array_v_uncons {a?} (pf_arr)
val () = f (pf | i, !p, env)
val () = loop (pf, pf2_arr | p + tsz, n, i+1, f, tsz, env)
prval () = pf_arr := array_v_cons {a} (pf1_at, pf2_arr)
in
// nothing
end else let
prval () = array_v_unnil (pf_arr)
prval () = pf_arr := array_v_nil {a} ()
in
// nothing
end // end of [if]
// end of [loop]
in
loop (pf, view@ base | &base, asz, 0, f, tsz, env)
end // end of [array_ptr_initialize_fun_tsz__main]
implement
array_ptr_initialize_fun_tsz
{a} {v} {n} (pf | base, asz, f, tsz) = let
typedef funptr_t = (!v | sizeLt n, &(a?) >> a) -<> void
typedef funptr1_t = (!v | sizeLt n, &(a?) >> a, !ptr) -<> void
val f1 = coerce (f) where {
extern castfn coerce (f: funptr_t):<> funptr1_t
}
val () = array_ptr_initialize_fun_tsz__main
{a} {v} {ptr} (pf | base, asz, f1, tsz, null)
in
// empty
end // end of [array_ptr_initialize_fun_tsz]
(* ****** ****** *)
implement
array_ptr_initialize_clo_tsz__main
{a} {v} {vt} {n} (pf | base, asz, f, tsz, env) = let
fun loop {i:nat | i <= n} {l:addr} .. (
pf: !v, pf_arr: !array_v (a?, n-i, l) >> array_v (a, n-i, l)
| p: ptr l, n: size_t n, i: size_t i
, f: &(!v | sizeLt n, &(a?) >> a, !vt) - void, tsz: sizeof_t a, env: !vt
) :<> void =
if i < n then let
prval (pf1_at, pf2_arr) = array_v_uncons {a?} (pf_arr)
val () = f (pf | i, !p, env)
val () = loop (pf, pf2_arr | p + tsz, n, i+1, f, tsz, env)
prval () = pf_arr := array_v_cons {a} (pf1_at, pf2_arr)
in
// nothing
end else let
prval () = array_v_unnil (pf_arr)
prval () = pf_arr := array_v_nil {a} ()
in
// nothing
end // end of [if]
// end of [loop]
in
loop (pf, view@ base | &base, asz, 0, f, tsz, env)
end // end of [array_ptr_initialize_clo_tsz__main]
implement
array_ptr_initialize_clo_tsz
{a} {v} {n} (pf | base, asz, f, tsz) = let
val p_f = &f; prval pf_f = view@ f
viewtypedef clo_t = (!v | sizeLt n, &(a?) >> a) - void
viewtypedef clo1_t = (!v | sizeLt n, &(a?) >> a, !Ptr) - void
prval pf1_f = coerce (pf_f) where {
extern praxi coerce {l:addr} (pf: clo_t @ l): clo1_t @ l
} // end of [prval]
val () = array_ptr_initialize_clo_tsz__main
{a} {v} {Ptr} (pf | base, asz, !p_f, tsz, null)
prval pf_f = coerce (pf1_f) where {
extern praxi coerce {l:addr} (pf: clo1_t @ l): clo_t @ l
} // end of [prval]
prval () = view@ f := pf_f
in
// empty
end // end of [array_ptr_initialize_clo_tsz]
(* ****** ****** *)
implement
array_ptr_clear_clo_tsz
{a} {v} {n} (pf | base, asz, f, tsz) = let
fun clear {n:nat} {l:addr} .. (
pf: !v,
pf_arr: !array_v (a, n, l) >> array_v (a?, n, l)
| p_arr: ptr l, n: size_t n
, f: &(!v | &a >> a?) - void, tsz: sizeof_t a
) :<> void =
if n > 0 then let
prval (pf1_at, pf2_arr) = array_v_uncons {a} (pf_arr)
val () = f (pf | !p_arr)
val () = clear (pf, pf2_arr | p_arr + tsz, n-1, f, tsz)
in
pf_arr := array_v_cons {a?} (pf1_at, pf2_arr)
end else let
prval () = array_v_unnil {a} (pf_arr)
in
pf_arr := array_v_nil {a?} ()
end // end of [if]
// end of [clear]
in
clear (pf, view@ base | &base, asz, f, tsz)
end // end of [array_ptr_clear_clo_tsz]
(* ****** ****** *)
implement{a}
array_ptr_split (pf | A, i) =
array_ptr_split_tsz {a} (pf | A, i, sizeof)
// end of [array_ptr_split]
(* ****** ****** *)
implement{a}
array_ptr_takeout (pf | A, i) =
array_ptr_takeout_tsz {a} (pf | A, i, sizeof)
// end of [array_ptr_takeout]
(* ****** ****** *)
infixl ( * ) szmul2
implement{a}
array_ptr_takeout2 (pf | A, i1, i2) =
array_ptr_takeout2_tsz {a} (pf | A, i1, i2, sizeof )
// end of [array_ptr_takeout2]
implement
array_ptr_takeout2_tsz
{a} {n, i1, i2} {l0} (pf | A, i1, i2, tsz) = let
val [off1:int] (pf1_mul | off1) = i1 szmul2 tsz
val [off2:int] (pf2_mul | off2) = i2 szmul2 tsz
prval (pf1, pf2, fpf) = array_v_takeout2 {a} (pf1_mul, pf2_mul, pf)
in
#[ l0+off1, l0+off2 | (pf1, pf2, fpf | A+off1, A+off2) ]
end // end of [array_ptr_takeout2_tsz]
(* ****** ****** *)
(* persistent arrays *)
(* ****** ****** *)
assume array_viewt0ype_int_type
(a:viewt@ype, n:int) = [l:addr] @{
data= ptr l, view= vbox (array_v (a, n, l))
} // end of [array_viewt0ype_int_type]
(*
viewtypedef
arraysize_viewt0ype_int_viewt0ype
(a: viewt@ype, n:int) = [l:addr] (free_gc_v l, @[a][n] @ l | ptr l, int n)
// end of [arraysize_viewt0ype_int_viewt0ype]
*)
implement
array_make_arrsz {a} {n} (arrsz) = let
prval () = free_gc_elim {a} (arrsz.0) // return the certificate
val (pfbox | ()) = vbox_make_view_ptr (arrsz.1 | arrsz.2)
in
@{ data= arrsz.2, view= pfbox }
end // end of [array_make_arrsz]
//
implement{a}
array_make_elt (asz, x) = let
val (pf_gc, pf_arr | p_arr) = array_ptr_alloc_tsz {a} (asz, sizeof)
prval () = free_gc_elim {a} (pf_gc) // return the certificate to GC
val () = array_ptr_initialize_elt (!p_arr, asz, x)
val (pfbox | ()) = vbox_make_view_ptr (pf_arr | p_arr)
in
@{ data= p_arr, view= pfbox }
end // end of [array_make_elt]
implement{a}
array_make_lst (asz, xs) = let
val (pf_gc, pf_arr | p_arr) = array_ptr_alloc_tsz {a} (asz, sizeof)
prval () = free_gc_elim {a} (pf_gc) // return the certificate to GC
val () = array_ptr_initialize_lst (!p_arr, xs)
val (pfbox | ()) = vbox_make_view_ptr (pf_arr | p_arr)
in
@{ data= p_arr, view= pfbox }
end // end of [array_make_lst]
(* ****** ****** *)
implement{a}
array_make_clo (pf | asz, f) =
array_make_clo_tsz {a} (pf | asz, f, sizeof)
// end of ...
implement
array_make_clo_tsz {a} (pf | asz, f, tsz) = let
val (pf_gc, pf_arr | p_arr) = array_ptr_alloc_tsz {a} (asz, tsz)
prval () = free_gc_elim {a} (pf_gc) // return the certificate to GC
val () = array_ptr_initialize_clo_tsz {a} (pf | !p_arr, asz, f, tsz)
val (pfbox | ()) = vbox_make_view_ptr (pf_arr | p_arr)
in
@{ data= p_arr, view= pfbox }
end // end of [array_make_clo_tsz]
(* ****** ****** *)
implement{a}
array_make_cloref
(asz, f) = array_make_cloref_tsz {a} (asz, f, sizeof)
// end of ...
implement
array_make_cloref_tsz {a} {n} (asz, f, tsz) = let
val (pf_gc, pf_arr | p_arr) = array_ptr_alloc_tsz {a} (asz, tsz)
prval () = free_gc_elim {a} (pf_gc) // return the certificate to GC
prval pf = unit_v ()
typedef cloref_t = (sizeLt n, &(a?) >> a) - void
val () = array_ptr_initialize_fun_tsz__main
{a} {unit_v} {cloref_t} (pf | !p_arr, asz, app, tsz, f) where {
val app = lam
(pf: !unit_v | i: sizeLt n, x: &(a?) >> a, f: !cloref_t): void = $effmask_all (f (i, x))
} // end of [val]
prval unit_v () = pf
val (pfbox | ()) = vbox_make_view_ptr (pf_arr | p_arr)
in
@{ data= p_arr, view= pfbox }
end // end of [array_make_cloref_tsz]
(* ****** ****** *)
(*
// these are now casting funtions:
implement array_make_view_ptr (pf | p) = @(pf | p)
implement array_get_view_ptr (A) = @(A.view | A.data)
*)
(* ****** ****** *)
implement{a}
array_get_elt_at (A, i) = let
val A_data = A.data; prval vbox pf = A.view in !A_data.[i]
end // end of [array_get_elt]
implement{a}
array_set_elt_at (A, i, x) = let
val A_data = A.data; prval vbox pf = A.view in !A_data.[i] := x
end // end of [array_set_elt_at]
implement{a}
array_xch_elt_at (A, i, x) = let
val A_data = A.data; prval vbox pf = A.view
in
array_ptr_xch_elt_at (!A_data, i, x)
end // end of [array_xch_elt_at]
(* ****** ****** *)
implement{a}
array_get_elt_at__intsz (A, i) = let
val i = i2sz i; val A_data = A.data; prval vbox pf = A.view
in
!A_data.[i]
end // end of [array_get_elt]
implement{a}
array_set_elt_at__intsz (A, i, x) = let
val i = i2sz i; val A_data = A.data; prval vbox pf = A.view
in
!A_data.[i] := x
end // end of [array_set_elt_at]
implement{a}
array_xch_elt_at__intsz (A, i, x) = let
val i = i2sz i; val A_data = A.data; prval vbox pf = A.view
in
array_ptr_xch_elt_at (!A_data, i, x)
end // end of [array_xch_elt_at]
(* ****** ****** *)
implement{a}
array_exch (A, i1, i2) =
if i1 <> i2 then let
val A_data = A.data; prval vbox pf = A.view
in
array_ptr_exch (!A_data, i1, i2)
end // end of [if]
// end of [array_exch]
(* ****** ****** *)
// various [foreach] functions on linear arrays
(* ****** ****** *)
implement
array_ptr_foreach_fun_tsz__main
{a} {v} {vt} {n} (pf | base, f, asz, tsz, env) = let
fun loop {i:nat | i <= n} {l:addr} .. (
pf: !v, pf_arr: !array_v (a, i, l) >> array_v (a, i, l)
| p: ptr l
, f: (!v | &a, !vt) -<> void, i: size_t i, tsz: sizeof_t a
, env: !vt
) :<> void =
if i > 0 then let
prval (pf1_at, pf2_arr) = array_v_uncons {a} (pf_arr)
val () = f (pf | !p, env)
val () = loop (pf, pf2_arr | p + tsz, f, i-1, tsz, env)
prval () = pf_arr := array_v_cons {a} (pf1_at, pf2_arr)
in
// nothing
end else let
prval () = array_v_unnil (pf_arr)
prval () = pf_arr := array_v_nil {a} ()
in
// nothing
end // end of [if]
in
loop (pf, view@ base | &base, f, asz, tsz, env)
end // end of [array_ptr_foreach_fun_tsz__main]
//
implement{a}
array_ptr_foreach_fun (pf_v | A, f, asz) =
array_ptr_foreach_fun_tsz {a} (pf_v | A, f, asz, sizeof)
// end of [implement]
implement
array_ptr_foreach_fun_tsz
{a} {v} {n} (pf_v | A, f, asz, tsz) = let
viewtypedef fun0_t = (!v | &a) - void
viewtypedef fun1_t = (!v | &a, !ptr) - void
val f = __cast (f) where { extern castfn __cast (f: fun0_t):<> fun1_t }
in
array_ptr_foreach_fun_tsz__main
{a} {v} {ptr} (pf_v | A, f, asz, tsz, null)
// end of [array_ptr_foreach_...]
end // end of [array_ptr_foreach_fun_tsz]
//
implement{a}
array_ptr_foreach_clo (pf_v | A, f, asz) =
array_ptr_foreach_clo_tsz {a} (pf_v | A, f, asz, sizeof)
// end of [implement]
implement
array_ptr_foreach_clo_tsz
{a} {v} {n} (pf_v | A, f, asz, tsz) = let
viewtypedef clo_t = (!v | &a) - void
stavar l_f: addr
val p_f: ptr l_f = &f
viewdef V = @(v, clo_t @ l_f)
fn app (pf: !V | x: &a, p_f: !ptr l_f):<> void = let
prval (pf1, pf2) = pf; val () = !p_f (pf1 | x) in pf := (pf1, pf2)
end // end of [app]
prval pf = (pf_v, view@ f)
val () = array_ptr_foreach_fun_tsz__main
{a} {V} {ptr l_f} (pf | A, app, asz, tsz, p_f)
prval (pf1, pf2) = pf
prval () = (pf_v := pf1; view@ f := pf2)
in
// empty
end // end of [array_ptr_foreach_clo_tsz]
(* ****** ****** *)
implement
array_ptr_iforeach_fun_tsz__main
{a} {v} {vt} {n} (pf | base, f, asz, tsz, env) = let
fun loop {i:nat | i <= n} {l:addr} .. (
pf: !v, pf_arr: !array_v (a, n-i, l) >> array_v (a, n-i, l)
| p: ptr l
, f: (!v | sizeLt n, &a, !vt) -<> void, n: size_t n, i: size_t i
, tsz: sizeof_t a, env: !vt
) :<> void =
if i < n then let
prval (pf1_at, pf2_arr) = array_v_uncons {a} (pf_arr)
val () = f (pf | i, !p, env)
val () = loop (pf, pf2_arr | p + tsz, f, n, i+1, tsz, env)
prval () = pf_arr := array_v_cons {a} (pf1_at, pf2_arr)
in
// nothing
end else let
prval () = array_v_unnil (pf_arr)
prval () = pf_arr := array_v_nil {a} ()
in
// nothing
end // end of [if]
in
loop (pf, view@ base | &base, f, asz, 0, tsz, env)
end // end of [array_ptr_iforeach_fun_tsz__main]
//
implement{a}
array_ptr_iforeach_fun (pf_v | A, f, asz) =
array_ptr_iforeach_fun_tsz {a} (pf_v | A, f, asz, sizeof)
// end of [implement]
implement
array_ptr_iforeach_fun_tsz
{a} {v} {n} (pf_v | A, f, asz, tsz) = let
viewtypedef fun0_t = (!v | sizeLt n, &a) - void
viewtypedef fun1_t = (!v | sizeLt n, &a, !ptr) - void
val f = __cast (f) where {
extern castfn __cast (f: fun0_t):<> fun1_t
}
in
array_ptr_iforeach_fun_tsz__main {a} {v} {ptr} (pf_v | A, f, asz, tsz, null)
end // end of [array_ptr_foreach_fun_tsz]
//
implement{a}
array_ptr_iforeach_clo (pf_v | A, f, asz) =
array_ptr_iforeach_clo_tsz {a} (pf_v | A, f, asz, sizeof)
// end of [implement]
implement
array_ptr_iforeach_clo_tsz
{a} {v} {n} (pf_v | A, f, asz, tsz) = let
viewtypedef clo_t = (!v | sizeLt n, &a) - void
stavar l_f: addr
val p_f: ptr l_f = &f
viewdef V = @(v, clo_t @ l_f)
fn app (pf: !V | i: sizeLt n, x: &a, p_f: !ptr l_f):<> void = let
prval (pf1, pf2) = pf; val () = !p_f (pf1 | i, x) in pf := (pf1, pf2)
end // end of [app]
prval pf = (pf_v, view@ f)
val () = array_ptr_iforeach_fun_tsz__main
{a} {V} {ptr l_f} (pf | A, app, asz, tsz, p_f)
prval (pf1, pf2) = pf
prval () = (pf_v := pf1; view@ f := pf2)
in
// empty
end // end of [array_ptr_iforeach_clo_tsz]
(* ****** ****** *)
// various [foreach] functions on persistent arrays
(* ****** ****** *)
implement{a}
array_foreach__main
{v} {vt} {n} (pf | A, f, asz, env) = let
typedef fun_t = (!v | &a, !vt) -<> void
fun loop {i:nat | i <= n} .. (
pf: !v
| A: array (a, n), f: fun_t, n: size_t n, i: size_t i
, env: !vt
) : void =
if i < n then let
val () = () where {
val (vbox pf_arr | p) = array_get_view_ptr (A)
val (pf1, fpf2 | p_i) = array_ptr_takeout (pf_arr | p, i)
val () = f (pf | !p_i, env)
prval () = pf_arr := fpf2 (pf1)
} // end of [val]
in
loop (pf | A, f, n, i+1, env)
end // end of [if]
// end of [loop]
in
loop (pf | A, f, asz, 0, env)
end // end of [array_foreach__main]
implement{a}
array_foreach_fun
{v} {n} (pf | A, f, asz) = let
val f = coerce (f) where { extern castfn
coerce (f: (!v | &a) -<> void):<> (!v | &a, !ptr) -<> void
} // end of [where]
in
array_foreach__main (pf | A, f, asz, null)
end // end of [array_foreach_fun]
implement{a}
array_foreach_clo
{v} {n} (pf_v | A, f, asz) = let
stavar l_f: addr
typedef clo_t = (!v | &a) - void
val p_f: ptr l_f = &f
viewdef V = (v, clo_t @ l_f)
fn app (pf: !V | x: &a, p_f: !ptr l_f):<> void = let
prval (pf1, pf2) = pf in !p_f (pf1 | x); pf := (pf1, pf2)
end // end of [app]
prval pf = (pf_v, view@ f)
val () = array_foreach__main {V} {ptr l_f} (pf | A, app, asz, p_f)
prval (pf1, pf2) = pf
prval () = (pf_v := pf1; view@ f := pf2)
in
// empty
end // end of [array_foreach_clo]
implement{a}
array_foreach_cloref {n} (A, f, asz) = let
viewtypedef cloref_t = (&a) - void
fn app (pf: !unit_v | x: &a, f: !cloref_t):<> void = $effmask_all (f x)
prval pf = unit_v ()
val () = array_foreach__main {unit_v} {cloref_t} (pf | A, app, asz, f)
prval unit_v () = pf
in
// empty
end // end of [array_foreach_cloref]
(* ****** ****** *)
implement{a}
array_iforeach__main
{v} {vt} {n} (pf | A, f, asz, env) = let
viewtypedef fun_t = (!v | sizeLt n, &a, !vt) - void
fun loop {i:nat | i <= n} .. (
pf: !v
| A: array (a, n), f: fun_t, n: size_t n, i: size_t i, env: !vt
) : void =
if i < n then let
val () = () where {
val (vbox pf_arr | p) = array_get_view_ptr (A)
val (pf1, fpf2 | p_i) = array_ptr_takeout (pf_arr | p, i)
val () = f (pf | i, !p_i, env)
prval () = pf_arr := fpf2 (pf1)
} // end of [val]
in
loop (pf | A, f, n, i+1, env)
end // end of [if]
// end of [loop]
val () = loop (pf | A, f, asz, 0, env)
in
// empty
end // end of [array_iforeach__main]
implement{a}
array_iforeach_fun
{v} {n} (pf | A, f, asz) = let
val f = coerce (f) where { extern castfn
coerce (f: (!v | sizeLt n, &a) -<> void):<> (!v | sizeLt n, &a, !ptr) -<> void
} // end of [where]
in
array_iforeach__main (pf | A, f, asz, null)
end // end of [array_foreach_fun]
implement{a}
array_iforeach_clo
{v} {n} (pf_v | A, f, asz) = let
stavar l_f: addr
typedef clo_t = (!v | sizeLt n, &a) - void
val p_f: ptr l_f = &f
viewdef V = (v, clo_t @ l_f)
fn app
(pf: !V | i: sizeLt n, x: &a, p_f: !ptr l_f):<> void = let
prval (pf1, pf2) = pf in !p_f (pf1 | i, x); pf := (pf1, pf2)
end // end of [app]
prval pf = (pf_v, view@ f)
val () = array_iforeach__main {V} {ptr l_f} (pf | A, app, asz, p_f)
prval (pf1, pf2) = pf
prval () = (pf_v := pf1; view@ f := pf2)
in
// empty
end // end of [array_iforeach_clo]
implement{a}
array_iforeach_cloref {n} (A, f, asz) = let
viewtypedef cloref_t = (sizeLt n, &a) - void
fn app (pf: !unit_v | i: sizeLt n, x: &a, f: !cloref_t):<> void = f (i, x)
prval pf = unit_v ()
val () = array_iforeach__main {unit_v} {cloref_t} (pf | A, app, asz, f)
prval unit_v () = pf
in
// empty
end // end of [array_iforeach_cloref]
(* ****** ****** *)
implement{a}
array_ptr_alloc (n) = array_ptr_alloc_tsz {a} (n, sizeof)
// end of [array_ptr_alloc]
(* ****** ****** *)
%{$
typedef unsigned char byte ;
//
// HX-2010-05-24
// In case 'memcpy' is already defined as a macro ...
//
#ifndef memcpy
extern void *memcpy (void *dst, const void* src, size_t n) ;
#endif // end of [memcpy]
ats_void_type
atspre_array_ptr_initialize_elt_tsz (
ats_ptr_type A
, ats_size_type asz
, ats_ptr_type ini
, ats_size_type tsz
) {
int i, itsz ; int left ; ats_ptr_type p ;
if (asz == 0) return ;
memcpy (A, ini, tsz) ;
i = 1 ; itsz = tsz ; left = asz - i ;
while (left > 0) {
p = (ats_ptr_type)(((byte*)A) + itsz) ;
if (left <= i) { memcpy (p, A, left * tsz) ; return ; }
memcpy (p, A, itsz);
i = i + i ; itsz = itsz + itsz ; left = asz - i ;
} /* end of [while] */
return ;
} /* end of [atspre_array_ptr_initialize_elt_tsz] */
%} // end of [%{$]
(* ****** ****** *)
// [array.sats] is already loaded by a call to [pervasive_load]
staload _(*anonymous*) = "prelude/SATS/array.sats" // this forces that the static
// loading function for [array.sats] is to be called at run-time
// this is really needed only if some datatypes are declared in [array.sats]
(* ****** ****** *)
(* end of [array.dats] *)