LooksReaderImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
written by Bill Paxton, March 1981
last edit by Bill Paxton, December 22, 1981 1:30 pm
Doug Wyatt, March 3, 1985 4:33:03 pm PST
Michael Plass, March 21, 1985 1:58:49 pm PST
LooksReaderImpl:
CEDAR
MONITOR
IMPORTS RunReader
EXPORTS LooksReader
= BEGIN OPEN LooksReader;
Create:
PUBLIC
PROC []
RETURNS [new: Ref] = {
create a reader for chars and looks
new ← NEW[Body];
new^ ← [0,0,noLooks,RunReader.Create[]];
};
SetPosition:
PUBLIC
PROC [reader: Ref, runs: Runs, index:
INT ← 0] = {
reader.rem ← reader.len ← 0;
RunReader.SetPosition[reader.runreader, runs, index]
};
SetIndex:
PUBLIC
PROC [reader: Ref, index:
INT ← 0] = {
reader.rem ← reader.len ← 0;
RunReader.SetIndex[reader.runreader, index]
};
BackupIndex:
PUBLIC
PROC [reader: Ref, amount:
INT] = {
SetIndex[reader, GetIndex[reader]-amount]
};
BumpIndex:
PUBLIC
PROC [reader: Ref, amount:
INT] = {
SetIndex[reader, GetIndex[reader]+amount]
};
Position:
PUBLIC
PROC [reader: Ref]
RETURNS [runs: Runs, index:
INT] = {
RETURN [GetRuns[reader], GetIndex[reader]]
};
GetRuns:
PUBLIC
PROC [reader: Ref]
RETURNS [Runs] = {
RETURN [RunReader.GetRuns[reader.runreader]]
};
GetIndex:
PUBLIC
PROC [reader: Ref]
RETURNS [index:
INT] = {
RETURN [
RunReader.GetIndex[reader.runreader]-reader.rem]
};
Get:
PUBLIC
PROC [reader: Ref]
RETURNS [Looks] = {
get looks, then increment reader location
rem: NAT;
IF (rem←reader.rem) = 0
THEN {
-- go to the next run
len: INT;
[len, reader.looks] ← RunReader.Get[reader.runreader];
IF len >
LAST[
NAT]
THEN {
RunReader.BackupIndex[reader.runreader,len-LAST[NAT]];
len ← LAST[NAT]
};
reader.len ← rem ← len
};
reader.rem ← rem-1;
RETURN[reader.looks]
};
Backwards:
PUBLIC
PROC [reader: Ref]
RETURNS [Looks] = {
decrement reader location, then get looks
rem: NAT;
IF (rem←reader.rem) >= reader.len
THEN {
-- go to the previous run
len: INT;
[len, reader.looks] ← RunReader.Backwards[reader.runreader];
IF len >
LAST[
NAT]
THEN {
RunReader.BumpIndex[reader.runreader,len-LAST[NAT]];
len ← LAST[NAT]
};
reader.len ← len; rem ← 0
};
reader.rem ← rem+1;
RETURN[reader.looks]
};
Peek:
PUBLIC
PROC [reader: Ref]
RETURNS [Looks] = {
get looks without incrementing reader location
looks: Looks;
IF reader.rem = 0 THEN
[,looks] ← RunReader.Peek[reader.runreader]
ELSE looks ← reader.looks;
RETURN [looks]
};
PeekBackwards:
PUBLIC
PROC [reader: Ref]
RETURNS [Looks] = {
like Backwards, but doesn't change position
looks: Looks;
IF reader.rem >= reader.len THEN
[,looks] ← RunReader.PeekBackwards[reader.runreader]
ELSE looks ← reader.looks;
RETURN [looks]
};
lksrdr1, lksrdr2, lksrdr3: Ref; -- shared looks readers
GetLooksReader:
PUBLIC
ENTRY
PROC
RETURNS [reader: Ref] = {
IF lksrdr3 # NIL THEN { reader ← lksrdr3; lksrdr3 ← NIL }
ELSE IF lksrdr2 # NIL THEN { reader ← lksrdr2; lksrdr2 ← NIL }
ELSE IF lksrdr1 # NIL THEN { reader ← lksrdr1; lksrdr1 ← NIL }
ELSE reader ← Create[];
};
FreeLooksReader:
PUBLIC
ENTRY
PROC [reader: Ref] = {
SetPosition[reader, NIL];
IF lksrdr3 = reader OR lksrdr2 = reader OR lksrdr1 = reader THEN ERROR;
IF lksrdr3 =
NIL
THEN lksrdr3 ← reader
ELSE IF lksrdr2 = NIL THEN lksrdr2 ← reader
ELSE IF lksrdr1 = NIL THEN lksrdr1 ← reader;
};
END.