-- 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.