-- CountWords.mesa
-- Edited by Sweet, 24-Aug-81 10:16:40
DIRECTORY
AltoDefs,
CommanderDefs USING [AddCommand, CommandBlockHandle],
IODefs,
SegmentDefs,
Storage,
StreamDefs;
Subst: PROGRAM
IMPORTS CommanderDefs, IODefs, SegmentDefs, StreamDefs, Storage =
BEGIN
BuffSize: CARDINAL = 30;
CountWords: PROCEDURE [fileName: STRING] =
BEGIN OPEN StreamDefs;
in: StreamHandle;
c: CHARACTER;
eof: BOOLEAN ← FALSE;
buffer: POINTER TO PACKED ARRAY [0..0) OF CHARACTER ← NIL;
bptr, btop: CARDINAL ← 0;
words: CARDINAL ← 0;
fileRead: BOOLEAN ← FALSE;
fillbuffer: PROCEDURE =
BEGIN
n: CARDINAL;
n ← ReadBlock[in, buffer, BuffSize*AltoDefs.PageSize];
IF in.endof[in] THEN
BEGIN
fileRead ← TRUE;
IF GetIndex[in].byte MOD 2 # 0 THEN btop ← 2*n-1
ELSE btop ← 2*n;
END
ELSE btop ← 2*n;
bptr ← 0;
END;
get: PROCEDURE RETURNS [c: CHARACTER] =
BEGIN
IF bptr < btop THEN
BEGIN c ← buffer[bptr]; bptr ← bptr+1 END
ELSE IF fileRead THEN c ← 0C
ELSE
BEGIN
fillbuffer[];
c ← buffer[0];
bptr ← 1;
END;
eof ← fileRead AND bptr >= btop;
END;
peek: PROCEDURE RETURNS [c: CHARACTER] =
BEGIN
IF bptr < btop THEN
c ← buffer[bptr]
ELSE IF fileRead THEN c ← 0C
ELSE
BEGIN
fillbuffer[];
c ← buffer[0];
bptr ← 0;
END;
END;
buffer ← Storage.Pages[BuffSize];
in ← NewByteStream[fileName, Read !
SegmentDefs.FileNameError =>
BEGIN
IODefs.WriteLine["--file not found"];
Storage.FreePages[buffer];
GO TO noFile;
END];
WHILE ~eof DO
c ← get[];
SELECT c FROM
IN ['0..'9], IN ['A..'Z], IN ['a..'z] =>
BEGIN
WHILE ~eof DO
SELECT peek[] FROM
IN ['0..'9], IN ['A..'Z], IN ['a..'z] => NULL;
ENDCASE => {words ← words + 1; EXIT};
c ← get[];
ENDLOOP;
END;
ENDCASE;
ENDLOOP;
in.destroy[in];
Storage.FreePages[buffer];
IODefs.WriteDecimal[words]; IODefs.WriteLine[" words"L];
EXITS
noFile => NULL;
END;
Init: PROCEDURE =
BEGIN OPEN CommanderDefs;
command: CommandBlockHandle;
command ← AddCommand["CountWords", LOOPHOLE[CountWords], 1];
command.params[0] ← [type: string, prompt: "Filename"];
END;
Init[];
END.