DIRECTORY
CS: TYPE USING [RopeFromStamp, z],
IO:
TYPE
USING [
atom, card, EndOf, GetChar, GetIndex, int, Put, PutChar, PutF, PutRope,
rope, SetIndex, STREAM],
PrincOpsUtils: TYPE USING [Codebase],
Rope: TYPE USING [Map, ROPE],
SMCommentTable: TYPE USING [Index, Ref, Text],
SMCommentTableOps: TYPE USING [Create, Explode, FindNext, Reset],
SMFI: TYPE USING [BcdFileInfo, SrcFileInfo],
SMLDriver: TYPE USING [Create],
SMOps: TYPE USING [ModelState, MS],
SMP1: TYPE P1 USING [InstallParseTable, Parse],
SMParseData: TYPE USING [],
SMTree:
TYPE Tree
USING [
AttrId, Handle, Id, Link, NodeName, Name, Number, Stamp, Text,
null, nullId, nullName],
SMTreeOps:
TYPE TreeOps
USING [
TM, Scan, Create, GetName, NthSon, PopTree, ScanSons],
SMUtil: TYPE USING [];
SMReaderImpl:
CEDAR
MONITOR
-- this monitor protects the model parsing code
IMPORTS
CS, IO, PrincOpsUtils, Rope, SMCommentTableOps, SMLDriver, SMP1, SMTreeOps,
SMParseData
EXPORTS SMUtil, SMOps ~ {
OPEN P1~~SMP1, Tree~~SMTree, TreeOps~~SMTreeOps;
tabSize: CARDINAL ~ 4;
PrintTree:
PUBLIC
PROC[m: SMOps.
MS, t: Tree.Link] ~ {
PrintSubTree[m.out, t, 0];
(m.out).PutChar['\n];
IF m.comments #
NIL
THEN {
index: SMCommentTable.Index ← 0;
comments: BOOL ← FALSE;
DO
ref: SMCommentTable.Ref ~ (m.comments).FindNext[index];
IF ref = NIL THEN EXIT;
IF ~comments THEN (m.out).PutRope["\nComments:"]; comments ← TRUE;
(m.out).PutChar['\n]; (m.out).PutChar[' ]; (m.out).Put[IO.card[index]];
index ← SMCommentTableOps.Explode[ref].start + 1;
ENDLOOP;
IF comments THEN (m.out).PutChar['\n]};
};
PrintSubTree:
PUBLIC
PROC[out:
IO.
STREAM, t: Tree.Link, nBlanks:
NAT] ~ {
Printer: TreeOps.Scan ~ {
Indent[nBlanks, out];
IF t = Tree.null THEN out.PutRope["<empty>"]
ELSE
WITH t
SELECT
FROM
name: Tree.Name => PrintName[name, out];
id: Tree.Id => PrintId[id, out];
node: Tree.Handle => {
WriteNodeName[node.name, out];
IF node.info # 0
THEN {
out.PutRope[" info="]; out.Put[IO.card[node.info]]};
IF node.attrs #
ALL[
FALSE]
THEN {
IF node.info # 0 THEN out.PutChar[' ];
out.PutChar['(];
FOR i: Tree.AttrId
IN Tree.AttrId
DO
IF node.attrs[i] THEN out.PutChar[VAL[i+'0.ORD]] ENDLOOP;
out.PutChar[')]};
nBlanks ← nBlanks + 2;
TreeOps.ScanSons[t, Printer];
nBlanks ← nBlanks - 2};
fiSrc: SMFI.SrcFileInfo => out.PutF["(fiSrc: %g)", IO.rope[fiSrc.localName]];
fiBcd: SMFI.BcdFileInfo => out.PutF["(fiBcd: %g)", IO.rope[fiBcd.localName]];
ENDCASE => PrintLiteral[t, out];
WriteNodeName:
PROC[n: Tree.NodeName, out:
IO.
STREAM] ~ {
out.PutRope[
SELECT n
FROM
$none => "node",
$lambda => "lambda",
$let => "let",
$arrow => "arrow",
$arrow2 => "arrow2",
$apply => "apply",
$applyDefault => "applyDefault",
$subscript => "subscript",
$union => "union",
$then => "then",
$exclusion => "exclusion",
$restriction => "restriction",
$splitUpper => "splitUpper",
$splitLower => "splitLower",
$group => "group",
$decl => "decl",
$declElem => "declElem",
$bind => "bind",
$bindRec => "bindRec",
$bindElem => "bindElem",
$type => "type",
$env => "env",
$nil => "nil",
$control => "control",
$unitId => "unitId",
$uiList => "uiList",
$unQuote => "unQuote",
$typeTYPE => "typeTYPE",
$typeDECL => "typeDECL",
$typeBINDING => "typeBINDING",
$typePATTERN => "typePATTERN",
$typeSTRING => "typeSTRING",
$nBind => "nBind",
$nBindRec => "nBindRec",
$stamp => "stamp",
$cross => "cross",
$cross2 => "cross2",
$locator => "locator",
ENDCASE => ERROR]
};
PrintLiteral:
PROC[t: Tree.Link, out:
IO.
STREAM] ~ {
WITH t
SELECT
FROM
text: Tree.Text => WriteQuotedText[text, out];
num: Tree.Number => out.Put[IO.int[num^]];
stamp: Tree.Stamp => out.PutRope[CS.RopeFromStamp[stamp^]];
n: REF LONG CARDINAL => out.Put[IO.card[n^]];
ENDCASE => out.PutChar['?];
};
PrintName:
PROC[name: Tree.Name, out:
IO.
STREAM] ~ {
out.Put[IF name = Tree.nullName THEN IO.rope["(anon)"] ELSE IO.atom[name]]};
PrintId:
PROC[id: Tree.Id, out:
IO.
STREAM] ~ {
IF id = Tree.nullId THEN out.PutRope["<null>"]
ELSE {
d: Tree.Handle ~ (IF id.db.name = $decl THEN id.db ELSE NARROW[id.db[1]]);
out.Put[IO.atom[TreeOps.GetName[TreeOps.NthSon[d[id.p], 1]]]];
out.PutChar['[]; out.Put[IO.card[id.p]]; out.PutChar[']]};
};