<<>> <> <> <> <> <> <> <<>> <> <> <> <> 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; <> << 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.