extern fun strcmp
{m1,n1:nat | n1 < m1}
{m2,n2:nat | n2 < m2} (
s1: &strbuf (m1, n1), s2: &strbuf (m2, n2)
) :<> Sgn
#define NUL '\0'
implement strcmp {m1,n1} {m2,n2}
(s1, s2) = loop (s1, s2, 0) where {
fun loop {i:nat | i <= n1; i <= n2} .<n1-i>.
(s1: &strbuf (m1, n1), s2: &strbuf (m2, n2), i: size_t i):<> Sgn = let
val c1 = strbuf_test_char_at (s1, i)
and c2 = strbuf_test_char_at (s2, i)
in
if c1 = NUL then
if c2 = NUL then 0 else ~1
else
if c2 = NUL then 1 else begin
if c1 < c2 then ~1 else if c1 > c2 then 1 else loop (s1, s2, i+1)
end end }
implement main (argc, argv) = let
val () = assert (argc >= 3)
val str1 = string1_of_string (argv.[1])
and str2 = string1_of_string (argv.[2])
val sgn = let
val (vbox pf1_buf | p1_buf) = strbuf_of_string1 str1 in
$effmask_all let
val (vbox pf2_buf | p2_buf) = strbuf_of_string1 str2 in
strcmp (!p1_buf, !p2_buf)
end end in
printf ("strcmp (%s, %s) = %i\n", @(str1, str2, sgn))
end