DisplayControllersPrinting.Mesa
Last Edited by: Spreitzer, September 19, 1985 6:50:50 pm PDT
Mike Spreitzer July 30, 1986 11:12:39 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, united, 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, united, 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, united, 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: INTSGN[thisDelta];
IF sgn = 0 THEN sgn ← thisSgn;
IF thisDelta # (delta + sgn) THEN EXIT;
delta ← thisDelta;
ENDLOOP;
SS.Bp[to, united, 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, united, 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];
};
to ← SS.Create[UB.NewInittedHandle[[margin: 59, output: [stream[to]]]]];
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: INTLOOPHOLE[k];
i2: INTLOOPHOLE[data];
c ← SELECT i1 FROM
<i2 => less,
=i2 => equal,
>i2 => greater,
ENDCASE => ERROR;
};
}.