staload "libc/SATS/stdio.sats"
#define MAXLINE 1000
typedef b0ytes (n: int) = @[byte?][n]
extern
fun getline {m:pos} {l:addr}
(pf_buf: b0ytes m @ l | p_buf: ptr l, m: int m)
: [n:nat | n < m] (strbuf (m, n) @ l | int n)
= "__getline"
extern
fun copy {m,n:nat | n < m} {l_to,l_from:addr} (
pf_to: !b0ytes m @ l_to >> strbuf (m, n) @ l_to
, pf_from: !strbuf (m, n) @ l_from
| p_to: ptr l_to, p_from: ptr l_from
) : void
= "__copy"
#define s2b bytes_v_of_strbuf_v
implement main () = let
#define M MAXLINE
var !p_line with pf_line = @[byte][M]()
var !p_longest with pf_longest = @[byte][M]()
val () = bytes_strbuf_trans (pf_longest | p_longest, 0)
val max = loop (pf_line, pf_longest | p_line, p_longest, 0) where {
fun loop {max:nat | max < M} (
pf_line: !b0ytes M @ p_line
, pf_longest: !strbuf (M, max) @ p_longest >> strbuf (M, max) @ p_longest
| p_line: ptr p_line, p_longest: ptr p_longest, max: int (max)
) : #[max: nat | max < M] int max = let
val (pf_line_new | n) = getline (pf_line | p_line, M)
in
if n = 0 then let
prval () = pf_line := s2b (pf_line_new)
in
max end else begin
if max < n then let
prval () = pf_longest := s2b (pf_longest)
val () = copy (pf_longest, pf_line_new | p_longest, p_line)
prval () = pf_line := s2b (pf_line_new)
in
loop (pf_line, pf_longest | p_line, p_longest, n)
end else let
prval () = pf_line := s2b (pf_line_new)
in
loop (pf_line, pf_longest | p_line, p_longest, max)
end
end end
}
in
if (max > 0) then let
val () = print_string (str) where {
extern castfn string_of_ptr (p: ptr): string
val str = string_of_ptr (p_longest)
} prval () = pf_longest := s2b (pf_longest)
in
end else let
prval () = pf_longest := s2b (pf_longest)
in
end end
%{$
ats_int_type
__getline (
ats_ptr_type s0, ats_int_type lim
) {
int c, i; char *s = (char*)s0 ;
for (i = 0; i < lim-1 && (c=getchar()) != EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n') { s[i] = c; ++i; }
s[i] = '\0';
return i;
} // end of [__getline]
ats_void_type
__copy (
ats_ptr_type to, ats_ptr_type from
) {
int i;
i = 0;
while ((((char*)to)[i] = ((char*)from)[i]) != '\0') ++i;
return ;
} // end of [__copy]
%}