V10/cmd/sml/doc/examples/awk/awk.sml
(* awk.sml *)
signature AWK =
sig
val makeInt : string -> int (* translates a digit string into an int *)
val awk : instream * (string list -> unit) * (unit -> unit) -> unit
end
structure Awk : AWK =
struct
val digit0 = ord "0"
and digit9 = ord "9"
exception MakeInt
fun makeInt (s:string) : int =
(* translates string s into an integer.
Bug: doesn't deal with negative integers *)
let val len = length s
fun translate(i,n) =
if i<len
then let val c = ordof(s,i)
in if digit0 <= c andalso c <= digit9
then translate(i+1,10*n+c-digit0)
else raise MakeInt
end
else n
in translate(0,0)
end
exception END
fun parseStream (instream) =
fn () => if end_of_stream instream
then raise END
else Lex2.words(input_line(instream))
fun awk(instream,step,final) =
let val lines = parseStream instream
fun iter () = (step(lines()); iter())
in iter() handle END => final()
end
end