DisplayControllersPrinting.Mesa
Last Edited by: Spreitzer, September 19, 1985 6:50:50 pm PDT
DIRECTORY Ascii, Basics, DisplayControllers, IO, RedBlackTree, RefText, Rope, StructuredStreams, UnparserBuffer;
DisplayControllersPrinting:
CEDAR
PROGRAM
IMPORTS IO, RedBlackTree, SS:StructuredStreams, UB:UnparserBuffer
= {OPEN DisplayControllers;
SymbolTable: TYPE = RedBlackTree.Table;
TProc: TYPE = PROC [dc: DisplayController, clientData: REF ANY];
Print:
PROC [to:
IO.
STREAM, cp: ControlProgram] = {
PrintChar:
PROC [c:
CHAR] = {
SELECT c
FROM
= 0C => to.PutRope["null"];
IN ['\001 .. '\040) => {to.PutChar['^]; to.PutChar[c + 64]};
= '\040 => to.PutRope["sp"];
IN ('\040 .. Ascii.DEL) => to.PutChar[c];
ENDCASE => to.PutF["\\%b", IO.int[c - 0C]];
};
PrintTransition:
PROC [t: Transition] = {
SS.Begin[to];
{ENABLE UNWIND => SS.End[to];
to.PutF[
"%g[%g] %g ",
IO.refAny[NEW[TProc ← t.action.proc]],
IO.refAny[t.action.clientData],
IO.rope[IF t.action.overrideable THEN "*" ELSE "-"]];
SS.Bp[to, TRUE, 1];
PrintVertex[t.newVertex];
};
SS.End[to];
};
printed: SymbolTable ← RedBlackTree.Create[Identity, CompareVertices];
PrintVertex:
PROC [v: Vertex] = {
SS.Begin[to];
{ENABLE UNWIND => SS.End[to];
IF v = cp.start THEN to.PutRope["start"] ELSE to.PutF["%b", IO.int[LOOPHOLE[v]]];
IF printed.Lookup[v] # NIL THEN {SS.End[to]; RETURN};
printed.Insert[v, v];
SS.Bp[to, TRUE, 1];
SELECT v.repStyle
FROM
epsilon => {
to.PutRope["{e "];
PrintTransition[v.t];
to.PutRope["}"];
};
list => {
en: EdgeList;
to.PutRope["{"];
SS.Begin[to];
{ENABLE UNWIND => SS.End[to];
to.PutRope["l "];
SS.Bp[to, TRUE, 0];
PrintTransition[v.t];
FOR el: EdgeList ← v.edgeList, en
WHILE el #
NIL
DO
sgn, delta: INT ← 0;
t: Transition ← el.first.transition;
FOR en ← el.rest, en.rest
WHILE en #
NIL
AND en.first.transition = t
DO
thisDelta: INT ← en.first.char - el.first.char;
thisSgn: INT ← SGN[thisDelta];
IF sgn = 0 THEN sgn ← thisSgn;
IF thisDelta # (delta + sgn) THEN EXIT;
delta ← thisDelta;
ENDLOOP;
SS.Bp[to, TRUE, 0];
to.PutRope["<["];
PrintChar[el.first.char];
IF delta # 0
THEN {
to.PutRope[" .. "];
PrintChar[el.first.char + delta]};
to.PutRope["] "];
PrintTransition[t];
to.PutRope["> "];
ENDLOOP;
};
SS.End[to];
to.PutRope["}"];
};
array => {
first, next, num: INT;
to.PutRope["{"];
SS.Begin[to];
{ENABLE UNWIND => SS.End[to];
to.PutRope["a "];
num ← 1 + (LAST[CHAR] - FIRST[CHAR]);
FOR first ← 0, next
WHILE first < num
DO
t: Transition ← v.edgeArray[0C + first];
FOR next ← first+1, next+1 WHILE next < num AND v.edgeArray[0C + next] = t DO NULL ENDLOOP;
SS.Bp[to, TRUE, 0];
to.PutRope["<["];
PrintChar[0C + first];
IF next > first+1
THEN {
to.PutRope[" .. "];
PrintChar[0C + next-1]};
to.PutRope["] "];
PrintTransition[t];
to.PutRope["> "];
ENDLOOP;
};
SS.End[to];
to.PutRope["}"];
};
ENDCASE => ERROR;
};
SS.End[to];
};
ubh: UB.Handle ← UB.NewHandle[[stream[to]]];
ubh.margin ← 59;
to ← SS.Create[ubh];
PrintVertex[cp.start];
to.PutRope["\n"];
to.Close[];
};
SGN:
PROC [i:
INT]
RETURNS [s: [-1 .. 1]] =
{s ← SELECT i FROM <0 => -1, =0 => 0, >0 => 1, ENDCASE => ERROR};
Identity:
PROC [data:
REF
ANY]
RETURNS [
REF
ANY] =
{RETURN [data]};
CompareVertices:
PROC [k, data:
REF
ANY]
RETURNS [c: Basics.Comparison] = {
i1: INT ← LOOPHOLE[k];
i2: INT ← LOOPHOLE[data];
c ←
SELECT i1
FROM
<i2 => less,
=i2 => equal,
>i2 => greater,
ENDCASE => ERROR;
};
}.