RoseTranslateWrite.Mesa
Last Edited by: Spreitzer, July 26, 1983 10:06 am
Last Edited by: Barth, March 8, 1983 10:45 am
DIRECTORY
FileIO, IO, OrderedSymbolTableRef, Rope, RoseTranslateTypes, RoseTranslateInsides, ShowTime, TiogaFileOps, TiogaStreams;
RoseTranslateWrite: CEDAR PROGRAM
IMPORTS FileIO, IO, OSTR: OrderedSymbolTableRef, Rope, ShowTime, TiogaFileOps, TS: TiogaStreams, RoseTranslateTypes, RoseTranslateInsides
EXPORTS RoseTranslateTypes, RoseTranslateInsides =
BEGIN OPEN RoseTranslateTypes, RoseTranslateInsides;
TypeConstructionError: PUBLIC ERROR [msg: ROPE] = CODE;
noDefault: PUBLIC REF ANYNEW [INT ← 69];
GetParm: PUBLIC PROC [n: [1..LAST[INTEGER]], name: ROPE, parms: REF ANY, default: REF ANY ← noDefault] RETURNS [it: REF ANY] =
BEGIN
IF parms = NIL THEN
BEGIN
IF default # noDefault THEN it ← default
ELSE ERROR TypeConstructionError[IO.PutFR["parm %g not found", IO.rope[name]]];
END
ELSE WITH parms SELECT FROM
bl: BindingList => BEGIN
FOR bl ← bl, bl.rest WHILE bl # NIL DO
IF bl.first.name.Equal[name, FALSE] THEN RETURN [bl.first.value];
ENDLOOP;
IF default # noDefault THEN it ← default
ELSE ERROR TypeConstructionError[IO.PutFR["parm %g not found", IO.rope[name]]];
END;
a: Args => BEGIN
i: INT ← n;
FOR l: LIST OF Arg ← a.args, l.rest WHILE l # NIL DO
IF i = 1 THEN RETURN [l.first];
i ← i - 1;
ENDLOOP;
IF default # noDefault THEN it ← default
ELSE ERROR TypeConstructionError[IO.PutFR["no %g'th parm", IO.int[i]]];
END;
ENDCASE => ERROR;
END;
TranslatePiece: PROC [job: Job, asAny: REF ANY] =
BEGIN
IF asAny # error THEN WITH asAny SELECT FROM
b: Binding => TranslateCellDef[b, job];
cs: CedarSource => InjectCedar[job, cs];
ENDCASE => [] ← Complain[job, "Got %g when expecting CEDAR or a CELL", IO.refAny[asAny]];
END;
Close: PUBLIC PROC [job: Job] =
BEGIN
IF job.errCount < 1 THEN
BEGIN
WITH job.parseTree SELECT FROM
s: Statements => FOR l: LORA ← s.statements, l.rest WHILE l # NIL DO TranslatePiece[job, l.first] ENDLOOP;
ENDCASE => TranslatePiece[job, job.parseTree];
END
ELSE job.log.PutRope["Translation aborted due to errors\n"];
job.log.PutF["%g error%g, %g warning%g", IO.card[job.errCount], IO.rope[IF job.errCount = 1 THEN "" ELSE "s"], IO.card[job.warnCount], IO.rope[IF job.warnCount = 1 THEN "" ELSE "s"]];
job.log.PutF["; source tokens: %g, time: %g\n", IO.card[job.tokenCount], IO.real[ShowTime.SinceMark[job.start]/1.0E6]];
job.directoryStream.PutRope[";"];
job.directoryStream.Close[];
job.importsStream.PutRope[" ="];
job.importsStream.Close[];
job.openStream.PutRope[";"];
job.openStream.Close[];
job.regStream.PutRope["END;"];
job.regStream.Close[];
job.typeStream.Close[];
TS.EndNode[job.to];
job.to.PutRope["RegisterCells[];"];
TS.EndNode[job.to];
TS.EndNode[job.to];
job.to.PutRope["END."];
job.to.Close[];
IF job.errCount < 1 THEN TRUSTED
BEGIN
destName: ROPE;
TiogaFileOps.Store[job.outRoot, destName ← job.rootName.Concat[".Mesa"]];
--DoMesaFormatting[destName];--
--UserExecExtras.DoIt[job.exec, Rope.Cat["compile ", job.rootName]];--
TiogaFileOps.Store[job.symbolsRoot, job.rootName.Concat[".RoseSymbols"]];
WriteDeps[job];
END;
END;
TranslateCellDef: PROC [b: Binding, job: Job] =
BEGIN
name: ROPE ← b.name;
cellDef: CellDef ← NARROW[b.value];
RationalizeInitData[job, name, cellDef];
AddInterfaceNodes[job, cellDef];
WriteInterfaceSpec[job, name, cellDef];
WriteRegistration[job, name, cellDef];
IF cellDef.interface.asList # NIL THEN cellDef.portCount ← WriteInterfaceDecls[job, name, cellDef.interface.asList];
IF cellDef.initDataGiven THEN WriteInitData[job, name, cellDef.initDataSource];
IF cellDef.defaultInitDataGiven THEN WriteDefaultInitData[job, name, cellDef.defaultInitDataSource];
IF cellDef.stateGiven THEN WriteState[job, name, cellDef.stateSource];
IF cellDef.expandGiven THEN WriteExpand[job, name, cellDef.expandCode.statements, cellDef];
IF cellDef.interface.asList # NIL THEN WriteIOCreator[job, name, cellDef];
IF cellDef.stateGiven OR cellDef.initializerGiven THEN WriteInitializer[job, name, cellDef.initializerSource, cellDef];
IF cellDef.evalGiven THEN WriteEval[job, name, cellDef.evalSource, cellDef];
IF cellDef.testGiven THEN WriteTest[job, name, cellDef.testSource, cellDef];
WritePorts[job, name, cellDef.portCount];
RemoveNodes[job];
AddCellClass[job, NEW [SymbolTableEntryRep[cellClass] ← [name: name, value: cellClass[definedIn: job.rootName, cd: cellDef]]]];
END;
RationalizeInitData: PROC [job: Job, className: ROPE, cellDef: CellDef] =
BEGIN
IF cellDef.defaultInitDataGiven AND cellDef.defaultInitExprGiven THEN
Whimper[job, "%g's default init data expression given both implicitly and explicitly", IO.rope[className]]
ELSE IF cellDef.defaultInitDataGiven THEN
BEGIN
cellDef.defaultInitExprGiven ← TRUE;
cellDef.defaultInitExpr ← IO.PutFR["%g.default%gInitRef", IO.rope[job.rootName], IO.rope[className]];
END;
END;
RemoveNodes: PROC [job: Job] =
BEGIN
DeleteNode: PROC [asAny: REF ANY] RETURNS [stop: BOOLEAN] =
BEGIN
ste: SymbolTableEntry ← NARROW[asAny];
IF ste.type = node THEN [] ← job.things.Delete[ste];
stop ← FALSE;
END;
job.things.EnumerateIncreasing[DeleteNode];
END;
AddInterfaceNodes: PROC [job: Job, cellDef: CellDef] =
BEGIN
FOR iel: InterfaceEltList ← cellDef.interface.asList, iel.rest WHILE iel # NIL DO
ne: nodeEntry ← NEW [SymbolTableEntryRep[node] ← [name: iel.first.name, value: node[iel.first.sti.st]]];
job.things.Insert[ne];
ENDLOOP;
END;
WriteInterfaceSpec: PROC [job: Job, name: ROPE, cellDef: CellDef] =
BEGIN
job.symbolsStream.PutF["%g %g %g %g ", IO.rope[name], IO.rope[job.rootName], IO.card[(IF cellDef.defaultInitExprGiven THEN 1 ELSE 0) + (IF cellDef.initializerGiven THEN 2 ELSE 0) + (IF cellDef.initDataGiven THEN 4 ELSE 0)], IO.refAny[cellDef.defaultInitExpr]];
IF cellDef.interface.asList # NIL THEN WriteInterface[job.symbolsStream, cellDef.interface] ELSE job.symbolsStream.PutRope["NULL"];
job.symbolsStream.PutRope[" !!\n"];
TS.EndNode[job.symbolsStream];
END;
WriteInterface: PROC [to: IO.STREAM, interface: DigestedInterface] =
BEGIN
first: BOOLEANTRUE;
to.PutRope["["];
FOR iel: InterfaceEltList ← interface.asList, iel.rest WHILE iel # NIL DO
IF first THEN first ← FALSE ELSE to.PutRope[", "];
to.PutF["%g%g", IO.rope[iel.first.name], IO.rope[ways[iel.first.input][iel.first.output]]];
WriteInvocation[to, iel.first.sti.invocation];
ENDLOOP;
to.PutRope["]"];
END;
ways: ARRAY BOOLEAN OF ARRAY BOOLEAN OF ROPE ← [["??", ">"], ["<", "="]];
WriteInvocation: PROC [to: IO.STREAM, i: Invocation] =
BEGIN
to.PutRope[i.name];
IF i.parms # NIL THEN
BEGIN
to.PutRope["["];
WITH i.parms SELECT FROM
bl: BindingList => WriteBindingList[to, bl];
a: Args => WriteArgs[to, a];
ENDCASE => ERROR;
to.PutRope["]"];
END;
END;
WriteBindingList: PROC [to: IO.STREAM, bl: BindingList] =
BEGIN
first: BOOLEANTRUE;
FOR bl ← bl, bl.rest WHILE bl # NIL DO
IF first THEN first ← FALSE ELSE to.PutRope[", "];
to.PutF["%g:", IO.rope[bl.first.name]];
WriteValue[to, bl.first.value];
ENDLOOP;
END;
WriteArgs: PROC [to: IO.STREAM, args: Args] =
BEGIN
first: BOOLEANTRUE;
FOR l: LIST OF Arg ← args.args, l.rest WHILE l # NIL DO
IF first THEN first ← FALSE ELSE to.PutRope[", "];
WriteValue[to, l.first];
ENDLOOP;
END;
WriteValue: PROC [to: IO.STREAM, value: REF ANY] =
BEGIN
WITH value SELECT FROM
r: ROPE => to.PutRope[r];
q: Quoted => to.Put[IO.refAny[q.rope]];
ri: REF INT => to.Put[IO.int[ri^]];
ENDCASE => ERROR;
END;
WriteInterfaceDecls: PROC [job: Job, name: ROPE, interface: InterfaceEltList] RETURNS [iCount: CARDINAL] =
BEGIN
toIO: IO.STREAM;
toPorts: IO.STREAM;
firstWord: CARDINAL ← 0;
dest: TiogaFileOps.Ref;
iCount ← 0;
TS.EndNode[job.to];
job.to.PutF["Create%gPorts: PROC =", IO.rope[name]];
toPorts ← TS.CreateOutput[TS.CurOutNode[job.to], "code"];
TS.EndNode[job.to];
TS.EndNode[job.to];
toPorts.PutRope["BEGIN"]; TS.EndNode[toPorts];
job.to.PutF["%gIORef: TYPE = REF %gIORec;", IO.rope[name], IO.rope[name]];
TS.EndNode[job.to];
job.to.PutF["%gIORec: TYPE = MACHINE DEPENDENT RECORD [", IO.rope[name]];
TS.EndNode[job.to];
dest ← TS.CurOutNode[job.to];
TS.EndNode[job.to];
toIO ← TS.CreateOutput[dest, "code"];
FOR interface ← interface, interface.rest WHILE interface # NIL DO
Finish: PROC [s: IO.STREAM] =
{IF interface.rest # NIL THEN {s.PutRope[","]; TS.EndNode[s]}};
DoFor: PROC [iename: ROPE] =
BEGIN
IF bitRem # 0 THEN
BEGIN
toIO.PutF["fill%g(%g:0..%g): [0..%g],", IO.card[iCount], IO.card[firstWord], IO.int[15 - bitRem], IO.card[uppers[16 - bitRem]]];
TS.EndNode[toIO];
END;
toIO.PutF["%g(%g:%g..%g): %g", IO.rope[iename], IO.card[firstWord], IO.card[(16-bitRem) MOD 16], IO.card[16*wordWidth - 1], IO.rope[mesaType]];
Finish[toIO];
toPorts.PutF["%gPorts[%g] ← [%g, %g, \"%g\", ", IO.rope[name], IO.card[iCount], IO.card[firstWord], IO.card[wordWidth], IO.rope[iename]];
toPorts.PutF["%g, %g, %g];", IO.rope[roseType], IO.bool[ie.input], IO.bool[ie.output]];
TS.EndNode[toPorts];
firstWord ← firstWord + wordWidth;
iCount ← iCount + 1;
END;
ie: InterfaceElt ← interface.first;
bitWidth, wordWidth, bitRem: CARDINAL;
roseType, mesaType: ROPE;
UseSignalType[job, ie.sti.st];
[bitWidth, roseType, mesaType] ← ie.sti.st.procs.Info[ie.sti.st.data];
wordWidth ← (bitWidth + 15)/16;
bitRem ← bitWidth MOD 16;
DoFor[ie.name];
ENDLOOP;
toIO.PutRope["];"]; toIO.Close[];
toPorts.PutRope["END;"]; toPorts.Close[];
END;
uppers: ARRAY [1..15] OF CARDINAL ← [1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767];
WriteInitData: PROC [job: Job, name: ROPE, cs: CedarSource] =
BEGIN
dest: TiogaFileOps.Ref;
TS.EndNode[job.to];
job.to.PutF["%gInitRef: TYPE = REF %gInitRec;", IO.rope[name], IO.rope[name]];
TS.EndNode[job.to];
job.to.PutF["%gInitRec: PUBLIC TYPE = RECORD [", IO.rope[name]];
dest ← TS.CurOutNode[job.to];
TS.ChangeDepth[job.to, 1];
job.to.PutF["];"]; TS.ChangeDepth[job.to, -1];
TS.CopyChildren[from: cs.parent, to: dest];
END;
WriteDefaultInitData: PROC [job: Job, name: ROPE, cs: CedarSource] =
BEGIN
dest: TiogaFileOps.Ref;
TS.EndNode[job.to];
job.to.PutF["default%gInitRef: PUBLIC %gInitRef ← NEW [%gInitRec ← [", IO.rope[name], IO.rope[name], IO.rope[name]];
dest ← TS.CurOutNode[job.to];
TS.ChangeDepth[job.to, 1];
job.to.PutF["]];"]; TS.ChangeDepth[job.to, -1];
TS.CopyChildren[from: cs.parent, to: dest];
END;
WriteState: PROC [job: Job, name: ROPE, cs: CedarSource] =
BEGIN
dest: TiogaFileOps.Ref;
TS.EndNode[job.to];
job.to.PutF["%gStateRef: TYPE = REF %gStateRec;", IO.rope[name], IO.rope[name]];
TS.EndNode[job.to];
job.to.PutF["%gStateRec: TYPE = RECORD [", IO.rope[name]];
dest ← TS.CurOutNode[job.to];
TS.ChangeDepth[job.to, 1];
job.to.PutF["];"]; TS.ChangeDepth[job.to, -1];
TS.CopyChildren[from: cs.parent, to: dest];
END;
WriteIOCreator: PROC [job: Job, name: ROPE, cellDef: CellDef] =
BEGIN
TS.EndNode[job.to];
job.to.PutF["Create%gIO: IOCreator = {", IO.rope[name]];
TS.ChangeDepth[job.to, 1];
job.to.PutF["cell.realCellStuff.newIO ← NEW [%gIORec];", IO.rope[name]];
TS.EndNode[job.to];
job.to.PutF["cell.realCellStuff.oldIO ← NEW [%gIORec];", IO.rope[name]];
TS.EndNode[job.to];
job.to.PutRope["};"];
TS.ChangeDepth[job.to, -1];
END;
WriteInitializer: PROC [job: Job, name: ROPE, cs: CedarSource, cellDef: CellDef] =
BEGIN
dest: TiogaFileOps.Ref;
opend: ROPE ← "";
TS.EndNode[job.to];
job.to.PutF["Initialize%g: Initializer = {", IO.rope[name]];
TS.ChangeDepth[job.to, 1];
job.to.PutRope["IF leafily THEN"];
TS.ChangeDepth[job.to, 1];
job.to.PutRope["BEGIN"];
TS.EndNode[job.to];
IF cellDef.initializerGiven THEN
BEGIN
job.to.PutF["ioRec: %gIORef ← NARROW[cell.realCellStuff.newIO];", IO.rope[name]];
TS.EndNode[job.to];
opend ← opend.Cat["ioRec"];
IF cellDef.initDataGiven THEN
BEGIN
job.to.PutF["narrowedInitData: %gInitRef ← NARROW[initData];", IO.rope[name]];
TS.EndNode[job.to];
opend ← opend.Cat[", narrowedInitData"];
END;
IF cellDef.stateGiven THEN opend ← opend.Cat[", state"];
END;
IF cellDef.stateGiven THEN
BEGIN
job.to.PutF["state: %gStateRef ← NEW [%gStateRec", IO.rope[name], IO.rope[name]];
IF cellDef.stateInittable THEN job.to.PutRope[" ← []"];
job.to.PutRope["];"];
TS.EndNode[job.to];
job.to.PutRope["cell.realCellStuff.state ← state;"];
TS.EndNode[job.to];
END;
IF cellDef.initializerGiven THEN
BEGIN
job.to.PutF["BEGIN OPEN %g;", IO.rope[opend]];
dest ← TS.CurOutNode[job.to];
TS.ChangeDepth[job.to, 1];
job.to.PutRope["END;"];
TS.ChangeDepth[job.to, -1];
TS.CopyChildren[from: cs.parent, to: dest];
END;
job.to.PutRope["END;"];
TS.ChangeDepth[job.to, -1];
job.to.PutRope["};"];
TS.ChangeDepth[job.to, -1];
END;
WriteEval: PROC [job: Job, name: ROPE, cs: CedarSource, cellDef: CellDef] =
BEGIN
dest: TiogaFileOps.Ref;
opend: ROPE;
TS.EndNode[job.to];
job.to.PutF["%gEval: EvalProc =", IO.rope[name]]; TS.ChangeDepth[job.to, 1];
job.to.PutRope["BEGIN"]; TS.EndNode[job.to];
job.to.PutF["newIO: %gIORef ← NARROW[cell.realCellStuff.newIO];", IO.rope[name]];
TS.EndNode[job.to];
job.to.PutF["oldIO: %gIORef ← NARROW[cell.realCellStuff.oldIO];", IO.rope[name]];
TS.EndNode[job.to];
IF cellDef.stateGiven THEN
BEGIN
job.to.PutF["state: %gStateRef ← NARROW[cell.realCellStuff.state];", IO.rope[name]];
TS.EndNode[job.to];
opend ← ", state";
END
ELSE opend ← "";
job.to.PutRope["oldIO^ ← newIO^;"];
TS.ChangeDepth[job.to, 1];
job.to.PutF["BEGIN OPEN newIO%g;", IO.rope[opend]];
dest ← TS.CurOutNode[job.to];
TS.EndNode[job.to];
job.to.PutRope["END;"];
TS.ChangeDepth[job.to, -1];
TS.CopyChildren[from: cs.parent, to: dest];
job.to.PutRope["END;"];
TS.ChangeDepth[job.to, -1];
END;
WriteTest: PROC [job: Job, name: ROPE, cs: CedarSource, cellDef: CellDef] =
BEGIN
dest: TiogaFileOps.Ref;
TS.EndNode[job.to];
job.to.PutF["%gTest: EvalProc =", IO.rope[name]]; TS.ChangeDepth[job.to, 1];
job.to.PutRope["BEGIN"]; TS.EndNode[job.to];
job.to.PutF["ioRec: %gIORef ← NARROW[cell.realCellStuff.newIO];", IO.rope[name]];
TS.ChangeDepth[job.to, 1];
job.to.PutRope["BEGIN OPEN ioRec;"];
dest ← TS.CurOutNode[job.to];
TS.EndNode[job.to];
job.to.PutRope["END;"];
TS.ChangeDepth[job.to, -1];
TS.CopyChildren[from: cs.parent, to: dest];
job.to.PutRope["END;"];
TS.ChangeDepth[job.to, -1];
END;
WriteExpand: PROC [job: Job, name: ROPE, ec: LORA, cellDef: CellDef] =
BEGIN
TS.EndNode[job.to];
job.to.PutF["%gExpand: ExpandProc = {", IO.rope[name]];
TS.ChangeDepth[job.to, 1];
IF cellDef.initDataGiven THEN
BEGIN
job.to.PutF["initRef: %gInitRef ← NARROW[initData];", IO.rope[name]];
TS.ChangeDepth[job.to, 1];
job.to.PutRope["BEGIN OPEN initRef;"];
TS.EndNode[job.to];
END;
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];
a: Application => WriteCellInstance[job, b.name, a];
r: ROPE => WriteWhateverInstance[job, b.name, r];
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.initDataGiven THEN
BEGIN
job.to.PutRope["END;"];
TS.ChangeDepth[job.to, -1];
END;
job.to.PutRope["};"]; TS.ChangeDepth[job.to, -1];
END;
InjectCedar: 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;
WriteNodeInstance: PROC [job: Job, name: ROPE, st: SignalType] =
BEGIN
roseType: ROPE;
ne: nodeEntry ← NEW [SymbolTableEntryRep[node] ← [name: name, value: node[st]]];
IF job.things.Lookup[name] = NIL THEN job.things.Insert[ne]
ELSE Whimper[job, "node %g multiply defined", IO.rope[name]];
[, roseType, ] ← st.procs.Info[st.data];
job.to.PutF["%g: Node ← CreateNode[within: thisCell, name: \"%g\", type: %g];", IO.rope[name], IO.rope[name], IO.rope[roseType]];
TS.EndNode[job.to];
END;
UseSignalType: PROC [job: Job, st: SignalType] =
BEGIN
c: REF ANY ← st.procs.Cannonize[st.data];
ce: REF ANYNARROW[job.used.Lookup[c]];
IF ce = NIL THEN
BEGIN
md: ROPE ← st.procs.MesaTypeDecl[st.data];
job.used.Insert[c];
IF md # NIL THEN
{job.typeStream.PutRope[md]; job.typeStream.PutRope[";"]; TS.EndNode[job.typeStream]};
END;
END;
TypeCheck: PROC [job: Job, args: REF ANY, interface: DigestedInterface, instanceName: ROPE] =
BEGIN
Check: PROC [keyword: ROPE, match: InterfaceElt, value: REF ANY] =
BEGIN
Descr: PROC RETURNS [r: ROPE] = {
r ← IF keyword = NIL
THEN IO.PutFR["%g#%g", IO.rope[instanceName], IO.card[index]]
ELSE IO.PutFR["%g.%g", IO.rope[instanceName], IO.rope[keyword]]};
ste: SymbolTableEntry;
valName: ROPE;
valNode: nodeEntry;
IF match = NIL AND keyword # NIL THEN
BEGIN
match ← NARROW[interface.asTable.Lookup[keyword]];
IF match = NIL THEN Whimper[job, "%g not a valid port on cell %g", IO.rope[keyword], IO.rope[instanceName]];
END;
WITH value SELECT FROM
r: ROPE => valName ← r;
ENDCASE => {Whimper[job, "%g should be bound to an ID, not %g", IO.rope[Descr[]], IO.refAny[value]]; RETURN};
ste ← NARROW[job.things.Lookup[valName]];
WITH ste SELECT FROM
ne: nodeEntry => valNode ← ne;
ENDCASE => {Whimper[job, "%g was bound to %g, which should have been a node, rather than %g", IO.rope[Descr[]], IO.rope[valName], IO.refAny[ste]]; RETURN};
IF match = NIL THEN RETURN;
IF match.spare THEN Whimper[job, "%g.%g specified twice", IO.rope[instanceName], IO.rope[match.name]]
ELSE match.spare ← TRUE;
IF match.sti.st.procs.Cannonize[match.sti.st.data] # valNode.signalType.procs.Cannonize[valNode.signalType.data] THEN
BEGIN
Whimper[job,
"Type mismatch for %g: got %g when expecting %g",
IO.rope[Descr[]],
IO.rope[valNode.signalType.procs.Describe[valNode.signalType.data]],
IO.rope[match.sti.st.procs.Describe[match.sti.st.data]]];
END;
END;
toMatch: InterfaceEltList ← interface.asList;
index: CARDINAL ← 0;
FOR iel: InterfaceEltList ← interface.asList, iel.rest WHILE iel # NIL DO
iel.first.spare ← FALSE;
ENDLOOP;
WITH args SELECT FROM
bl: BindingList => FOR bl ← bl, bl.rest WHILE bl # NIL DO
index ← index + 1;
Check[bl.first.name, NIL, bl.first.value];
ENDLOOP;
a: Args => BEGIN
l: LIST OF Arg;
FOR l ← a.args, l.rest WHILE l # NIL AND toMatch # NIL DO
index ← index + 1;
Check[NIL, toMatch.first, l.first];
toMatch ← toMatch.rest;
ENDLOOP;
IF l # NIL --OR toMatch # NIL-- THEN Whimper[job, "too many parameters to %g", IO.rope[instanceName]];
END;
ENDCASE => ERROR;
index ← 0;
FOR iel: InterfaceEltList ← interface.asList, iel.rest WHILE iel # NIL DO
index ← index + 1;
IF NOT iel.first.spare THEN
--old: Whimper[job, "%g.%g never specified", IO.rope[instanceName], IO.rope[iel.first.name]];--
--new:-- Check[iel.first.name, iel.first, iel.first.name];
ENDLOOP;
END;
WriteCellInstance: PROC [job: Job, instanceName: ROPE, a: Application] =
BEGIN
ste: SymbolTableEntry ← NARROW[job.things.Lookup[a.fn]];
cd: CellDef;
definedIn: ROPE;
fromSelf: BOOLEAN;
IF ste = NIL THEN
BEGIN
[] ← Complain[job, "Cell Class %g undefined!", IO.rope[a.fn]];
cd ← NEW [CellDefRep ← []]; definedIn ← NIL;
IF a.fn # NIL THEN AddCellClass[job, NEW [SymbolTableEntryRep[cellClass] ← [name: a.fn, value: cellClass[definedIn: definedIn, cd: cd]]]];
END
ELSE WITH ste SELECT FROM
cce: ccEntry => {definedIn ← cce.definedIn; cd ← cce.cd};
ENDCASE => BEGIN
[] ← Complain[job, "Can't instantiate %g like a Cell Class", IO.refAny[ste]];
definedIn ← NIL;
cd ← NEW [CellDefRep ← []];
END;
fromSelf ← definedIn.Equal[job.rootName, FALSE];
job.to.PutF["[] ← CreateCell[within: thisCell, instanceName: \"%g\", className: \"%g\", interfaceNodes: ", IO.rope[instanceName], IO.rope[a.fn]];
IF definedIn # NIL THEN TypeCheck[job, a.args, cd.interface, 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"];
IF a.initData # NIL THEN job.to.PutF[", initData: %g", IO.rope[a.initData]]
ELSE IF cd.initDataGiven AND cd.initializerGiven THEN
BEGIN
IF cd.defaultInitExprGiven THEN
BEGIN
job.to.PutF[", initData: %g", IO.rope[cd.defaultInitExpr]];
END
ELSE Whimper[job, "%g must be given init data", IO.rope[instanceName]];
END;
job.to.PutRope["];"];
TS.EndNode[job.to];
IF definedIn # NIL AND NOT fromSelf THEN AddImport[job, definedIn];
END;
WriteWhateverInstance: PROC [job: Job, name: ROPE, class: ROPE] =
BEGIN
sti: SignalTypeInvocation ← InstantiateSignalType[job, class, NIL];
IF sti # NIL THEN WriteNodeInstance[job, name, sti.st];
END;
WritePorts: PROC [job: Job, name: ROPE, count: CARDINAL] =
BEGIN
TS.EndNode[job.to];
job.to.PutF["%gPorts: Ports ← NEW [PortsRep[%g]];", IO.rope[name], IO.card[count]];
TS.EndNode[job.to];
END;
WriteRegistration: PROC [job: Job, name: ROPE, cellDef: CellDef] =
BEGIN
IF cellDef.interface.asList # NIL THEN
BEGIN
job.regStream.PutF["Create%gPorts[];", IO.rope[name]];
TS.EndNode[job.regStream];
END;
job.regStream.PutF["RegisterCellClass[className: \"%g\",", IO.rope[name]];
TS.ChangeDepth[job.regStream, 1];
IF cellDef.expandGiven THEN job.regStream.PutF["expandProc: %gExpand,", IO.rope[name]] ELSE job.regStream.PutRope["expandProc: NIL,"];
TS.EndNode[job.regStream];
IF cellDef.interface.asList # NIL THEN job.regStream.PutF["ioCreator: Create%gIO,", IO.rope[name]] ELSE job.regStream.PutRope["ioCreator: NIL,"];
IF cellDef.stateGiven OR cellDef.initializerGiven THEN job.regStream.PutF["initializer: Initialize%g,", IO.rope[name]] ELSE job.regStream.PutRope["initializer: NIL,"];
TS.EndNode[job.regStream];
IF cellDef.evalGiven THEN job.regStream.PutF["evalProc: %gEval,", IO.rope[name]] ELSE job.regStream.PutRope["evalProc: NIL,"];
IF cellDef.testGiven THEN job.regStream.PutF["testProc: %gTest,", IO.rope[name]] ELSE job.regStream.PutRope["testProc: NIL,"];
TS.EndNode[job.regStream];
IF cellDef.interface.asList # NIL THEN
BEGIN
job.regStream.PutF["ioTemplate: NEW [%gIORec],", IO.rope[name]];
END
ELSE BEGIN
job.regStream.PutRope["ioTemplate: NIL,"];
END;
TS.EndNode[job.regStream];
job.regStream.PutF["ports: %gPorts];", IO.rope[name]];
TS.ChangeDepth[job.regStream, -1];
END;
WriteDeps: PROC [job: Job] =
BEGIN
WriteDep: PROC [asAny: REF ANY] RETURNS [stop: BOOLEAN] =
BEGIN
depName: ROPENARROW[asAny];
depFile.PutRope[" "];
depFile.PutRope[depName];
stop ← FALSE;
END;
WriteLoad: PROC [asAny: REF ANY] RETURNS [stop: BOOLEAN] =
BEGIN
depName: ROPENARROW[asAny];
cmFile.PutF["@%g.roseLoad\n", IO.rope[depName]];
stop ← FALSE;
END;
depFile: IO.STREAM ← FileIO.Open[fileName: job.rootName.Concat[".RoseDeps"], accessOptions: overwrite];
cmFile: IO.STREAM ← FileIO.Open[fileName: job.rootName.Concat[".roseLoad"], accessOptions: overwrite];
job.libbed.EnumerateIncreasing[WriteDep];
job.libbed.EnumerateIncreasing[WriteLoad];
depFile.PutRope[" ; "];
job.directory.EnumerateIncreasing[WriteDep];
depFile.Close[];
cmFile.PutF["runnew %g\n", IO.rope[job.rootName]];
cmFile.Close[];
END;
END.