RoseTranslateWrite2.Mesa
Last Edited by: Spreitzer, September 6, 1984 5:40:14 pm PDT
Last Edited by: Barth, March 8, 1983 10:45 am
Last Edited by: Gasbarro, August 16, 1984 4:05:44 pm PDT
DIRECTORY Asserting, AssertingIO, Basics, Convert, FS, IO, OrderedSymbolTableRef, Rope, RoseTranslateTypes, RoseTranslateInsides, TiogaFileOps, TiogaStreams;
RoseTranslateWrite2: CEDAR PROGRAM
IMPORTS Asserting, IO, OSTR: OrderedSymbolTableRef, Rope, TS: TiogaStreams, RoseTranslateInsides
EXPORTS RoseTranslateInsides =
BEGIN OPEN RoseTranslateTypes, RoseTranslateInsides;
WriteExpand: PUBLIC PROC [job: Job, name: ROPE, ec: LORA, cellDef: CellDef] =
BEGIN
TS.EndNode[job.to];
job.to.PutF["%gExpand: PROC [thisCell: Cell, to: ExpansionReceiver] --ExpandProc-- = {", IO.rope[name]];
TS.ChangeDepth[job.to, 1];
IF cellDef.forFn # NIL THEN {
job.to.PutF["args: REF %gArgs ← NARROW[thisCell.type.typeData];", IO.rope[name]];
TS.ChangeDepth[job.to, 1];
job.to.PutRope["{OPEN args;"];
TS.EndNode[job.to]};
IF (cellDef.interfaceLiteral # NIL) AND (cellDef.interfaceLiteral.asList # NIL) THEN {
job.to.PutRope["PrivateLookupNode: PROC [name: ROPE] RETURNS [node: Node] = {node ← RoseCreate.LookupNode[from: thisCell, path: LIST[name]]};"];
TS.EndNode[job.to];
};
IF cellDef.interfaceLiteral # NIL THEN FOR iel: InterfaceEltList ← cellDef.interfaceLiteral.asList, iel.rest WHILE iel # NIL DO
job.to.PutF[
"%g: Node ← PrivateLookupNode[\"%g\"];",
IO.rope[iel.first.name], IO.rope[iel.first.name]];
TS.EndNode[job.to];
ENDLOOP;
job.nodeCreateHacks ← OSTR.CreateTable[CompareNCHs];
job.nchCount ← 0;
job.previewing ← TRUE;
FOR lora: LORA ← ec, lora.rest WHILE lora # NIL DO
WriteBinding: PROC [b: Binding] =
BEGIN
WITH b.value SELECT FROM
sti: SignalTypeInvocation => WriteNodeInstance[job, b.name, sti.st, b.assertions, b.initial];
a: Application => WriteCellInstance[job, name, b.name, a];
id: ID => WriteWhateverInstance[job, b.name, id.rope, b.assertions, b.initial];
ENDCASE => ERROR;
END;
WITH lora.first SELECT FROM
cs: CedarSource => NULL;
bl: BindingList => FOR bl ← bl, bl.rest WHILE bl # NIL DO WriteBinding[bl.first] ENDLOOP;
b: Binding => WriteBinding[b];
ENDCASE => ERROR;
ENDLOOP;
job.previewing ← FALSE;
FOR lora: LORA ← ec, lora.rest WHILE lora # NIL DO
WriteBinding: PROC [b: Binding] =
BEGIN
WITH b.value SELECT FROM
sti: SignalTypeInvocation => WriteNodeInstance[job, b.name, sti.st, b.assertions, b.initial];
a: Application => WriteCellInstance[job, name, b.name, a];
id: ID => WriteWhateverInstance[job, b.name, id.rope, b.assertions, b.initial];
ENDCASE => ERROR;
END;
WITH lora.first SELECT FROM
cs: CedarSource => InjectCedar[job, cs];
bl: BindingList => FOR bl ← bl, bl.rest WHILE bl # NIL DO WriteBinding[bl.first] ENDLOOP;
b: Binding => WriteBinding[b];
ENDCASE => ERROR;
ENDLOOP;
IF cellDef.forFn # NIL THEN {
job.to.PutRope["};"]; TS.ChangeDepth[job.to, -1]};
job.to.PutRope["};"]; TS.ChangeDepth[job.to, -1];
END;
InjectCedar: PUBLIC PROC [job: Job, cs: CedarSource] =
BEGIN
where: TiogaFileOps.Ref;
TS.EndNode[job.to];
job.to.PutRope["--explicitly requested CEDAR:"];
TS.EndNode[job.to];
where ← TS.CurOutNode[job.to];
TS.EndNode[job.to];
TS.CopyChildren[from: cs.parent, to: where];
END;
NodeCreateHack: TYPE = REF NodeCreateHackRep;
NodeCreateHackRep: TYPE = RECORD [
key, name: ROPE,
callCount: CARDINAL];
CompareNCHs: PROC [r1, r2: REF ANY] RETURNS [c: Basics.Comparison] =
BEGIN
Key: PROC [r: REF ANY] RETURNS [k: ROPE] = {k ← WITH r SELECT FROM
x: ROPE => x,
nch: NodeCreateHack => nch.key,
ENDCASE => ERROR};
c ← Key[r1].Compare[Key[r2]];
END;
WriteNodeInstance: PROC [job: Job, name: ROPE, st: NodeType, assertions: Assertions, initialValue: REF ANY] =
BEGIN
initialExpression: ROPENIL;
xPhobicize: BOOLNOT st.simple;
xPhobeHead: ROPE;
FOR assertions ← assertions, assertions.rest WHILE assertions # NIL DO
key: ATOMNARROW[Asserting.RelnOf[assertions.first]];
SELECT key FROM
$XPhobic => xPhobicize ← TRUE;
$XPhillic => xPhobicize ← FALSE;
ENDCASE => Whimper[nullSR, job, "Don't recognize assertion %g about node %g", IO.refAny[assertions.first], IO.rope[name]];
ENDLOOP;
IF xPhobicize AND st.simple THEN {
Whimper[nullSR, job, "Don't xphobicize a simple node (%g, of type %g)", IO.rope[name], IO.rope[st.procs.UserDescription[st]]];
xPhobicize ← FALSE};
xPhobeHead ← IF xPhobicize THEN "RoseCreate.XPhobicize[" ELSE "";
IF initialValue # NIL THEN WITH initialValue SELECT FROM
q: Quoted => initialExpression ← IO.PutFR["\"%q\"", IO.rope[q.rope]];
cl: CedarLiteral => initialExpression ← cl.cedar;
ENDCASE => ERROR;
IF job.previewing THEN BEGIN
roseType: Mesa ← st.procs.MesaDescription[st];
key: ROPEIO.PutFR["\"%q\"%g ← %g", IO.rope[roseType.mesa], IO.bool[xPhobicize], IO.rope[initialExpression]];
nch: NodeCreateHack ← NARROW[job.nodeCreateHacks.Lookup[key]];
IF nch = NIL THEN job.nodeCreateHacks.Insert[nch ← NEW [NodeCreateHackRep ← [
key: key,
name: NIL,
callCount: 0]]];
nch.callCount ← nch.callCount + 1;
END
ELSE BEGIN
roseType: Mesa ← st.procs.MesaDescription[st];
key: ROPEIO.PutFR["\"%q\"%g ← %g", IO.rope[roseType.mesa], IO.bool[xPhobicize], IO.rope[initialExpression]];
nch: NodeCreateHack ← NARROW[job.nodeCreateHacks.Lookup[key]];
ne: nodeEntry ← NEW [SymbolTableEntryRep[node] ← [name: name, value: node[st]]];
IF job.things.Lookup[name] = NIL THEN job.things.Insert[ne]
ELSE Whimper[nullSR, job, "node %g multiply defined", IO.rope[name]];
AddMesa[job, roseType];
IF nch.callCount >= nodeCreateHackThreshold THEN BEGIN
IF nch.name = NIL THEN BEGIN
nch.name ← IO.PutFR["NodeCreateHack%g", IO.card[job.nchCount ← job.nchCount + 1]];
job.to.PutF["%g: PROC [name: ROPE] RETURNS [node: Node] = {node ← %gto.class.NodeInstance[erInstance: to.instance, name: name, type: %g", IO.rope[nch.name], IO.rope[xPhobeHead], IO.rope[roseType.mesa]];
IF initialExpression # NIL THEN job.to.PutF[", initialValue: %g", IO.rope[initialExpression]];
IF xPhobicize THEN job.to.PutRope["]"];
job.to.PutRope["]};"]; TS.EndNode[job.to];
END;
job.to.PutF["%g: Node ← %g[\"%g\"", IO.rope[name], IO.rope[nch.name], IO.rope[name]];
END
ELSE BEGIN
job.to.PutF["%g: Node ← %gto.class.NodeInstance[erInstance: to.instance, name: \"%g\", type: %g", IO.rope[name], IO.rope[xPhobeHead], IO.rope[name], IO.rope[roseType.mesa]];
IF initialExpression # NIL THEN job.to.PutF[", initialValue: %g", IO.rope[initialExpression]];
IF xPhobicize THEN job.to.PutRope["]"];
END;
job.to.PutRope["];"];
TS.EndNode[job.to];
END;
END;
nodeCreateHackThreshold: CARDINAL ← 3;
WriteCellInstance: PROC [job: Job, defName, instanceName: ROPE, a: Application] =
BEGIN
ste: SymbolTableEntry;
cd: CellDef;
definedIn: ROPE;
typeNameExpr: ROPE;
fromSelf: BOOLEAN;
IF job.previewing THEN RETURN;
WITH a.subject SELECT FROM
id: ID => {
lit: ROPE ← id.rope;
typeNameExpr ← IO.PutFR["\"%q\"", IO.rope[lit]];
ste ← NARROW[job.things.Lookup[lit]];
IF ste = NIL THEN
BEGIN
[] ← Complain[a.sr, job, "Cell Class %g undefined!", IO.rope[lit]];
cd ← NEW [CellDefRep ← []]; definedIn ← NIL;
IF lit # NIL THEN AddCellClass[job, NEW [SymbolTableEntryRep[cellClass] ← [name: lit, value: cellClass[globvar: FALSE, definedIn: definedIn, cd: cd]]]];
END
ELSE WITH ste SELECT FROM
cce: ccEntry => {
fromSelf ← (definedIn ← cce.definedIn).Equal[job.rootName, FALSE];
cd ← cce.cd;
IF NOT cce.globvar
THEN typeNameExpr ← IO.PutFR["\"%q\"", IO.rope[ste.name]]
ELSE {
typeNameExpr ← ste.name.Cat[".name"];
IF NOT fromSelf
THEN typeNameExpr ← definedIn.Cat[".", typeNameExpr]};
};
ENDCASE => BEGIN
[] ← Complain[a.sr, job, "Can't instantiate %g like a Cell Class", IO.refAny[ste]];
definedIn ← NIL;
cd ← NEW [CellDefRep ← []];
END;
};
ia: Application => {s: IO.STREAMIO.ROS[];
sub: IDNARROW[ia.subject];
functionName: ROPE ← Rope.Cat["?", sub.rope, "?"];
ste: SymbolTableEntry ← NARROW[job.things.Lookup[sub.rope]];
ok: BOOLFALSE;
cd ← NEW [CellDefRep ← []];
IF ste # NIL THEN WITH ste SELECT FROM
cfe: cfEntry => {
fromSelf ← (definedIn ← cfe.definedIn).Equal[job.rootName, FALSE];
functionName ← IF fromSelf THEN sub.rope ELSE definedIn.Cat[".", sub.rope];
IF NOT fromSelf THEN AddImport[job, definedIn];
cd ← cfe.cf.cd;
ok ← TRUE};
ENDCASE;
IF NOT ok THEN Whimper[ia.sr, job, "You tried to use %g as a CellTypeFunction name, but it ain't (it's a %g)", IO.rope[sub.rope], IO.refAny[ste]];
WriteCellFnInvocation[s, [nullSR, functionName, ia.args]];
typeNameExpr ← IO.RopeFromROS[s].Cat[".name"];
};
ENDCASE => ERROR;
fromSelf ← definedIn.Equal[job.rootName, FALSE];
job.to.PutF["[] ← to.class.CellInstance[erInstance: to.instance, instanceName: \"%g\", typeName: %g, interfaceNodes: ", IO.rope[instanceName], IO.rope[typeNameExpr]];
IF cd.interfaceLiteral # NIL THEN TypeCheck[job, defName, a.args, cd.interfaceLiteral, instanceName];
IF a.args # NIL THEN
BEGIN
job.to.PutRope["\""];
WITH a.args SELECT FROM
bl: BindingList => WriteBindingList[job.to, bl];
a: Args => WriteArgs[job.to, a];
ENDCASE => ERROR;
job.to.PutRope["\""];
END
ELSE job.to.PutRope["NIL"];
job.to.PutRope["];"];
TS.EndNode[job.to];
IF definedIn # NIL AND NOT fromSelf THEN AddImport[job, definedIn];
END;
WriteWhateverInstance: PROC [job: Job, name, class: ROPE, assertions: Assertions, initialValue: REF ANY] =
BEGIN
sti: SignalTypeInvocation ← InstantiateSignalType[job, class, NIL];
IF sti # NIL THEN WriteNodeInstance[job, name, sti.st, assertions, initialValue];
END;
END.