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 ANY ← NEW [ROPE ← "error"];
noDefault: PUBLIC REF ANY ← NEW [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.STREAM ← IO.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 CARDINAL ← LOOPHOLE[r1];
c2: LONG CARDINAL ← LOOPHOLE[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.