home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-07-03 | 2.7 KB | 89 lines | [TEXT/R*ch] |
- (* Strbase -- internal utilities for String and Substring *)
-
- #include "../config/m.h"
- #ifdef SIXTYFOUR
- val maxlen = 144115188075855863; (* = (2^54-1)*8-1, with 64 bit *)
- #else
- val maxlen = 16777211; (* = (2^22-1)*4-1, with 32 bit *)
- #endif
-
- local
- prim_val sub_ : string -> int -> char = 2 "get_nth_char";
- prim_val mkstring_ : int -> string = 1 "create_string";
- prim_val blit_ : string -> int -> string -> int -> int -> unit
- = 5 "blit_string";
-
- fun revconcat strs =
- let fun acc [] len = len
- | acc (v1::vr) len = acc vr (size v1 + len)
- val len = acc strs 0
- val newstr = if len > maxlen then raise Size else mkstring_ len
- fun copyall to [] = () (* Now: to = 0. *)
- | copyall to (v1::vr) =
- let val len1 = size v1
- val to = to - len1
- in blit_ v1 0 newstr to len1; copyall to vr end
- in copyall len strs; newstr end;
-
- fun rest (ss as (s, i, n)) =
- if n = 0 then ss else (s, i+1, n-1);
-
- in
-
- fun foldl f e (s,i,n) =
- let val stop = i+n
- fun h j res = if j>=stop then res
- else h (j+1) (f (sub_ s j, res))
- in h i e end;
-
- fun translate f ss =
- revconcat (foldl (fn (s, res) => f s :: res) [] ss);
-
- local
- fun scanl chop pred (s, i, n) =
- let
- val stop = i+n
- fun scan j = if j < stop andalso pred(sub_ s j) then scan (j+1)
- else j
- in
- chop (s, i, n, scan i - i)
- end
- fun scanr chop pred (s, i, n) =
- let
- val stop = i-1
- fun scan j = if j > stop andalso pred(sub_ s j) then scan(j-1)
- else j
- in
- chop (s, i, n, scan (i+n-1) - i + 1)
- end
- in
- fun splitl p = scanl (fn (s, i, n, k) => ((s, i, k), (s, i+k, n-k))) p
- fun splitr p = scanr (fn (s, i, n, k) => ((s, i, k), (s, i+k, n-k))) p
- fun dropl p = scanl (fn (s, i, n, k) => (s, i+k, n-k)) p
- fun dropr p = scanr (fn (s, i, n, k) => (s, i, k)) p
- fun takel p = scanl (fn (s, i, n, k) => (s, i, k)) p
- fun taker p = scanr (fn (s, i, n, k) => (s, i+k, n-k)) p
- end (* local *)
-
- fun tokens isDelim ss =
- let fun findTok ss = dropl isDelim ss
- fun h (remains as (_, _, n)) res =
- if n = 0 then List.rev res
- else
- let val (token, aftertoken) =
- splitl (fn c => not(isDelim c)) remains
- in h (findTok aftertoken) (token :: res) end
- in h (findTok ss) [] end;
-
- fun fields isDelim ss =
- let fun h ss res =
- let val (field, afterfield as (_, _, n)) =
- splitl (fn c => not(isDelim c)) ss
- in
- if n = 0 then List.rev (field :: res)
- else h (rest afterfield) (field :: res)
- end
- in h ss [] end;
-
- end
-