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