C2CAndMimosaImpl.mesa
Copyright Ó 1990, 1991, 1993 by Xerox Corporation. All rights reserved.
Christian Jacobi, October 4, 1990 12:00:47 pm PDT
Christian Jacobi, January 25, 1993 7:15 pm PST
Willie-s, September 24, 1991 6:13 pm PDT
This module hooks C2C into Mimosa.
It basically
registers a a code generation procedure into mimosa,
interpretes the switches
and calls C2CAccess.
DIRECTORY
Ascii,
CardTab,
C2CAccess,
IntCodeDefs,
IntCodeGen,
IO,
MimSysOps,
RefText,
Rope;
C2CAndMimosaImpl: CEDAR PROGRAM
IMPORTS C2CAccess, IntCodeGen, MimSysOps, RefText, Rope =
BEGIN
outputExtension: Rope.ROPE ¬ ".c2c.c";
externProcsExtension: Rope.ROPE ¬ ".externProcs";
--these switches are used for the mimosa command (not for the C2C command)
debugSwitchKey: CHAR = 'd;
oldCExtSwitchKey: CHAR = 'c;
floatInlineSwitchKey: CHAR = 'f;
leaveGarbageSwitchKey: CHAR = 'g;
xLFSwitchKey: CHAR = 'l;
referenceCountKey: CHAR = 'q;
lineNumberSwitchKey: CHAR = 'v;
dbxLineNumberSwitchKey: CHAR = 'a;
externProcsSwitchKey: CHAR = 'r;
outerSwitchKey: CHAR = 'o;
debuggingCodeCheckingSwitchKey: CHAR = 't;
globalErrorStream: IO.STREAM; --used within re-entry lock
globalName: Rope.ROPE; --used within re-entry lock
CreateErrStream: PROC [] RETURNS [err: IO.STREAM] = {
errMsg: Rope.ROPE;
err ¬ globalErrorStream;
IF err=NIL THEN {
[stream: err, err: errMsg] ¬ MimSysOps.Open[name: Rope.Concat[globalName, ".errlog"], kind: write];
IF errMsg#NIL THEN ERROR;
globalErrorStream ¬ err;
};
};
SwitchesToRope: PROC [switches: PACKED ARRAY CHAR['a..'z] OF BOOL] RETURNS [Rope.ROPE ¬ NIL] = {
x: REF TEXT ¬ RefText.New[24];
FOR c: CHAR IN ['a..'z] DO
IF switches[c] THEN x ¬ RefText.AppendChar[x, c];
ENDLOOP;
RETURN [Rope.FromRefText[x]]
};
GenerateCodeFromMimosa: IntCodeGen.CodeGenerator
[fileName: Rope.ROPE,
moduleName: Rope.ROPE,
versionStamp: Rope.ROPE,
root: IntCodeDefs.Node,
names: CardTab.Ref,
labels: CardTab.Ref,
data: REF ANY,
switches: PACKED ARRAY CHAR['a..'z] OF BOOL]
RETURNS [msg: Rope.ROPE ← NIL]
= {
params: C2CAccess.InputParameters ¬ [];
ok: BOOL;
synopsis: Rope.ROPE;
line: Rope.ROPE;
errMsg: Rope.ROPE ¬ NIL;
Msg: PROC [r: Rope.ROPE] = {IF r#NIL THEN msg ¬ Rope.Cat[msg, r, "\n"]};
Inner: PROC [] = {
--Set up for CreateErrStream; note we have re-entry lock
globalErrorStream ¬ NIL;
globalName ¬ moduleName;
params.getErrorStream ¬ CreateErrStream;
--
params.moduleName ¬ moduleName;
params.versionStamp ¬ versionStamp;
params.fileName ¬ fileName;
params.root ¬ root;
params.supportInlineFloatingPoint ¬ switches[floatInlineSwitchKey];
params.supportReferenceCounting ¬ switches[referenceCountKey];
params.debuggingMode ¬ switches[debugSwitchKey];
params.destroyRoot ¬ ~ switches[leaveGarbageSwitchKey];
params.names ¬ names;
params.labels ¬ labels;
line ¬ Rope.Concat["switches: ", SwitchesToRope[switches]];
params.commentLines ¬ CONS[line, params.commentLines];
params.lineTerminationChar ¬ IF switches[xLFSwitchKey] THEN Ascii.LF ELSE Ascii.CR;
IF switches[externProcsSwitchKey] THEN {
xpStream: IO.STREAM;
externProcsName: Rope.ROPE ¬ Rope.Concat[fileName, externProcsExtension];
[stream: xpStream, err: errMsg] ¬ MimSysOps.Open[name: externProcsName, kind: read];
IF errMsg#NIL THEN {Msg[errMsg]; GOTO Oops};
IF xpStream=NIL THEN {Msg["names file not opened"]; GOTO Oops};
params.namesStream ¬ xpStream
};
params.debuggingCode ¬ switches[debuggingCodeCheckingSwitchKey];
BEGIN
outputName: Rope.ROPE ¬ Rope.Concat[fileName, IF switches[oldCExtSwitchKey] THEN outputExtension ELSE ".c"];
[stream: params.outputStream, err: errMsg] ¬ MimSysOps.Open[name: outputName, kind: write];
IF errMsg#NIL THEN {Msg[errMsg]; GOTO Oops};
IF params.outputStream=NIL THEN {Msg["output file not created"]; GOTO Oops};
END;
IF switches[lineNumberSwitchKey] THEN {
lineFileName: Rope.ROPE ¬ Rope.Concat[fileName, ".c2c.lines"];
[stream: params.lineNumberStream, err: errMsg] ¬ MimSysOps.Open[name: lineFileName, kind: write];
IF errMsg#NIL THEN {Msg[errMsg]; GOTO Oops};
IF params.lineNumberStream=NIL THEN {
Msg[Rope.Concat[lineFileName, " not created"]]; GOTO Oops
};
params.generateLineNumberStream ¬ TRUE;
params.generateSourceMacros ¬ FALSE;
params.generateDBXStyleSourceMacros ¬ FALSE;
}
ELSE IF switches[dbxLineNumberSwitchKey] THEN {
params.generateLineNumberStream ¬ FALSE;
params.generateSourceMacros ¬ TRUE;
params.generateDBXStyleSourceMacros ¬ TRUE;
};
[ok, synopsis] ¬ C2CAccess.CallC2C[params];
IF globalErrorStream#NIL THEN {
[] ¬ MimSysOps.Close[globalErrorStream];
globalErrorStream ¬ NIL;
};
IF ~ok THEN {
[] ¬ MimSysOps.Close[params.outputStream, TRUE];
Msg[synopsis]; GOTO Oops
};
errMsg ¬ MimSysOps.Close[params.outputStream];
IF errMsg#NIL THEN {Msg[errMsg]; GOTO Oops};
EXITS Oops => {
IF msg=NIL
THEN msg ¬ "code generation failed"
ELSE msg ¬ Rope.Concat["code generation failed: ", msg];
};
};
C2CAccess.ExcludeReEntry[Inner];
};
IntCodeGen.RegisterCodeGenerator[GenerateCodeFromMimosa, NIL];
END.