-- PPHelperImpl.mesa
-- Russ Atkinson, June 9, 1982 3:49 pm
DIRECTORY
Ascii USING [ControlZ, CR, FF, TAB],
PPHelper,
PPLeaves USING [HTIndex, LTIndex],
PPP1 USING [IdOfLock],
PPTree USING [Handle, Link, NodeName],
PPTreeOps USING [NSons, NthSon],
PPUtil USING [ShowChar],
Rope USING [Equal, ROPE, Text];
PPHelperImpl: CEDAR PROGRAM
IMPORTS PPP1, PPTreeOps, PPUtil, Rope
EXPORTS PPHelper
SHARES Rope
= BEGIN OPEN Ascii, PPLeaves, PPTreeOps, Tree: PPTree, Rope;
LockId: HTIndex ← PPP1.IdOfLock[];
-- this handle is used to hold on to the log stream
indent, position, line, page: PUBLIC INT ← 0;
sizing: PUBLIC BOOL ← FALSE;
lastChar: PUBLIC CHAR ← 0C;
lateTrigger: PUBLIC INT ← 80;
earlyTrigger: PUBLIC INT ← 64;
Excess: PUBLIC ERROR = CODE;
Init: PUBLIC PROC = {
indent ← position ← line ← page ← 0;
sizing ← FALSE;
};
GetInfo: PUBLIC PROC [t: Tree.Link] RETURNS [info: INT] = {
DO WITH t SELECT FROM
hti: HTIndex =>
info ← IF hti = LockId THEN 0 ELSE 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: PUBLIC PROC [t: Tree.Link] RETURNS [a1,a2,a3: BOOL] = {
WITH t SELECT FROM
x: Tree.Handle => RETURN [x.attr[1], x.attr[2], x.attr[3]]
ENDCASE => a1 ← a2 ← a3 ← FALSE};
WriteChar: PUBLIC PROC [c: CHAR] = {
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};
TRUSTED {PPUtil.ShowChar[c]}};
WriteId: PUBLIC PROC [r: ROPE] = {
s: Text ← NARROW[r];
c: CHAR ← lastChar ← 'A;
len: NAT ← IF s = NIL THEN 0 ELSE s.length;
IF len = 0 THEN RETURN;
c ← s[0];
IF c IN ['B..'C] THEN
{-- could be a trivial translation
SELECT len FROM
7 => IF Rope.Equal[s, "BOOLEAN"] THEN {s ← "BOOL"; len ← 4};
9 => IF Rope.Equal[s, "CHARACTER"] THEN {s ← "CHAR"; len ← 4};
ENDCASE};
position ← position + len;
IF sizing THEN
{IF position > lateTrigger THEN ERROR Excess;
RETURN};
FOR i: NAT IN [0..len) DO
TRUSTED {PPUtil.ShowChar[s[i]]};
ENDLOOP};
WriteText: PUBLIC PROC [r: ROPE] = {
-- 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..s.length) DO
c: CHAR ← s[i];
IF c = Ascii.ControlZ THEN
{WriteChar[Ascii.CR]; RETURN};
WriteChar[c]
ENDLOOP}};
WriteQuotedText: PUBLIC PROC [r: ROPE] = {
-- we assume that the rope has been flattened
-- an error occurs if it is not
-- we also assume that the scanner has escape 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..s.length) DO
WriteChar[s[i]];
ENDLOOP};
WriteChar['"]};
Indent: PUBLIC PROC = {
count: INT ← indent - position;
WHILE (count←count-1) >= 0 DO
WriteChar[' ]
ENDLOOP};
Break: PUBLIC PROC = {
IF position > indent THEN WriteChar[CR];
Indent[]};
END.