(* Word8Vector.mlp *) prim_eqtype vector; type elem = Word8.word; local prim_val vector_ : int -> vector = 1 "create_string"; prim_val sub_ : vector -> int -> elem = 2 "get_nth_char"; prim_val update_ : vector -> int -> elem -> unit = 3 "set_nth_char"; prim_val blit_ : vector -> int -> vector -> int -> int -> unit = 5 "blit_string"; in prim_val length : vector -> int = 1 "string_length"; #if defined(msdos) #include "../config.dos/m.h" #elif defined(win32) #include "../config.w32/m.h" #else #include "../config/m.h" #endif #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 fun fromList (vs : elem list) = let val n = List.length vs val a = if n > maxLen then raise Size else vector_ n fun init [] i = () | init (v::vs) i = (update_ a i v; init vs (i+1)) in (init vs 0; a) end; fun tabulate(n, f : int -> elem) = if n < 0 orelse n > maxLen then raise Size else let val a = vector_ n fun init i = if i >= n then () else (update_ a i (f i); init (i+1)) in (init 0; a) end; fun sub(v, i) = if i < 0 orelse i >= length v then raise Subscript else sub_ v i; fun extract (vec, i, slicelen) = let val n = case slicelen of NONE => length vec - i | SOME n => n val newvec = if i<0 orelse n<0 orelse i+n > length vec then raise Subscript else vector_ n in blit_ vec i newvec 0 n; newvec end; fun concat vecs = let fun acc [] len = len | acc (v1::vr) len = acc vr (length v1 + len) val len = acc vecs 0 val newvec = if len > maxLen then raise Size else vector_ len fun copyall to [] = () | copyall to (v1::vr) = let val len1 = length v1 in blit_ v1 0 newvec to len1; copyall (to+len1) vr end in copyall 0 vecs; newvec end; fun foldl f e a = let val stop = length a fun lr j res = if j < stop then lr (j+1) (f(sub_ a j, res)) else res in lr 0 e end fun foldr f e a = let fun rl j res = if j >= 0 then rl (j-1) (f(sub_ a j, res)) else res in rl (length a - 1) e end fun app f a = let val stop = length a fun lr j = if j < stop then (f(sub_ a j); lr (j+1)) else () in lr 0 end fun map (f : elem -> elem) (a : vector) : vector = let val stop = length a val newvec = vector_ stop fun lr j = if j < stop then (update_ newvec j (f(sub_ a j)); lr (j+1)) else () in lr 0; newvec end fun sliceend (a, i, NONE) = if i<0 orelse i>length a then raise Subscript else length a | sliceend (a, i, SOME n) = if i<0 orelse n<0 orelse i+n>length a then raise Subscript else i+n; fun foldli f e (slice as (a, i, _)) = let fun loop stop = let fun lr j res = if j < stop then lr (j+1) (f(j, sub_ a j, res)) else res in lr i e end in loop (sliceend slice) end; fun foldri f e (slice as (a, i, _)) = let fun loop start = let fun rl j res = if j >= i then rl (j-1) (f(j, sub_ a j, res)) else res in rl start e end; in loop (sliceend slice - 1) end fun appi f (slice as (a, i, _)) = let fun loop stop = let fun lr j = if j < stop then (f(j, sub_ a j); lr (j+1)) else () in lr i end in loop (sliceend slice) end; fun mapi (f : int * elem -> elem) (slice as (a : vector, i, _)) : vector = let val stop = sliceend slice val newvec = vector_ (stop - i) fun loop stop = let fun lr j = if j < stop then (update_ newvec (j-i) (f(j, sub_ a j)); lr (j+1)) else () in lr i end in loop stop; newvec end; end