This is just a quick question on advice before starting something. I just
started out looking at ATS2 today, I noticed fgets functions seem to have
changed in several ways from ATS to ATS2. Chiefly, it seems that ATS1 has
FILE streams and ATS2 has FILEref and FILEptrs.
I want to write a function to read in matrices (tabular data) that will be
used going forward in ATS2, but I also need it now in ATS for (hopefully)
the last peg in the ATS-part of the project I’ve been working on. This
probably isn’t a terribly important feature for my program, but I may as
well get it over with now :). I guess the best thing to do would be to
just use fgets_err in ATS1, which seems to match up more with fgets in
ATS2. I am guessing that using the linear type would be best here, since it
would be part of a library function that others may use, so we can always
avoid forcing a GC requirement.
ATS2:
dataview
fgets_v (
sz:int, n0: int, addr, addr
) =
| {lbf:addr}
fgets_v_fail (sz, n0, lbf, null) of b0ytes(sz) @ lbf
| {n:nat | n < n0} {lbf:agz}
fgets_v_succ (sz, n0, lbf, lbf) of strbuf(sz, n) @ lbf
// end of [fgets_v]
*)
//
symintr fgets
//
fun fgets0
{sz:int}{n0:pos | n0 <= sz}
(
buf: &bytes(sz) >> _, n0: int n0, filr: FILEref
) :<!wrt> Ptr0 // = addr@(buf) or NULL
fun fgets1
{sz:int}{n0:pos | n0 <= sz}{m:fm}
(
pfm: fmlte (m, r)
| buf: &bytes(sz) >> _, n0: int n0, filp: !FILEptr1 (m)
) :<!wrt> Ptr0 // = addr@(buf) or NULL
//
overload fgets with fgets0
overload fgets with fgets1
ATS:
dataview
fgets_v (sz:int, n0: int, addr, addr) =
| {l_buf:addr}
fgets_v_fail (sz, n0, l_buf, null) of b0ytes (sz) @ l_buf
| {n:nat | n < n0} {l_buf:addr | l_buf > null}
fgets_v_succ (sz, n0, l_buf, l_buf) of strbuf (sz, n) @ l_buf
// end of [fgets_v]
fun fgets_err
{sz,n0:int | 0 < n0; n0 <= sz}
{m:fm} {l_buf:addr} (
pf_mod: file_mode_lte (m, r)
, pf_buf: b0ytes (sz) @ l_buf
| p: ptr l_buf, n0: int n0, f: &FILE m
) :<> [l:addr] (fgets_v (sz, n0, l_buf, l) | ptr l)
= “mac#atslib_fgets_err”
// end of [fgets_err]
//
// HX:
// this function returns an empty strbuf
// if EOF is reached but no character is read
//
fun fgets_exn
{sz,n0:int | 0 < n0; n0 <= sz}
{m:fm} {l_buf:addr} (
pf_mod: file_mode_lte (m, r),
pf_buf: !b0ytes (sz) @ l_buf >>
[n:nat | n < n0] strbuf (sz, n) @ l_buf
| p: ptr l_buf, n0: int n0, f: &FILE m
) :<!exn> void = “atslib_fgets_exn”
// end of [fgets_exn]