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 ANY ← NEW [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: BOOLEAN ← TRUE;
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: BOOLEAN ← TRUE;
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: BOOLEAN ← TRUE;
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 ANY ← NARROW[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: ROPE ← NARROW[asAny];
depFile.PutRope[" "];
depFile.PutRope[depName];
stop ← FALSE;
END;
WriteLoad:
PROC [asAny:
REF
ANY]
RETURNS [stop:
BOOLEAN] =
BEGIN
depName: ROPE ← NARROW[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.