(* String -- 1994-12-10, 1995-11-07, 1999-04-22 *)local type char = Char.char; prim_val sub_ : string -> int -> char = 2 "get_nth_char"; prim_val mkstring_ : int -> string = 1 "create_string"; prim_val update_ : string -> int -> char -> unit = 3 "set_nth_char"; prim_val strcmp_ : string -> string -> int = 2 "compare_strings"; prim_val blit_ : string -> int -> string -> int -> int -> unit = 5 "blit_string"; fun (f o g) x = f (g x);intype string = stringval maxSize = Strbase.maxlenval size = sizefun sub(s, i) = if i<0 orelse i >= size s then raise Subscript else sub_ s i;fun concat strs = let fun acc [] len = len | acc (v1::vr) len = acc vr (size v1 + len) val len = acc strs 0 val newstr = if len > maxSize then raise Size else mkstring_ len fun copyall to [] = () | copyall to (v1::vr) = let val len1 = size v1 in blit_ v1 0 newstr to len1; copyall (to+len1) vr end in copyall 0 strs; newstr end;val op ^ = op ^;fun str c = let val newstr = mkstring_ 1 in update_ newstr 0 c; newstr end;fun implode cs = let val n = List.length cs val newstr = if n > maxSize then raise Size else mkstring_ n fun init [] i = () | init (c::cr) i = (update_ newstr i c; init cr (i+1)) in (init cs 0; newstr) end;fun extract (s, i, slicelen) = let val n = case slicelen of NONE => size s - i | SOME n => n val newstr = if i<0 orelse n<0 orelse n>size s-i then raise Subscript else mkstring_ n in blit_ s i newstr 0 n; newstr end;fun substring (s, i, n) = extract(s, i, SOME n);fun explode s = let fun h j res = if j<0 then res else h (j-1) (sub_ s j :: res) in h (size s - 1) [] end;fun map (f : char -> char) (a : string) : string = let val stop = size a val newstr = mkstring_ stop fun lr j = if j < stop then (update_ newstr j (f(sub_ a j)); lr (j+1)) else () in lr 0; newstr endfun compare (s1, s2) = (case strcmp_ s1 s2 of ~2 => LESS | ~1 => LESS | 0 => EQUAL | 1 => GREATER | 2 => GREATER | _ => raise Fail "internal error: String.compare");fun collate cmp (s1, s2) = let val n1 = size s1 and n2 = size s2 val stop = if n1 < n2 then n1 else n2 fun h j = (* At this point s1[0..j-1] = s2[0..j-1] *) if j = stop then if n1 < n2 then LESS else if n1 > n2 then GREATER else EQUAL else case cmp(sub_ s1 j, sub_ s2 j) of LESS => LESS | GREATER => GREATER | EQUAL => h (j+1) in h 0 end;fun translate f s = Strbase.translate f (s, 0, size s);fun tokens p s = List.map substring (Strbase.tokens p (s, 0, size s));fun fields p s = List.map substring (Strbase.fields p (s, 0, size s));fun isPrefix s1 s2 = let val n1 = size s1 and n2 = size s2 val stop = if n1 < n2 then n1 else n2 fun h j = (* At this point s1[0..j-1] = s2[0..j-1] *) j = stop orelse sub_ s1 j = sub_ s2 j andalso h (j+1) in n1 <= n2 andalso h 0 end;fun foldl f e s = let val stop = size s fun h j res = if j>=stop then res else h (j+1) (f (sub_ s j, res)) in h 0 e end;fun foldr f e s = let fun h j res = if j<0 then res else h (j-1) (f (sub_ s j, res)) in h (size s - 1) e end;fun find p s = let val stop = size s fun h j = if j>=stop then NONE else if p (sub_ s j) then SOME j else h (j+1) in h 0 end;fun fromString s = let fun getc i = if i < size s then SOME (sub_ s i, i+1) else NONE fun h src res = case getc src of NONE => SOME (implode(List.rev res)) | SOME(#"\\", src1) => (case Strbase.fromMLescape getc src1 of NONE => NONE | SOME(c, src2) => h src2 (c :: res)) | SOME(c, src1) => h src1 (c :: res) in h 0 [] end;fun toString s = Strbase.translate Strbase.toMLescape (s, 0, size s);fun fromCString s = Strbase.fromCString sfun toCString s = Strbase.translate Strbase.toCescape (s, 0, size s)val op < = op < : string * string -> bool;val op <= = op <= : string * string -> bool;val op > = op > : string * string -> bool;val op >= = op >= : string * string -> bool;end
(* String -- 1994-12-10, 1995-11-07, 1999-04-22 *)
local
type char = Char.char;
prim_val sub_ : string -> int -> char = 2 "get_nth_char";
prim_val mkstring_ : int -> string = 1 "create_string";
prim_val update_ : string -> int -> char -> unit = 3 "set_nth_char";
prim_val strcmp_ : string -> string -> int = 2 "compare_strings";
prim_val blit_ : string -> int -> string -> int -> int -> unit
= 5 "blit_string";
fun (f o g) x = f (g x);
in
type string = string
val maxSize = Strbase.maxlen
val size = size
fun sub(s, i) =
if i<0 orelse i >= size s then raise Subscript
else sub_ s i;
fun concat strs =
let fun acc [] len = len
| acc (v1::vr) len = acc vr (size v1 + len)
val len = acc strs 0
val newstr = if len > maxSize then raise Size else mkstring_ len
fun copyall to [] = ()
| copyall to (v1::vr) =
let val len1 = size v1
in blit_ v1 0 newstr to len1; copyall (to+len1) vr end
in copyall 0 strs; newstr end;
val op ^ = op ^;
fun str c =
let val newstr = mkstring_ 1
in update_ newstr 0 c; newstr end;
fun implode cs =
let val n = List.length cs
val newstr = if n > maxSize then raise Size else mkstring_ n
fun init [] i = ()
| init (c::cr) i = (update_ newstr i c; init cr (i+1))
in (init cs 0; newstr) end;
fun extract (s, i, slicelen) =
let val n = case slicelen of NONE => size s - i | SOME n => n
val newstr = if i<0 orelse n<0 orelse n>size s-i then raise Subscript
else mkstring_ n
in blit_ s i newstr 0 n; newstr end;
fun substring (s, i, n) = extract(s, i, SOME n);
fun explode s =
let fun h j res = if j<0 then res
else h (j-1) (sub_ s j :: res)
in h (size s - 1) [] end;
fun map (f : char -> char) (a : string) : string =
let val stop = size a
val newstr = mkstring_ stop
fun lr j = if j < stop then (update_ newstr j (f(sub_ a j));
lr (j+1))
else ()
in lr 0; newstr end
fun compare (s1, s2) =
(case strcmp_ s1 s2 of
~2 => LESS
| ~1 => LESS
| 0 => EQUAL
| 1 => GREATER
| 2 => GREATER
| _ => raise Fail "internal error: String.compare");
fun collate cmp (s1, s2) =
let val n1 = size s1
and n2 = size s2
val stop = if n1 < n2 then n1 else n2
fun h j = (* At this point s1[0..j-1] = s2[0..j-1] *)
if j = stop then if n1 < n2 then LESS
else if n1 > n2 then GREATER
else EQUAL
else
case cmp(sub_ s1 j, sub_ s2 j) of
LESS => LESS
| GREATER => GREATER
| EQUAL => h (j+1)
in h 0 end;
fun translate f s =
Strbase.translate f (s, 0, size s);
fun tokens p s =
List.map substring (Strbase.tokens p (s, 0, size s));
fun fields p s =
List.map substring (Strbase.fields p (s, 0, size s));
fun isPrefix s1 s2 =
let val n1 = size s1
and n2 = size s2
val stop = if n1 < n2 then n1 else n2
fun h j = (* At this point s1[0..j-1] = s2[0..j-1] *)
j = stop orelse sub_ s1 j = sub_ s2 j andalso h (j+1)
in n1 <= n2 andalso h 0 end;
fun foldl f e s =
let val stop = size s
fun h j res = if j>=stop then res
else h (j+1) (f (sub_ s j, res))
in h 0 e end;
fun foldr f e s =
let fun h j res = if j<0 then res
else h (j-1) (f (sub_ s j, res))
in h (size s - 1) e end;
fun find p s =
let val stop = size s
fun h j = if j>=stop then NONE
else if p (sub_ s j) then SOME j
else h (j+1)
in h 0 end;
fun fromString s =
let fun getc i = if i < size s then SOME (sub_ s i, i+1) else NONE
fun h src res =
case getc src of
NONE => SOME (implode(List.rev res))
| SOME(#"\\", src1) =>
(case Strbase.fromMLescape getc src1 of
NONE => NONE
| SOME(c, src2) => h src2 (c :: res))
| SOME(c, src1) => h src1 (c :: res)
in h 0 [] end;
fun toString s = Strbase.translate Strbase.toMLescape (s, 0, size s);
fun fromCString s = Strbase.fromCString s
fun toCString s = Strbase.translate Strbase.toCescape (s, 0, size s)
val op < = op < : string * string -> bool;
val op <= = op <= : string * string -> bool;
val op > = op > : string * string -> bool;
val op >= = op >= : string * string -> bool;
end