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