(* The Great Win32 Language Shootout http://dada.perl.it/shootout/
contributed by Isaac Gouy (Modula2 novice)
To build: xc =m wc
To run: wc < input.txt
*)
MODULE Wc;
<* m2extensions + *>
FROM SRawIO IMPORT Read;
FROM SIOResult IMPORT ReadResult, wrongFormat;
FROM SYSTEM IMPORT ADR, FILL;
FROM STextIO IMPORT WriteLn;
FROM SWholeIO IMPORT WriteCard;
CONST
buffer_size = 4096;
LF = CHR(10);
CR = CHR(13);
TAB = CHR(9);
Space = CHR(32);
Null = CHR(0);
TYPE Buffer_Type = ARRAY [1..buffer_size] OF CHAR;
PROCEDURE Fill(VAR buf: Buffer_Type);
VAR i: INTEGER;
BEGIN
(* Clear the buffer *)
FILL( ADR(buf), Null, buffer_size );
(* Raw read into the buffer *)
Read(buf);
IF ReadResult() = wrongFormat THEN
(* ignore LF if it's followed by end of input *)
i := LENGTH(buf);
IF (i > 0) AND (buf[i] = LF) THEN
buf[i] := Null;
END;
END;
END Fill;
VAR
nc, nl, nw: CARDINAL;
i, read_length: CARDINAL;
buf: Buffer_Type;
c: CHAR;
insideWord: BOOLEAN;
BEGIN
insideWord := FALSE;
REPEAT
Fill(buf);
read_length := LENGTH(buf);
INC(nc, read_length);
FOR i := 1 TO read_length DO
c := buf[i];
IF c = LF THEN INC(nl); END;
IF (c = Space) OR (c = LF) OR (c = TAB) OR (c = CR) THEN
insideWord := FALSE;
ELSIF NOT insideWord THEN
insideWord := TRUE;
INC(nw);
END;
END;
UNTIL read_length<1;
WriteCard(nl,1); WriteCard(nw,0); WriteCard(nc,0); WriteLn;
END Wc.