DIRECTORY RunReader USING [Ref], TextLooks USING [Looks, noLooks, Runs]; LooksReader: CEDAR DEFINITIONS = BEGIN Looks: TYPE = TextLooks.Looks; noLooks: Looks = TextLooks.noLooks; Runs: TYPE = TextLooks.Runs; Ref: TYPE = REF Body; Body: TYPE = PRIVATE RECORD [ rem: INTEGER, -- remainder of current run len: NAT, -- length of current run looks: Looks, -- looks for current run runreader: RunReader.Ref -- reader for runs ]; Create: PROC [] RETURNS [Ref]; SetPosition: PROC [reader: Ref, runs: Runs, index: INT _ 0]; SetIndex: PROC [reader: Ref, index: INT _ 0]; BackupIndex: PROC [reader: Ref, amount: INT]; BumpIndex: PROC [reader: Ref, amount: INT]; Position: PROC [reader: Ref] RETURNS [runs: Runs, index: INT]; GetRuns: PROC [reader: Ref] RETURNS [Runs]; GetIndex: PROC [reader: Ref] RETURNS [index: INT]; Get: PROC [reader: Ref] RETURNS [Looks]; InlineGet: PROC [reader: Ref] RETURNS [Looks] ~ INLINE { IF (reader.rem_reader.rem-1) >= 0 THEN RETURN[reader.looks]; reader.rem_reader.rem+1; RETURN[Get[reader]]; }; Backwards: PROC [reader: Ref] RETURNS [Looks]; Peek: PROC [reader: Ref] RETURNS [Looks]; PeekBackwards: PROC [reader: Ref] RETURNS [Looks]; GetLooksReader: PROC RETURNS [Ref]; FreeLooksReader: PROC[Ref]; END.  LooksReader.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. written by Bill Paxton, March 1981 last edit by Bill Paxton, May 28, 1982 10:24 am Doug Wyatt, March 2, 1985 5:01:18 pm PST Michael Plass, March 21, 1985 2:04:00 pm PST LooksReader provides fast inline access to looks designed for speed in reading a sequence of looks either forwards or backwards supports looks as defined by TextLooks.Mesa create a reader by calling Create reader: LooksReader.Ref _ Create[]; position it where you want to read by SetPosition LooksReader.SetPosition[reader, runs, index]; where runs is TextLooks.Runs to read from and index is the initial position for the reader you can reposition a reader at any time read its position in the following ways: [runs, index] _ LooksReader.Position[reader]; runs _ LooksReader.GetRuns[reader]; index _ LooksReader.GetIndex[reader]; to read in ascending order (left to right) initialize position before first looks to be read for example, use 0 to start at beginning then call Get which reads to the right and increments the position looks _ LooksReader.Get[reader]; to read in descending order (right to left) initialize position after first looks to be read for example, use Size[runs] to start at end then call Backwards which reads to the left and decrements the position looks _ LooksReader.Backwards[reader]; can also get looks without changing the reader position to look at the next looks that Get would return, call Peek looks _ LooksReader.Peek[reader]; to look at what Backwards would return, call PeekBackwards looks _ LooksReader.PeekBackwards[reader]; can intermix reading or peeking to left and right don't need to reinitialize the reader to change direction create a reader for chars and looks set position of reader return position of looks reader the following two routines implement a small cache of looks readers so can avoid creating a lot of garbage but don't use unless sure will not free more than once no harm if fail to free (garbage collector will get it) but chaos if free twice Κ΅˜codešœ™Kšœ Οmœ1™Kšœ™K˜—š‘œžœžœ˜+K˜—Kš‘œžœžœ žœ˜2K˜š‘œžœžœ ˜(K˜—š‘ œžœžœ žœ˜8Jšžœ žœžœ˜