RoseTranslateRandoms.Mesa
Last Edited by: Spreitzer, May 10, 1984 4:49:41 pm PDT PDT PDT
DIRECTORY
Atom, BasicTime, Commander, FS, IO, IOClasses, OrderedSymbolTableRef, PutGet, Rope, RoseTranslateTypes, RoseTranslateInsides, SignalTypeRegistration, TextNode, TiogaFileOps, TiogaOps, TiogaStreams, UserCredentials, ViewerClasses, ViewerOps, ViewerTools;
RoseTranslateRandoms: CEDAR PROGRAM
IMPORTS Atom, BasicTime, Commander, FS, IO, IOClasses, OSTR: OrderedSymbolTableRef, PutGet, Rope, SignalTypeRegistration, TFO: TiogaFileOps, TiogaOps, TS: TiogaStreams, RoseTranslateInsides, UserCredentials, ViewerOps, ViewerTools
EXPORTS RoseTranslateTypes, RoseTranslateInsides =
BEGIN OPEN RoseTranslateTypes, RoseTranslateInsides;
TypeConstructionError: PUBLIC ERROR [msg: ROPE] = CODE;
Circularity: PUBLIC ERROR = CODE;
error: PUBLIC REF ANYNEW [ROPE ← "error"];
noDefault: PUBLIC REF ANYNEW [ROPE ← "no default"];
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;
ForceMesaType: PUBLIC PROC [mesaType: ROPE, on: NodeType] RETURNS [forced: NodeType] =
BEGIN
ERROR; --no longer supported
END;
TranslateCmd: Commander.CommandProc --PROC [cmd: Handle] RETURNS [result: REF ← NIL, msg: Rope.ROPE ← NIL]-- =
BEGIN
commandLineStream: IO.STREAMIO.RIS[cmd.commandLine];
[] ← commandLineStream.SkipWhitespace[flushComments: FALSE];
WHILE NOT commandLineStream.EndOf[] DO
name: ROPE ← commandLineStream.GetTokenRope[IO.IDProc].token;
errs: CARDINAL ← 1;
errs ← Translate[cmd, name, NIL, TranslateJob !Circularity => CONTINUE];
IF errs > 0 THEN RETURN [$Failure];
[] ← commandLineStream.SkipWhitespace[flushComments: FALSE];
ENDLOOP;
END;
Translate: PUBLIC PROC [exec: Commander.Handle, rootName: ROPE, pathIn: LIST OF ROPE, type: JobType] RETURNS [errCount: CARDINAL] = TRUSTED
BEGIN
inRoot: TextNode.Ref ← NIL;
job: Job ← NEW [JobRep ← [
exec: exec,
rootName: rootName,
path: CONS[rootName, pathIn],
outRoot: TFO.CreateRoot[],
symbolsRoot: TFO.CreateRoot[],
directory: OSTR.CreateTable[CompareRopes],
imports: OSTR.CreateTable[CompareRopes],
opened: OSTR.CreateTable[CompareRopes],
libbed: OSTR.CreateTable[CompareRopes],
things: OSTR.CreateTable[SignalTypeRegistration.CompareSymbolTableEntries],
used: OSTR.CreateTable[CompareRefAnies],
type: type,
start: BasicTime.GetClockPulses[]]];
logFile: IO.STREAM;
sourceName, logName: ROPE;
inRoot ← PutGet.FromFile[sourceName ← rootName.Concat[".Rose"] !FS.Error =>
BEGIN
viewerLog.PutF["\nOpen failed on %g\n", IO.rope[sourceName]];
inRoot ← NIL;
CONTINUE;
END];
IF inRoot = NIL THEN RETURN [1];
job.from ← TS.CreateInput[inRoot];
job.to ← TS.CreateOutput[job.outRoot, "code"];
job.symbolsStream ← TS.CreateOutput[job.symbolsRoot];
logFile ← FS.StreamOpen[fileName: logName ← rootName.Concat[".log"], accessOptions: create];
job.log ← IOClasses.CreateDribbleOutputStream[logFile, viewerLog];
Open[job, sourceName];
[job.parseTree, ] ← ParseExpression[job, FALSE];
Close[job];
logFile.Close[];
viewerLog.PutRope["Done.\n\n"];
errCount ← job.errCount;
END;
Open: PROC [job: Job, sourceName: ROPE] = TRUSTED
BEGIN
job.log.PutF["\nTranslating %g into %g.Mesa, log on %g.Log\n", IO.rope[sourceName], IO.rope[job.rootName], IO.rope[job.rootName]];
job.to.PutF["--%g.Mesa", IO.rope[job.rootName]]; TS.EndNode[job.to];
job.to.PutF["--created by RoseTranslate from %g of %g for %g at %g", IO.rope[sourceName], IO.time[FS.FileInfo[sourceName].created], IO.rope[UserCredentials.Get[].name], IO.time[]]; TS.EndNode[job.to];
TS.EndNode[job.to];
TS.EndNode[job.to];
job.to.PutRope["DIRECTORY"];
job.directoryStream ← TS.CreateOutput[TS.CurOutNode[job.to], "code"];
TS.EndNode[job.to];
TS.EndNode[job.to];
job.to.PutF["%g: CEDAR PROGRAM", IO.rope[job.rootName]];
job.importsStream ← TS.CreateOutput[TS.CurOutNode[job.to], "code"];
job.importsStream.PutRope["IMPORTS "];
TS.EndNode[job.to];
TS.EndNode[job.to];
job.to.PutRope["BEGIN OPEN"];
job.openStream ← TS.CreateOutput[TS.CurOutNode[job.to], "code"];
TS.EndNode[job.to];
TS.EndNode[job.to];
job.to.PutRope["--Signal Type decls"];
job.typeStream ← TS.CreateOutput[TS.CurOutNode[job.to], "code"];
TS.EndNode[job.to];
TS.EndNode[job.to];
job.to.PutRope["RegisterCells: PROC ="];
job.regStream ← TS.CreateOutput[TS.CurOutNode[job.to], "code"];
TS.EndNode[job.to];
job.regStream.PutRope["BEGIN"]; TS.EndNode[job.regStream];
AddOpen[job, "RoseTypes"];
AddImport[job, "RoseCreate"];
END;
TypeCheck: PUBLIC 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 # valNode.nodeType THEN
BEGIN
Whimper[job,
"Type mismatch for %g: got %g when expecting %g",
IO.rope[Descr[]],
IO.rope[valNode.nodeType.procs.UserDescription[valNode.nodeType]],
IO.rope[match.sti.st.procs.UserDescription[match.sti.st]]];
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;
DoMesaFormatting: PROC [fileName: ROPE] = TRUSTED
BEGIN
check: ATOM ← Atom.MakeAtom[fileName];
asAny: REF ANY ← Atom.GetProp[atom: check, prop: $mjsMesaFmtCheck];
ri: REF INT;
v: ViewerClasses.Viewer;
viewerName: ROPE;
IF asAny = NIL THEN Atom.PutProp[atom: check, prop: $mjsMesaFmtCheck, val: asAny ← ri ← NEW [INT ← 0]] ELSE ri ← NARROW[asAny];
ri^ ← ri^ + 1;
viewerName ← IF ri^ = 1 THEN fileName ELSE IO.PutFR["%g!%g", IO.rope[fileName], IO.int[ri^]];
v ← ViewerTools.MakeNewTextViewer[info: [name: viewerName, file: fileName, iconic: FALSE]];
TiogaOps.SelectDocument[v];
TiogaOps.MesaFormatting[];
END;
Complain: PUBLIC PROC [context: REF ANY, complaint: ROPE, v1, v2, v3, v4, v5: IO.Value ← [null[]]] RETURNS [reduced: REF ANY] =
BEGIN
job: Job ← NARROW[context];
job.log.PutF["Somewhere before %g: ", IO.int[job.from.GetIndex[]]];
job.log.PutF[complaint.Concat["\n"], v1, v2, v3, v4, v5];
job.errCount ← job.errCount + 1;
reduced ← error;
END;
Whimper: PUBLIC PROC [context: REF ANY, complaint: ROPE, v1, v2, v3, v4, v5: IO.Value ← [null[]]] =
BEGIN
job: Job ← NARROW[context];
job.log.PutF["Somewhere before %g: ", IO.int[job.from.GetIndex[]]];
job.log.PutF[complaint.Concat["\n"], v1, v2, v3, v4, v5];
job.warnCount ← job.warnCount + 1;
END;
CompareRopes: OSTR.CompareProc = {RETURN [Rope.Compare[NARROW[r1], NARROW[r2]]]};
CompareRefAnies: OSTR.CompareProc =
BEGIN
c1: LONG CARDINALLOOPHOLE[r1];
c2: LONG CARDINALLOOPHOLE[r2];
RETURN [IF c1 < c2 THEN less ELSE IF c1 > c2 THEN greater ELSE equal];
END;
Setup: PROC =
BEGIN
Commander.Register["RoseTranslate", TranslateCmd, "Translates rosemary sources (.Rose) into Mesa files"];
END;
Setup[];
END.