home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Moscow ML 1.31 / source code / mosml / src / mosmllib / Strbase.mlp < prev    next >
Encoding:
Text File  |  1996-07-03  |  2.7 KB  |  89 lines  |  [TEXT/R*ch]

  1. (* Strbase -- internal utilities for String and Substring *)
  2.  
  3. #include "../config/m.h"
  4. #ifdef SIXTYFOUR
  5. val maxlen = 144115188075855863;      (* = (2^54-1)*8-1, with 64 bit *)
  6. #else
  7. val maxlen = 16777211;          (* = (2^22-1)*4-1, with 32 bit *)
  8. #endif
  9.  
  10. local 
  11.     prim_val sub_      : string -> int -> char         = 2 "get_nth_char";
  12.     prim_val mkstring_ : int -> string                 = 1 "create_string";
  13.     prim_val blit_     : string -> int -> string -> int -> int -> unit 
  14.                                                        = 5 "blit_string";
  15.  
  16.     fun revconcat strs =
  17.     let fun acc [] len       = len
  18.           | acc (v1::vr) len = acc vr (size v1 + len)
  19.         val len = acc strs 0
  20.         val newstr = if len > maxlen then raise Size else mkstring_ len 
  21.         fun copyall to []       = () (* Now: to = 0. *)
  22.           | copyall to (v1::vr) = 
  23.         let val len1 = size v1
  24.             val to   = to - len1
  25.         in blit_ v1 0 newstr to len1; copyall to vr end
  26.     in copyall len strs; newstr end;
  27.  
  28.     fun rest (ss as (s, i, n)) = 
  29.     if n = 0 then ss else (s, i+1, n-1);
  30.  
  31. in
  32.  
  33. fun foldl f e (s,i,n) = 
  34.     let val stop = i+n
  35.         fun h j res = if j>=stop then res 
  36.                       else h (j+1) (f (sub_ s j, res))
  37.     in h i e end;
  38.  
  39. fun translate f ss = 
  40.     revconcat (foldl (fn (s, res) => f s :: res) [] ss);
  41.  
  42. local
  43.     fun scanl chop pred (s, i, n) = 
  44.     let
  45.         val stop = i+n
  46.         fun scan j = if j < stop andalso pred(sub_ s j) then scan (j+1)
  47.              else j
  48.     in
  49.         chop (s, i, n, scan i - i)
  50.     end
  51.     fun scanr chop pred (s, i, n) = 
  52.     let
  53.         val stop = i-1
  54.         fun scan j = if j > stop andalso pred(sub_ s j) then scan(j-1)
  55.              else j
  56.     in
  57.         chop (s, i, n, scan (i+n-1) - i + 1)
  58.     end
  59. in
  60.     fun splitl p = scanl (fn (s, i, n, k) => ((s, i, k), (s, i+k, n-k))) p
  61.     fun splitr p = scanr (fn (s, i, n, k) => ((s, i, k), (s, i+k, n-k))) p
  62.     fun dropl  p = scanl (fn (s, i, n, k) => (s, i+k, n-k))              p
  63.     fun dropr  p = scanr (fn (s, i, n, k) => (s, i, k))                  p
  64.     fun takel  p = scanl (fn (s, i, n, k) => (s, i, k))                  p
  65.     fun taker  p = scanr (fn (s, i, n, k) => (s, i+k, n-k))              p
  66. end (* local *)
  67.  
  68. fun tokens isDelim ss = 
  69.     let fun findTok ss = dropl isDelim ss
  70.         fun h (remains as (_, _, n)) res = 
  71.         if n = 0 then List.rev res
  72.         else
  73.         let val (token, aftertoken) = 
  74.             splitl (fn c => not(isDelim c)) remains 
  75.         in h (findTok aftertoken) (token :: res) end
  76.     in h (findTok ss) [] end;
  77.  
  78. fun fields isDelim ss = 
  79.     let fun h ss res = 
  80.         let val (field, afterfield as (_, _, n)) = 
  81.         splitl (fn c => not(isDelim c)) ss
  82.         in 
  83.         if n = 0 then List.rev (field :: res)
  84.         else h (rest afterfield) (field :: res) 
  85.         end
  86.     in h ss [] end;
  87.  
  88. end
  89.