-- File: ScriptShowImpl.mesa - last edit by
-- Karlton: 2-Sep-82 14:21:31
DIRECTORY
Ascii USING [CR, NUL, SP],
Environment USING [Byte],
Real USING [AppendReal],
ScriptHash USING [AppendId, Handle, Hash],
ScriptNode USING [Operator, QualifiedID, String],
ScriptParse USING [Error],
ScriptTree USING [Handle, RootNode, TreeHandle, Walk],
Stream USING [Handle, PutBlock, PutChar],
String USING [AppendLongDecimal];
ScriptShowImpl: PROGRAM
IMPORTS Real, ScriptHash, ScriptParse, ScriptTree, Stream, String
EXPORTS ScriptParse = {
indentPerDepth: CARDINAL = 4;
Nibble: TYPE = [0..15];
HexChar: TYPE = MACHINE DEPENDENT RECORD [
pad(0:0..7): Environment.Byte,
left(0:8..11): Nibble,
right(0:12..15): Nibble];
Handle: TYPE = ScriptTree.Handle;
Format: TYPE = {tree, script};
Frame: TYPE = POINTER TO FrameObject;
FrameObject: TYPE = RECORD [
out: Stream.Handle,
univ, id: ScriptHash.Handle,
lastChar: CHARACTER,
format: Format ← tree];
ShowTree: PUBLIC PROCEDURE [
out: Stream.Handle,
univ, id: ScriptHash.Handle,
tree: ScriptTree.TreeHandle] = {
f: FrameObject ← [out, univ, id, Ascii.NUL, tree];
ShowNode[@f, ScriptTree.RootNode[tree], 0]};
Externalize: PUBLIC PROCEDURE [
out: Stream.Handle,
univ, id: ScriptHash.Handle,
tree: ScriptTree.TreeHandle] = {
f: FrameObject ← [out, univ, id, Ascii.NUL, script];
ShowString[@f, "Interscript/Reference/83 "L];
ShowChar[@f, Ascii.CR];
ShowNode[@f, ScriptTree.RootNode[tree], 0];
ShowString[@f, "ENDSCRIPT"L];
ShowChar[@f, Ascii.CR]};
ShowSons: PROCEDURE [f: Frame, r: Handle, d: CARDINAL] = {
son: Handle;
son ← ScriptTree.Walk[r, down];
WHILE son # NIL DO
ShowNode[f, son, d + 1];
son ← ScriptTree.Walk[son, right]
ENDLOOP};
NoSons: PROCEDURE [f: Frame, r: Handle] = {
IF ScriptTree.Walk[r, down] # NIL THEN
ERROR ScriptParse.Error[invalidTree, 0];
ShowBreak[f]};
GetSons: PROCEDURE [n: Handle, min, max: [0..3]]
RETURNS [Handle, Handle, Handle] = {
sons: ARRAY [0..4) OF Handle ← ALL[NIL];
sons[0] ← ScriptTree.Walk[n, down];
FOR i: CARDINAL IN [1..4) DO
IF sons[i-1] = NIL THEN EXIT;
sons[i] ← ScriptTree.Walk[sons[i-1], right];
ENDLOOP;
IF sons[max] # NIL THEN ERROR ScriptParse.Error[invalidTree, 0];
IF sons[min - 1] = NIL THEN ERROR ScriptParse.Error[invalidTree, 0];
RETURN[sons[0], sons[1], sons[2]]};
ShowNode: PROCEDURE [f: Frame, n: Handle, d: CARDINAL] = {
IF f.format = tree THEN
THROUGH [0..d*indentPerDepth) DO ShowChar[f, Ascii.SP] ENDLOOP;
ShowNodeContent[f, n, d]};
ShowNodeContent: PROCEDURE [f: Frame, n: Handle, d: CARDINAL] = {
first, second, third: Handle;
WITH node: n.node SELECT FROM
atom => {ShowId[f, node.atom, f.univ]; NoSons[f, n]};
application => {
ShowIds[f, node.ids, f.id];
SELECT f.format FROM
script => {
ShowChar[f, '[]; ShowSons[f, n, d]; ShowChar[f, ']]; ShowBreak[f]};
tree => {ShowString[f, "[]"]; ShowBreak[f]; ShowSons[f, n, d]};
ENDCASE};
boolean => {ShowBoolean[f, node.boolean]; NoSons[f, n]};
choice => {
[first, second, third] ← GetSons[n, 3, 3];
SELECT f.format FROM
script => {
ShowChar[f, '(];
ShowNode[f, first, d + 1];
ShowChar[f, '|];
ShowNode[f, second, d + 1];
ShowChar[f, '|];
ShowNode[f, third, d + 1];
ShowChar[f, ')];
ShowBreak[f]};
tree => {
ShowString[f, "Selection"L];
ShowBreak[f];
ShowNode[f, first, d + 1];
ShowBreak[f];
ShowNode[f, second, d + 1];
ShowBreak[f];
ShowNode[f, third, d + 1];
ShowBreak[f]};
ENDCASE};
dollar => {ShowIdLabel[f, node.label, f.univ, "$"L]; NoSons[f, n]};
environment => {
[first, second, ] ← GetSons[n, 2, 2];
SELECT f.format FROM
script => {
ShowChar[f, '[];
ShowNode[f, first, d];
ShowChar[f, '|];
ShowNode[f, second, d];
ShowChar[f, ']];
ShowBreak[f]};
tree => {
ShowString[f, "Environment"L];
ShowBreak[f];
ShowNode[f, first, d];
ShowBreak[f];
ShowNode[f, second, d];
ShowBreak[f]};
ENDCASE};
expression => {
[first, second, ] ← GetSons[n, 1, 2];
SELECT f.format FROM
script => {
IF second # NIL THEN ShowNode[f, first, d + 1];
ShowOperator[f, node.expression];
ShowNode[f, IF second = NIL THEN first ELSE second, d + 1];
ShowBreak[f]};
tree => {
ShowOperator[f, node.expression];
ShowBreak[f];
ShowNode[f, first, d + 1];
ShowBreak[f];
IF second # NIL THEN {ShowNode[f, second, d + 1]; ShowBreak[f]}};
ENDCASE};
globalBind => {
[first, , ] ← GetSons[n, 1, 1];
ShowIds[f, node.lhs, IF node.univ THEN f.univ ELSE f.id];
ShowString[f, " := "L];
ShowNodeContent[f, first, d]};
integer => {ShowInteger[f, node.integer]; NoSons[f, n]};
links => {
ShowString[f, "LINKS "L]; ShowId[f, node.label, f.id]; NoSons[f, n]};
localBind => {
[first, , ] ← GetSons[n, 1, 1];
ShowIds[f, node.lhs, f.id];
ShowString[f, " ← "L];
ShowNodeContent[f, first, d]};
node => {
SELECT f.format FROM
script => {
ShowChar[f, '{];
ShowSons[f, n, d];
ShowChar[f, '}];
ShowChar[f, Ascii.CR]};
tree => {ShowString[f, "Node"L]; ShowBreak[f]; ShowSons[f, n, d]};
ENDCASE};
percent => {ShowIdsLabel[f, node.ids, f.id, "%"L]; NoSons[f, n]};
placeHolder => {
IF f.format = tree THEN {ShowString[f, "Place Holder"L]; ShowBreak[f]};
ShowSons[f, n, d]};
qualifiedID => {ShowIds[f, node.ids, f.id]; NoSons[f, n]};
quotedExpression => {
SELECT f.format FROM
script => {
ShowChar[f, ''];
ShowSons[f, n, d];
ShowChar[f, ''];
ShowChar[f, Ascii.CR]};
tree => {
ShowString[f, "Quoted Expression"L]; ShowBreak[f]; ShowSons[f, n, d]};
ENDCASE};
real => {ShowReal[f, node.real]; NoSons[f, n]};
source => {
ShowIds[f, node.ids, f.id]; ShowChar[f, '↑]; ShowBreak[f]; NoSons[f, n]};
string => {ShowText[f, node.string]; NoSons[f, n]};
target => {
ShowIds[f, node.ids, f.id]; ShowChar[f, ':]; ShowBreak[f]; NoSons[f, n]};
univApplication => {
ShowId[f, node.atom, f.univ];
SELECT f.format FROM
script => {
ShowChar[f, '[]; ShowSons[f, n, d]; ShowChar[f, ']]; ShowBreak[f]};
tree => {ShowString[f, "[]"]; ShowBreak[f]; ShowSons[f, n, d]};
ENDCASE};
vector => {
SELECT f.format FROM
script => {
ShowChar[f, '(]; ShowSons[f, n, d]; ShowChar[f, ')]; ShowBreak[f]};
tree => {ShowString[f, "Vector"L]; ShowBreak[f]; ShowSons[f, n, d]};
ENDCASE};
ENDCASE => ERROR};
ShowString: PROC [f: Frame, v: LONG STRING] = {
f.out.PutBlock[[LOOPHOLE[@v.text], 0, v.length]];
f.lastChar ← Ascii.NUL};
ShowChar: PROC [f: Frame, v: CHARACTER] = INLINE {
f.out.PutChar[v]; f.lastChar ← v};
ShowBreak: PROC [f: Frame] = {
char: CHARACTER = IF f.format = tree THEN Ascii.CR ELSE Ascii.SP;
IF f.lastChar # char THEN ShowChar[f, char]};
ShowHex: PROC [f: Frame, v: HexChar] = INLINE {
ShowChar[f, 'A + v.left]; ShowChar[f, 'A + v.right]};
ShowText: PROC [f: Frame, string: ScriptNode.String] = {
ShowChar[f, '<];
SELECT f.format FROM
script => {
IF string.allSimple THEN ShowString[f, string.string]
ELSE {
OpenEscape: PROC = INLINE {
IF ~inEscape THEN {ShowChar[f, '=]; inEscape ← TRUE}};
CloseEscape: PROC = INLINE {
IF inEscape THEN {ShowChar[f, '=]; inEscape ← FALSE}};
set: CHARACTER ← 0C;
char: CHARACTER;
pos: CARDINAL;
inEscape: BOOLEAN ← FALSE;
WHILE pos < string.string.length DO
SELECT (char ← string.string[pos]) FROM
377C => {pos ← pos + 1; set ← string.string[pos]};
ENDCASE => {
IF set # 0C THEN {
OpenEscape[];
ShowInteger[f, (set - 0C)*256 + (char - 0C)];
ShowChar[f, Ascii.SP]}
ELSE SELECT char FROM
'=, '> => {OpenEscape[]; ShowHex[f, LOOPHOLE[char]]};
IN [40C..176C] => {CloseEscape[]; ShowChar[f, char]};
ENDCASE => {OpenEscape[]; ShowHex[f, LOOPHOLE[char]]}};
pos ← pos + 1;
ENDLOOP;
CloseEscape[]}};
tree => {
IF string.allSet0 THEN ShowString[f, string.string]
ELSE {
set: CHARACTER ← 0C;
c: CHARACTER;
pos: CARDINAL ← 0;
WHILE pos < string.string.length DO
SELECT (c ← string.string[pos]) FROM
377C => {pos ← pos + 1; set ← string.string[pos]};
ENDCASE => ShowChar[f, IF set = 0C THEN c ELSE 377C];
pos ← pos + 1;
ENDLOOP}};
ENDCASE;
ShowChar[f, '>]};
ShowOperator: PROC [f: Frame, v: ScriptNode.Operator] = {
ShowString[f, SELECT v FROM
plus => "+ "L, minus => "- "L, divide => "/ "L, multiply => "* "L,
ENDCASE => ERROR ScriptParse.Error[invalidTree, 0]]};
ShowBoolean: PROC [f: Frame, v: BOOLEAN] = {
SELECT v FROM
TRUE => ShowString[f, IF f.format = script THEN "T"L ELSE "TRUE"L];
FALSE => ShowString[f, IF f.format = script THEN "F"L ELSE "FALSE"L];
ENDCASE};
ShowInteger: PROC [f: Frame, v: LONG INTEGER] = {
string: STRING = [20];
String.AppendLongDecimal[string, v];
ShowString[f, string]};
ShowReal: PROC [f: Frame, v: REAL] = {
string: STRING = [20];
Real.AppendReal[s: string, r: v, forceE: TRUE];
ShowString[f, string]};
ShowId: PROC [f: Frame, hash: ScriptHash.Hash, table: ScriptHash.Handle] = {
val: LONG STRING = [40];
ScriptHash.AppendId[table, val, hash];
ShowString[f, val]};
ShowIdLabel: PROC [
f: Frame, hash: ScriptHash.Hash, table: ScriptHash.Handle, label: STRING] = {
IF f.format = tree THEN {ShowString[f, label]; ShowChar[f, Ascii.SP]};
ShowId[f, hash, table];
IF f.format = script THEN ShowString[f, label]};
ShowIds: PROC [
f: Frame, ids: ScriptNode.QualifiedID, table: ScriptHash.Handle] = {
FOR i: CARDINAL IN [0..ids.length) DO
IF i > 0 THEN ShowChar[f, '.]; ShowId[f, ids[i], table] ENDLOOP};
ShowIdsLabel: PROC [
f: Frame, ids: ScriptNode.QualifiedID, table: ScriptHash.Handle,
label: STRING] = {
IF f.format = tree THEN {ShowString[f, label]; ShowChar[f, Ascii.SP]};
ShowIds[f, ids, table];
IF f.format = script THEN ShowString[f, label]};
}. -- of ScriptShowImpl