SiroccoExternalImpl.Mesa
Copyright Ó 1986, 1987 by Xerox Corporation. All rights reserved.
Bill Jackson (bj) August 27, 1987 0:20:01 am PDT
DIRECTORY
IO USING [ bool, card, rope, PutF, refAny, STREAM ],
Rope USING [ ROPE, Equal ],
SiroccoCGDef USING [ Generic, ItemKind, ValueKind ],
SymTab USING [ EachPairAction, Pairs, Ref ],
ThreeC4Support USING [ GetReportStream ],
SiroccoBaseDef USING [ ],
SiroccoPrivate,
SiroccoPrivateTypes;
SiroccoExternalImpl: CEDAR PROGRAM
IMPORTS IO, Rope, SymTab, ThreeC4Support
EXPORTS SiroccoPrivate ~ {
OPEN SiroccoCGDef, SiroccoPrivate, SiroccoPrivateTypes;
ROPE: TYPE ~ Rope.ROPE;
STREAM: TYPE ~ IO.STREAM;
Dump/Snarf Object files
DumpTypeGraph: PUBLIC PROC [ graph: TypeGraph ] ~ {
s: STREAM ~ ThreeC4Support.GetReportStream[];
DumpItemTable: SymTab.EachPairAction ~ {
item: ITEM ~ NARROW[val]; -- guaranteed to be indirect!
name: ROPE ~ item.name;
position: CARD ~ item.position;
kind: SiroccoCGDef.ItemKind ~ item.kind;
node: TypeGraphNode ~ item.type;
value: AbstractValue ~ item.value;
SELECT kind FROM
type => {
IO.PutF[s, "\t{ type %g, %g, %g, %g }\n",
IO.rope[name],
IO.card[position],
IO.card[LOOPHOLE[node]],
IO.card[0]
];
};
const => {
IO.PutF[s, "\t{ const %g, %g, %g, %g }\n",
IO.rope[name],
IO.card[position],
IO.card[LOOPHOLE[node]],
IO.card[LOOPHOLE[value]]
];
};
ENDCASE => { NULL };
};
DumpItemTG: SymTab.EachPairAction ~ {
item: ITEM ~ NARROW[val]; -- guaranteed to be indirect!
name: ROPE ~ item.name;
position: CARD ~ item.position;
kind: SiroccoCGDef.ItemKind ~ item.kind;
node: TypeGraphNode ~ item.type;
value: AbstractValue ~ item.value;
SELECT kind FROM
type => {
DumpTGN[s, node];
};
const => {
DumpTGN[s, node];
DumpAVN[s, value];
};
ENDCASE => { ERROR };
};
context: CONTEXT ~ graph.context;
scope: SCOPE ~ context.scope;
id: ROPE ~ scope.id;
pgm: CARD ~ scope.pgm;
version: CARD ~ scope.version;
items: SymTab.Ref ~ scope.items;
IO.PutF[s, "\n"];
IO.PutF[s, "{ %g, %g, %g }\n",
IO.rope[id],
IO.card[pgm],
IO.card[version]
];
IO.PutF[s, "\n"];
IO.PutF[s, "{ Items\n"];
[] ← SymTab.Pairs[items, DumpItemTable];
IO.PutF[s, "\t}\n"];
IO.PutF[s, "\n"];
IO.PutF[s, "{ TypeGraph\n"];
[] ← SymTab.Pairs[items, DumpItemTG];
IO.PutF[s, "\t}\n"];
IO.PutF[s, "\n"];
};
Type Graph/Node Creators
internal for now!
MarkTypeGraphNode: PROC [node: TypeGraphNode] ~ {
};
DumpTGN: PUBLIC TGNDumpProc ~ {
IF ( node = NIL ) THEN RETURN;
MarkTypeGraphNode[node]; -- unneccessary?
WITH node SELECT FROM
tgn: REF NodeRep => { DumpIndirectTGN[s, tgn, n]; };
tgn: HackTGN => { DumpHackTGN[s, tgn, n]; };
tgn: ArrayTGN => { DumpArrayTGN[s, tgn, n]; };
tgn: BaseTypeTGN => { DumpBaseTypeTGN [s, tgn, n]; };
tgn: ChoiceTGN => { DumpChoiceTGN [s, tgn, n]; };
tgn: DerefTGN => { DumpDerefTGN [s, tgn, n]; };
tgn: EnumTGN => { DumpEnumTGN [s, tgn, n]; };
tgn: ErrorTGN => { DumpErrorTGN [s, tgn, n]; };
tgn: LinkTGN => { DumpLinkTGN [s, tgn, n]; };
tgn: ProcTGN => { DumpProcTGN [s, tgn, n]; };
tgn: RecordTGN => { DumpRecordTGN [s, tgn, n]; };
tgn: SequenceTGN => { DumpSequenceTGN [s, tgn, n]; };
tgn: FieldListTGN => { DumpFieldListTGN [s, tgn, n]; };
tgn: UnionTGN => { DumpUnionTGN [s, tgn, n]; };
tgn: FieldTGN => { DumpFieldTGN [s, tgn, n]; };
ENDCASE => { ERROR };
};
DumpIndirectTGN: PUBLIC TGNDumpProc ~ {
tgn: REF NodeRep ~ NARROW[node];
DumpTGN[s, tgn.specifics, n];
IO.PutF[s, "\t{ %g: $indirecttgn %g }\n", IO.card[LOOPHOLE[node]], IO.card[LOOPHOLE[tgn.specifics]] ];
};
DumpHackTGN: PUBLIC TGNDumpProc ~ {
tgn: HackTGN ~ NARROW[node];
DumpTGN[s, tgn.value, n];
DumpTGN[s, tgn.next, n];
IO.PutF[s, "\t{ %g: $hacktgn %g %g }\n",
IO.card[LOOPHOLE[node]],
IO.card[LOOPHOLE[tgn.value]],
IO.card[LOOPHOLE[tgn.next]]
];
};
Primitive Creators
DumpEmptyTGN: PUBLIC TGNDumpProc ~ {
IF TRUE THEN IO.PutF[s, "$empty %g", IO.refAny[node] ];
};
DumpPrimitiveTGN: PUBLIC TGNDumpProc ~ {
IF TRUE THEN IO.PutF[s, "$primitive %g", IO.refAny[node] ];
};
Primary Creators
DumpArrayTGN: PUBLIC TGNDumpProc ~ {
atgn: ArrayTGN ~ NARROW[node];
DumpAVN[s, atgn.length];
DumpTGN[s, atgn.itemType, n];
IO.PutF[s, "\t{ %g: $array %g %g }\n",
IO.card[LOOPHOLE[node]],
IO.card[LOOPHOLE[atgn.length]],
IO.card[LOOPHOLE[atgn.itemType]]
];
};
DumpBaseTypeTGN: PUBLIC TGNDumpProc ~ {
btgn: BaseTypeTGN ~ NARROW[node];
IO.PutF[s, "\t{ %g: $basetype %g %g }\n",
IO.card[LOOPHOLE[node]],
IO.card[btgn.type.ORD],
IO.refAny[node]
]; -- fix me!
};
DumpChoiceTGN: PUBLIC TGNDumpProc ~ {
ctgn: ChoiceTGN ~ NARROW[node];
DumpTGN[s, ctgn.ktype, n];
DumpTGN[s, ctgn.union, n];
IO.PutF[s, "\t{ %g: $choice %g %g }\n",
IO.card[LOOPHOLE[node]],
IO.card[LOOPHOLE[ctgn.ktype]],
IO.card[LOOPHOLE[ctgn.union]]
];
};
DumpDerefTGN: PUBLIC TGNDumpProc ~ {
tgn: DerefTGN ~ NARROW[node];
DumpTGN[s, tgn.type, n]; -- recursion cut point!
IO.PutF[s, "\t{ %g: $derefTGN %g }\n",
IO.card[LOOPHOLE[node]],
IO.rope[tgn.item]
];
};
DumpEnumTGN: PUBLIC TGNDumpProc ~ {
etgn: EnumTGN ~ NARROW[node];
DumpTGN[s, etgn.enum, n];
IO.PutF[s, "\t{ %g: $enum %g }\n",
IO.card[LOOPHOLE[node]],
IO.card[LOOPHOLE[etgn.enum]]
];
};
DumpErrorTGN: PUBLIC TGNDumpProc ~ {
etgn: ErrorTGN ~ NARROW[node];
DumpTGN[s, etgn.fieldlist, n];
IO.PutF[s, "\t{ %g: $error %g }\n",
IO.card[LOOPHOLE[node]],
IO.card[LOOPHOLE[etgn.fieldlist]]
];
};
DumpLinkTGN: PUBLIC TGNDumpProc ~ {
tgn: LinkTGN ~ NARROW[node];
DumpTGN[s, tgn.tgn, n]; -- recursion cut point!
IO.PutF[s, "\t{ %g: $derefTGN %g %g }\n",
IO.card[LOOPHOLE[node]],
IO.rope[tgn.interface],
IO.rope[tgn.item]
];
};
DumpProcTGN: PUBLIC TGNDumpProc ~ {
tgn: ProcTGN ~ NARROW[node];
DumpTGN[s, tgn.args, n];
DumpTGN[s, tgn.results, n];
DumpTGN[s, tgn.errors, n];
IO.PutF[s, "\t{ %g: $proc %g %g %g }\n",
IO.card[LOOPHOLE[node]],
IO.card[LOOPHOLE[tgn.args]],
IO.card[LOOPHOLE[tgn.results]],
IO.card[LOOPHOLE[tgn.errors]]
];
};
DumpRecordTGN: PUBLIC TGNDumpProc ~ {
tgn: RecordTGN ~ NARROW[node];
DumpTGN[s, tgn.fieldlist, n];
IO.PutF[s, "\t{ %g: $record %g }\n",
IO.card[LOOPHOLE[node]],
IO.card[LOOPHOLE[tgn.fieldlist]]
];
};
DumpSequenceTGN: PUBLIC TGNDumpProc ~ {
tgn: SequenceTGN ~ NARROW[node];
DumpAVN[s, tgn.maxlength];
DumpTGN[s, tgn.subtype, n];
IO.PutF[s, "\t{ %g: $sequence %g %g }\n",
IO.card[LOOPHOLE[node]],
IO.card[LOOPHOLE[tgn.maxlength]],
IO.card[LOOPHOLE[tgn.subtype]]
];
};
Secondary Creators
DumpFieldListTGN: PUBLIC TGNDumpProc ~ {
tgn: FieldListTGN ~ NARROW[node];
DumpAVN[s, tgn.ordinal];
IO.PutF[s, "\t{ %g: $fieldlist %g %g }\n",
IO.card[LOOPHOLE[node]],
IO.rope[tgn.tag],
IO.card[LOOPHOLE[tgn.ordinal]]
];
};
DumpUnionTGN: PUBLIC TGNDumpProc ~ {
tgn: UnionTGN ~ NARROW[node];
DumpTGN[s, tgn.namelist, n];
DumpTGN[s, tgn.type, n];
IO.PutF[s, "\t{ %g: $union %g %g }\n",
IO.card[LOOPHOLE[node]],
IO.card[LOOPHOLE[tgn.namelist]],
IO.card[LOOPHOLE[tgn.type]]
];
};
DumpFieldTGN: PUBLIC TGNDumpProc ~ {
tgn: FieldTGN ~ NARROW[node];
DumpTGN[s, tgn.namelist, n];
DumpTGN[s, tgn.type, n];
IO.PutF[s, "\t{ %g: $field %g %g }\n",
IO.card[LOOPHOLE[node]],
IO.card[LOOPHOLE[tgn.namelist]],
IO.card[LOOPHOLE[tgn.type]]
];
};
DumpEmptyFieldTGN: PUBLIC TGNDumpProc ~ {
tgn: FieldTGN ~ NARROW[node];
IO.PutF[s, "\t{ %g: $emptyfield }\n", IO.card[LOOPHOLE[node]] ];
};
Abstract Value Node Creators
internal for now!
DumpGenericAVN: PUBLIC AVNDumpProc ~ {
IO.PutF[s, "\t\t{ %g }\n",
IO.refAny[value]
];
};
MarkAbstractValue: PROC [value: AbstractValue] ~ {
};
DumpAVN: PUBLIC AVNDumpProc ~ {
IF ( value = NIL ) THEN RETURN;
MarkAbstractValue[value]; -- unneccessary?
WITH value SELECT FROM
avn: REF AbstractValueObject => { DumpIndirectAVN[s, avn, n]; };
avn: HackAVN => { DumpHackAVN[s, avn, n]; };
avn: NullAVN => { DumpNullAVN [s, avn, n]; };
avn: LogicalAVN => { DumpLogicalAVN [s, avn, n]; };
avn: NumericalAVN => { DumpNumericalAVN [s, avn, n]; };
avn: RopeAVN => { DumpRopeAVN [s, avn, n]; };
avn: BindingAVN => { DumpBindingAVN [s, avn, n]; };
avn: ConstructorAVN => { DumpConstructorAVN [s, avn, n]; };
avn: DerefAVN => { DumpDerefAVN [s, avn, n]; };
avn: GroupingAVN => { DumpGroupingAVN [s, avn, n]; };
avn: LinkAVN => { DumpLinkAVN [s, avn, n]; };
avn: VariantAVN => { DumpVariantAVN [s, avn, n]; };
ENDCASE => { ERROR };
};
DumpIndirectAVN: PUBLIC AVNDumpProc ~ {
avn: REF AbstractValueObject ~ NARROW[value];
DumpAVN[s, avn.specifics, n];
IO.PutF[s, "\t{ %g: $indirectavn %g }\n", IO.card[LOOPHOLE[value]], IO.card[LOOPHOLE[avn.specifics]] ];
};
DumpHackAVN: PUBLIC AVNDumpProc ~ {
avn: HackAVN ~ NARROW[value];
DumpAVN[s, avn.value, n];
DumpAVN[s, avn.next, n];
IO.PutF[s, "\t{ %g: $hackavn %g %g }\n",
IO.card[LOOPHOLE[value]],
IO.card[LOOPHOLE[avn.value]],
IO.card[LOOPHOLE[avn.next]]
];
};
Primary Creators
DumpNullAVN: PUBLIC AVNDumpProc ~ {
IF TRUE THEN IO.PutF[s, "$null %g", IO.refAny[value] ];
};
DumpLogicalAVN: PUBLIC AVNDumpProc ~ {
avn: LogicalAVN ~ NARROW[value];
IO.PutF[s, "\t{ %g: $logical %g }\n",
IO.card[LOOPHOLE[value]],
IO.bool[avn.value]
];
};
DumpNumericalAVN: PUBLIC AVNDumpProc ~ {
avn: NumericalAVN ~ NARROW[value];
IO.PutF[s, "\t{ %g: $number %g %g }\n",
IO.card[LOOPHOLE[value]],
IO.bool[avn.inverted],
IO.card[avn.value]
];
};
DumpRopeAVN: PUBLIC AVNDumpProc ~ {
avn: RopeAVN ~ NARROW[value];
IO.PutF[s, "\t{ %g: $rope %g }\n",
IO.card[LOOPHOLE[value]],
IO.rope[avn.value]
];
};
Secondary Creators
DumpBindingAVN: PUBLIC AVNDumpProc ~ {
avn: BindingAVN ~ NARROW[value];
DumpTGN[s, avn.tgn, n];
DumpAVN[s, avn.node, n];
IO.PutF[s, "\t{ %g: $binding %g %g }\n",
IO.card[LOOPHOLE[value]],
IO.card[LOOPHOLE[avn.tgn]],
IO.card[LOOPHOLE[avn.node]]
];
};
DumpConstructorAVN: PUBLIC AVNDumpProc ~ {
avn: ConstructorAVN ~ NARROW[value];
DumpAVN[s, avn.node, n];
IO.PutF[s, "\t{ %g: $constructor %g }\n",
IO.card[LOOPHOLE[value]],
IO.card[LOOPHOLE[avn.node]]
];
};
DumpDerefAVN: PUBLIC AVNDumpProc ~ {
avn: DerefAVN ~ NARROW[value];
DumpAVN[s, avn.value, n]; -- recursion cut point!
IO.PutF[s, "\t{ %g: $deref %g }\n",
IO.card[LOOPHOLE[value]],
IO.rope[avn.item]
];
};
DumpGroupingAVN: PUBLIC AVNDumpProc ~ {
avn: GroupingAVN ~ NARROW[value];
DumpAVN[s, avn.value, n]; -- recursion cut point!
IO.PutF[s, "\t{ %g: $grouping %g }\n",
IO.card[LOOPHOLE[value]],
IO.card[LOOPHOLE[avn.node]]
];
};
DumpLinkAVN: PUBLIC AVNDumpProc ~ {
avn: LinkAVN ~ NARROW[value];
DumpAVN[s, avn.avn, n];
IO.PutF[s, "\t{ %g: $linkavn %g %g %g }\n",
IO.card[LOOPHOLE[value]],
IO.rope[avn.interface],
IO.rope[avn.item],
IO.card[LOOPHOLE[avn.avn]]
];
};
DumpVariantAVN: PUBLIC AVNDumpProc ~ {
avn: VariantAVN ~ NARROW[value];
DumpAVN[s, avn.node, n];
IO.PutF[s, "\t{ %g: $variant %g %g }\n",
IO.card[LOOPHOLE[value]],
IO.rope[avn.id],
IO.card[LOOPHOLE[avn.node]]
];
};
internal/external conversion routines
KindToRope: PROC [ kind: TGNKind ] RETURNS [ rope: ROPE ] ~ {
SELECT kind FROM
indirect => { rope ← "$indirect" };
generic => { rope ← "$generic" };
internal => { rope ← "$internal" };
ENDCASE => ERROR;
};
RopeToKind: PROC [ rope: ROPE ] RETURNS [ kind: TGNKind ] ~ {
SELECT TRUE FROM
Rope.Equal[rope, "$indirect"] => { kind ← indirect };
Rope.Equal[rope, "$generic"] => { kind ← generic };
Rope.Equal[rope, "$internal"] => { kind ← internal };
ENDCASE => ERROR;
};
ValueKindToRope: PROC [ kind: ValueKind ] RETURNS [ rope: ROPE ] ~ {
SELECT kind FROM
bool => { rope ← "$bool" };
constructor => { rope ← "$constructor" };
grouping => { rope ← "$grouping" };
negation => { rope ← "$negation" };
null => { rope ← "$null" };
number => { rope ← "$number" };
string => { rope ← "$string" };
variant => { rope ← "$indirect" };
ENDCASE => ERROR;
};
RopeToValueKind: PROC [ rope: ROPE ] RETURNS [ kind: ValueKind ] ~ {
SELECT TRUE FROM
Rope.Equal[rope, "$bool"] => { kind ← bool };
Rope.Equal[rope, "$constructor"] => { kind ← constructor };
Rope.Equal[rope, "$grouping"] => { kind ← grouping };
Rope.Equal[rope, "$negation"] => { kind ← negation };
Rope.Equal[rope, "$null"] => { kind ← null };
Rope.Equal[rope, "$number"] => { kind ← number };
Rope.Equal[rope, "$string"] => { kind ← string };
Rope.Equal[rope, "$variant"] => { kind ← variant };
ENDCASE => ERROR;
};
ClassToRope: PROC [ class: Generic ] RETURNS [ rope: ROPE ] ~ {
SELECT class FROM
array => rope ← "$array";
bool => rope ← "$bool";
card16 => rope ← "$card16";
card32 => rope ← "$card32";
choice => rope ← "$choice";
enum => rope ← "$enum";
error => rope ← "$error";
int16 => rope ← "$int16";
int32 => rope ← "$int32";
proc => rope ← "$proc";
record => rope ← "$record";
seq => rope ← "$seq";
sink => rope ← "$sink";
source => rope ← "$source";
string => rope ← "$string";
unspec => rope ← "$unspec";
ENDCASE => ERROR;
};
RopeToClass: PROC [ rope: ROPE ] RETURNS [ class: Generic ] ~ {
SELECT TRUE FROM
Rope.Equal[rope, "$array"] => class ← array;
Rope.Equal[rope, "$bool"] => class ← bool;
Rope.Equal[rope, "$card16"] => class ← card16;
Rope.Equal[rope, "$choice"] => class ← choice;
Rope.Equal[rope, "$enum"] => class ← enum;
Rope.Equal[rope, "$error"] => class ← error;
Rope.Equal[rope, "$int16"] => class ← int16;
Rope.Equal[rope, "$card32"] => class ← card32;
Rope.Equal[rope, "$int32"] => class ← int32;
Rope.Equal[rope, "$proc"] => class ← proc;
Rope.Equal[rope, "$record"]=> class ← record;
Rope.Equal[rope, "$seq"] => class ← seq;
Rope.Equal[rope, "$sink"] => class ← sink;
Rope.Equal[rope, "$source"] => class ← source;
Rope.Equal[rope, "$string"] => class ← string;
Rope.Equal[rope, "$unspec"] => class ← unspec;
ENDCASE => ERROR;
};
}.