(* -*- mode: sml -*- * $Id: wc.smlnj,v 1.2 2001/07/09 00:25:29 doug Exp $ * http://www.bagley.org/~doug/shootout/ * from Stephen Weeks *) structure Test : sig val main : (string * string list) -> OS.Process.status end = struct fun incr r = r := !r + 1 val nl = ref 0 val nw = ref 0 val nc = ref 0 val max = 4096 val buf = Word8Array.array (max, 0w0) val sub = Word8Array.sub fun readblock scanfun = let val nread = Posix.IO.readArr (Posix.FileSys.stdin, {buf = buf, i = 0, sz = NONE}) in if nread = 0 then () else (nc := !nc + nread; scanfun (0, nread)) end val c2b = Byte.charToByte val newline = c2b #"\n" val space = c2b #" " val tab = c2b #"\t" fun scan_out_of_word (i, n) = if i < n then let val c = sub (buf, i) in if c = newline then (incr nl; scan_out_of_word (i + 1, n)) else if c = space orelse c = tab then scan_out_of_word (i + 1, n) else (incr nw; scan_in_word (i + 1, n)) end else readblock scan_out_of_word and scan_in_word (i, n) = if i < n then let val c = sub (buf, i) in if c = newline then (incr nl; scan_out_of_word (i + 1, n)) else if c = space orelse c = tab then scan_out_of_word (i + 1, n) else scan_in_word (i + 1, n) end else readblock scan_in_word fun printl [] = print "\n" | printl(h::t) = ( print h ; printl t ) fun main (name, args) = let val _ = (scan_out_of_word (0, 0); printl [Int.toString (!nl), " ", Int.toString (!nw), " ", Int.toString (!nc)]) in OS.Process.success end end val _ = SMLofNJ.exportFn("wc", Test.main);