-- SakuraHelperImpl.mesa
-- last edit by Russ Atkinson, 5-Jun-81 15:15:05
-- last edit by Suzuki, 15-Nov-81 19:05:15
DIRECTORY
IOStream: TYPE USING [CR, FF, TAB, Handle, PutChar],
SakuraHelper: TYPE,
PPLeaves: TYPE USING [HTIndex, LTIndex],
SakuraTree: TYPE USING [Handle, Link, NodeName],
SakuraTreeOps: TYPE USING [NSons, NthSon],
SakuraOps: TYPE USING [GetLog],
Rope: TYPE USING [Size, Ref, Text],
RopeInline: TYPE USING [LowPart];
SakuraHelperImpl: PROGRAM
IMPORTS IOStream, SakuraOps, SakuraTreeOps, Rope, RopeInline
EXPORTS SakuraHelper
= PUBLIC BEGIN OPEN PPLeaves, SakuraTreeOps, Tree: SakuraTree, IOStream, Rope;
Index: TYPE = LONG INTEGER;
Char: TYPE = CHARACTER;
-- this handle is used to hold on to the log stream
handle: IOStream.Handle ← NIL;
indent, position, line, page: Index ← 0;
sizing: BOOLEAN ← FALSE;
lastChar: Char ← 0C;
lateTrigger: Index ← 90;
earlyTrigger: Index ← 70;
Excess: ERROR = CODE;
Init: PROC = {
indent ← position ← line ← page ← 0;
sizing ← FALSE;
handle ← SakuraOps.GetLog[];
};
GetInfo: PROC [t: Tree.Link] RETURNS [info: Index] = {
DO WITH t SELECT FROM
hti: HTIndex => info ← hti.index;
lti: LTIndex => info ← lti.index;
x: Tree.Handle =>
{info ← x.info;
IF info = 0 THEN
FOR i: NAT IN [1..NSons[t]] WHILE info = 0 DO
info ← GetInfo[NthSon[t, i]]
ENDLOOP}
ENDCASE => info ← 0;
EXIT
ENDLOOP};
GetAttrs: PROC [t: Tree.Link] RETURNS [a1: BOOLEAN, a2: BOOLEAN, a3: BOOLEAN] = {
WITH t SELECT FROM
x: Tree.Handle => RETURN [x.attr[1], x.attr[2], x.attr[3]]
ENDCASE => a1 ← a2 ← a3 ← FALSE};
WriteChar: PROC [c: CHARACTER] = {
IF (lastChar ← c) < 40C
THEN
{SELECT c FROM
TAB => {position ← position + 8;
position ← position - position MOD 8;
lastChar ← ' };
CR => {position ← 0; line ← line + 1};
FF => {position ← 0; line ← 0; page ← page + 1};
ENDCASE}
ELSE position ← position + 1;
IF sizing THEN
{IF lastChar # ' AND position >= lateTrigger THEN ERROR Excess;
RETURN};
PutChar[handle, c]};
WriteId: PROC [r: Ref] = {
s: Text = NARROW[r];
len: NAT ← IF s = NIL THEN 0 ELSE RopeInline.LowPart[Size[r]];
position ← position + len;
lastChar ← 'A;
IF sizing THEN
{IF position > lateTrigger THEN ERROR Excess;
RETURN};
FOR i: NAT IN [0..len) DO
PutChar[handle, s[i]]
ENDLOOP};
WriteText: PROC [r: Ref] = {
-- we assume that the rope has been flattened
-- an error occurs if it is not
IF r # NIL THEN {
s: Text = NARROW[r];
FOR i: NAT IN [0..RopeInline.LowPart[Size[s]]) DO
WriteChar[s[i]]
ENDLOOP}};
WriteQuotedText: PROC [r: Ref] = {
-- we assume that the rope has been flattened
-- an error occurs if it is not
-- we also assume that the scanner has left extra quote marks in
-- but that the leading and trailing quotes are gone
WriteChar['"];
IF r # NIL THEN {
s: Text = NARROW[r];
FOR i: NAT IN [0..RopeInline.LowPart[Size[s]]) DO
WriteChar[s[i]];
ENDLOOP};
WriteChar['"]};
Indent: PROC = {
count: Index ← indent - position;
WHILE (count←count-1) >= 0 DO
WriteChar[' ]
ENDLOOP};
Break: PROC = {
IF position > indent THEN WriteChar[CR];
Indent[]};
END.