DIRECTORY Basics: TYPE USING [DIVMOD, LongDivMod], BasicTime: TYPE USING [GMT, Now, Period], Commander: TYPE USING [Handle, Register], CommandUtil: TYPE USING [ PairList, Echo, Failed, GetNth, ListLength, Parse, SetExtension], CompilerOps: TYPE USING [ LetterSwitches, StreamId, Transaction, AppendHerald, DefaultSwitches, DoTransaction, Punt, Start, Stop], FileIO: TYPE USING [StreamFromOpenFile], FileParms: TYPE USING [BindingProc, nullActual], FileParmOps: TYPE USING [ClearAList, Finalize, Initialize, SetAList], FS: TYPE USING [Close, EnumerateForInfo, InfoProc, nullOpenFile, OpenFile], IO: TYPE USING [card, Close, int, Put, PutChar, PutF, PutRope, rope, SetLength, STREAM, time, UserAborted], OSMiscOps: TYPE USING [DeleteFile, FindFile], Rope: TYPE USING [Fetch, Find, Length, ROPE, Substr], TimeStamp: TYPE USING [Null], UnsafeStorage: TYPE USING [NewUZone, FreeUZone]; Interface: PROGRAM [] IMPORTS Basics, BasicTime, Commander, CommandUtil, CompilerOps, FileIO, FileParmOps, FS, IO, OSMiscOps, Rope, UnsafeStorage EXPORTS = { StreamHandle: TYPE = IO.STREAM; log: StreamHandle _ NIL; useLog: BOOL; -- for compiler.log for error reporting SetTypescript: PROC = {IF log = NIL THEN log _ NewOutputStream["Compiler.Log"]}; NewLine: PROC = {log.PutRope["\n"]}; NewOutputStream: PROC [s: Rope.ROPE] RETURNS [stream: StreamHandle] = { file: FS.OpenFile; file _ OSMiscOps.FindFile[s, write]; stream _ FileIO.StreamFromOpenFile[file]; IO.SetLength[stream, 0]}; NewInputStream: PROC [s: Rope.ROPE] RETURNS [file: FS.OpenFile, stream: StreamHandle, createTime: BasicTime.GMT] = { GetCreated: FS.InfoProc = TRUSTED {createTime _ created; RETURN[continue: TRUE]}; file _ OSMiscOps.FindFile[s, read]; FS.EnumerateForInfo[s, GetCreated]; stream _ FileIO.StreamFromOpenFile[file]}; WriteHerald: PROC [s: StreamHandle, id: Rope.ROPE] = { CompilerOps.AppendHerald[s]; IO.PutRope[s, " (Pilot Version)/n"]; IF id # NIL THEN {IO.Put[s, IO.rope[id], IO.rope[" -- "]]}; IO.Put[s, IO.time[], IO.rope["/n"]]}; WriteTime: PROC [time: LONG CARDINAL] = { hr, min, sec: CARDINAL; [min, sec] _ Basics.LongDivMod[time, 60]; [hr, min] _ Basics.DIVMOD[min, 60]; SELECT TRUE FROM hr # 0 => log.PutF["%d:%02d:%02d", IO.card[hr], IO.card[min], IO.card[sec]]; min # 0 => log.PutF["%d:%02d", IO.card[min], IO.card[sec]]; ENDCASE => log.PutF["%d", IO.card[sec]]}; ObjectInit: PROC = { IF objectStream = NIL THEN objectStream _ NewOutputStream[objectName]}; ErrorInit: PROC = { IF errorStream = NIL THEN IF useLog THEN errorStream _ log ELSE { errorName _ MakeErrorName[rootName]; errorStream _ NewOutputStream[errorName]; WriteHerald[errorStream, errorName]; IO.PutChar[errorStream, '\n]}}; MakeErrorName: PROC [root: Rope.ROPE] RETURNS [Rope.ROPE] = { RETURN [CommandUtil.SetExtension[root, "errlog"]]}; GetStream: PROC [id: CompilerOps.StreamId] RETURNS [s: IO.STREAM] = { SELECT id FROM source => s _ sourceStream; object => {IF objectStream = NIL THEN ObjectInit[]; s _ objectStream}; log => {IF errorStream = NIL THEN ErrorInit[]; s _ errorStream}; ENDCASE => ERROR; RETURN}; Initialize: PROC = { created: BasicTime.GMT; [sourceFile, sourceStream, created] _ NewInputStream[sourceName]; parms.sourceStream _ sourceStream; parms.source.version _ TimeStamp.Null; parms.source.version.time _ LOOPHOLE[created]}; Finalize: PROC [started: BOOL] = { IF objectStream # NIL THEN IO.Close[objectStream]; IF sourceStream # NIL THEN IO.Close[sourceStream]; IF errorStream # NIL AND errorStream # log THEN IO.Close[errorStream]; objectStream _ sourceStream _ errorStream _ NIL; IF sourceFile # FS.nullOpenFile THEN FS.Close[sourceFile]; sourceFile _ FS.nullOpenFile; IF parms.nErrors # 0 AND started THEN OSMiscOps.DeleteFile[objectName]; IF errorName = NIL THEN { errorName _ MakeErrorName[rootName]; OSMiscOps.DeleteFile[errorName]}}; WriteErrlogName: PROC = { IF useLog OR log = NIL THEN RETURN; IO.PutRope[log, " on "]; IO.PutRope[log, rootName]; IO.PutRope[log, ".errlog"]}; WriteClosing: PROC [cmdr: Commander.Handle, startTime: BasicTime.GMT] = { OPEN IO; elapsed: BasicTime.GMT; Put[log, rope[sourceName], rope[" -- "]]; elapsed _ LOOPHOLE[BasicTime.Period[BasicTime.Now[], startTime]]; IF parms.nErrors # 0 THEN { errors _ TRUE; Put[log, rope["aborted, "], int[parms.nErrors], rope["errors"]]; IF parms.nWarnings # 0 THEN { warnings _ TRUE; Put[log, rope[" and "], int[parms.nWarnings], rope[" warnings"]]}; WriteErrlogName[]; Put[log, rope[", time: "], time[elapsed]]} ELSE { Put[log, rope["source tokens: "], int[parms.sourceTokens]]; Put[log, rope[", time: "], time[elapsed]]; IF parms.objectBytes # 0 THEN { Put[log, rope["\n code bytes: "], int[parms.objectBytes]]; Put[log, rope[", links: "], int[parms.linkCount]]; Put[log, rope[", frame size: "], int[parms.objectFrameSize]]; IF parms.matched THEN PutChar[log, '.]}; IF parms.nWarnings # 0 THEN { warnings _ TRUE; NewLine[]; Put[log, int[parms.nWarnings], rope[" warnings"]]; WriteErrlogName[]}}; IF parms.nErrors = 0 THEN cmdr.out.PutRope["no errors"] ELSE cmdr.out.Put[IO.int[parms.nErrors], IO.rope[" errors"]]; IF parms.nWarnings # 0 THEN cmdr.out.Put[IO.rope[", "], IO.int[parms.nWarnings], IO.rope[" warnings"]]; cmdr.out.PutRope["/n"]}; StopCompiler: PROC [cmdr: Commander.Handle, startTime: BasicTime.GMT] = { elapsed: BasicTime.GMT; cmdr.out.PutRope["End of compilation/n"]; elapsed _ LOOPHOLE[BasicTime.Period[BasicTime.Now[], startTime]]; IF moduleCount > 1 THEN IO.Put[log, IO.rope["\nTotal elapsed time: "], IO.time[elapsed]]; NewLine[]; IO.Close[log]; log _ NIL}; parms: REF CompilerOps.Transaction = NEW[CompilerOps.Transaction]; standardDefaults: CompilerOps.LetterSwitches = CompilerOps.DefaultSwitches[]; switchDefaults: CompilerOps.LetterSwitches; sourceName, objectName, errorName: Rope.ROPE _ NIL; rootName: Rope.ROPE _ NIL; sourceFile: FS.OpenFile _ FS.nullOpenFile; sourceStream, objectStream, errorStream: StreamHandle _ NIL; errors, warnings: BOOL _ FALSE; moduleCount: CARDINAL; SetRoot: PROC [s: Rope.ROPE] RETURNS [root: Rope.ROPE] = { dotIndex: INT _ Rope.Find[s, "."]; RETURN[IF dotIndex > -1 THEN Rope.Substr[s, 0, dotIndex] ELSE s]}; Compile: SAFE PROC [cmdr: Commander.Handle] = TRUSTED { StartPass: PROC [pass: CARDINAL] RETURNS [goOn: BOOL] = { cmdr.out.PutRope[" ."]; userAbort _ cmdr.in.UserAborted[]; IF userAbort THEN cmdr.out.PutRope[" aborted."]; RETURN [~userAbort]}; userAbort: BOOL; -- set by ^DEL compilerStartTime, moduleStartTime: BasicTime.GMT; scratchZone: UNCOUNTED ZONE _ UnsafeStorage.NewUZone[]; switchDefaults _ CompilerOps.DefaultSwitches[]; parms.fileParms _ FileParmOps.Initialize[scratchZone]; CompilerOps.Start[scratchZone]; compilerStartTime _ BasicTime.Now[]; moduleCount _ 0; userAbort _ FALSE; SetTypescript[]; WriteHerald[log, NIL]; errors _ warnings _ FALSE; DO first: BOOL _ TRUE; args, results: CommandUtil.PairList; switches: Rope.ROPE _ NIL; localPause: BOOL; sense: BOOL; BEGIN parms.switches _ switchDefaults; parms.switches['p] _ FALSE; parms.debugPass _ CARDINAL.LAST; parms.getStream _ GetStream; parms.startPass _ StartPass; parms.objectBytes _ 0; parms.objectFrameSize _ 0; parms.linkCount _ 0; parms.nErrors _ 0; parms.nWarnings _ 0; parms.sourceTokens _ 0; [sourceName, args, results, switches] _ CommandUtil.Parse[command: cmdr.commandLine ! CommandUtil.Failed => {GO TO badSyntax}]; IF sourceName = NIL AND switches = NIL THEN EXIT; IO.PutRope[log, "\nCommand: "]; CommandUtil.Echo[log, sourceName, args, results, switches]; IF CommandUtil.ListLength[results] > 1 THEN GO TO badSemantics; IF sourceName = NIL THEN GO TO globalSwitches; rootName _ SetRoot[IF CommandUtil.ListLength[results] = 1 THEN CommandUtil.GetNth[results, 0] ELSE sourceName]; IF switches # NIL THEN { sense _ TRUE; FOR i: INT IN [0..switches.Length[]) DO c: CHAR = switches.Fetch[i]; SELECT c FROM '-, '~ => sense _ ~sense; IN ['a..'z] => {parms.switches[c] _ sense; sense _ TRUE}; IN ['A..'Z] => { parms.switches[VAL['a.ORD+(c.ORD-'A.ORD)]] _ sense; sense _ TRUE}; IN ['1..'5] => {parms.debugPass _ c-'0; sense _ TRUE}; ENDCASE; ENDLOOP}; sourceName _ CommandUtil.SetExtension[sourceName, "mesa"]; parms.source.locator _ sourceName; IF CommandUtil.ListLength[results] # 0 THEN { objectName _ CommandUtil.GetNth[list: results, n: 0, delete: TRUE]; results _ NIL} ELSE objectName _ rootName; parms.objectName _ CommandUtil.SetExtension[objectName, "bcd"]; parms.objectFile _ FS.nullOpenFile; moduleCount _ moduleCount + 1; cmdr.out.Put[IO.rope["Compiling: "], IO.rope[rootName]]; FOR c: CHAR IN ['a..'z] DO sd: BOOL = (IF c = 'p THEN FALSE ELSE standardDefaults[c]); IF parms.switches[c] # sd THEN { IF first THEN {first _ FALSE; cmdr.out.PutChar['/]}; IF sd THEN cmdr.out.PutChar['-]; cmdr.out.PutChar['c]}; ENDLOOP; useLog _ parms.switches['g]; parms.switches['g] _ FALSE; localPause _ parms.switches['p]; parms.switches['p] _ FALSE; Initialize[ ! ANY => {GOTO noSource}]; FileParmOps.SetAList[args]; BEGIN BindPattern: FileParms.BindingProc = { parms.pattern _ actual; parms.op _ IF actual = FileParms.nullActual THEN compile ELSE replace}; parms.fileParms.Binding[ formalId: "$", formalType: NIL, binder: BindPattern]; END; NewLine[]; moduleStartTime _ BasicTime.Now[]; CompilerOps.DoTransaction[parms ! CompilerOps.Punt => {GO TO punt}]; Finalize[TRUE]; FileParmOps.ClearAList[]; WriteClosing[cmdr, moduleStartTime]; EXITS globalSwitches => { objectName _ NIL; sense _ TRUE; FOR i: INT IN [0..switches.Length[]) DO c: CHAR = switches.Fetch[i]; SELECT c FROM '-, '~ => sense _ ~sense; IN ['a..'z] => {switchDefaults[c] _ sense; sense _ TRUE}; IN ['A..'Z] => { switchDefaults[VAL['a.ORD+(c.ORD-'A.ORD)]] _ sense; sense _ TRUE}; ENDCASE => EXIT; ENDLOOP}; noSource => { IO.Put[log, IO.rope[" -- source not found\n"], IO.time[]]; errors _ TRUE; parms.nErrors _ 1; args _ NIL}; badSemantics => { objectName _ NIL; errors _ TRUE; IO.PutRope[log, " -- Illegal command"]}; END; NewLine[]; IF userAbort THEN { IO.PutRope[log, "\n... command aborted\n"]; GO TO truncateList}; IF (errors OR warnings) AND localPause THEN GO TO truncateList; REPEAT badSyntax => { IO.PutRope[log, "\n-- Illegal syntax"]; errors _ TRUE}; truncateList => switchDefaults['p] _ TRUE; punt => {Finalize[TRUE]; WriteClosing[cmdr, moduleStartTime]; NewLine[]}; ENDLOOP; StopCompiler[cmdr, compilerStartTime]; CompilerOps.Stop[]; FileParmOps.Finalize[]; UnsafeStorage.FreeUZone[scratchZone]}; Commander.Register["Compiler", Compile, "Compile a list of modules."]; }. NInterface.mesa last modified by Satterthwaite, May 12, 1983 5:16 pm Last Edited by: Maxwell, August 29, 1983 11:04 am special output stream control compiler sequencing write to the Commander output file SELECT TRUE FROM userAbort => aborted, parms.nErrors # 0 => IF parms.nWarnings # 0 THEN errorsAndWarnings ELSE errors, parms.nWarnings # 0 => warnings, ENDCASE => ok; * * * * * * M A I N B O D Y C O D E * * * * * * do the compilation feedback pattern for replacement RETURN [SELECT TRUE FROM userAbort => aborted, errors => errors, warnings => warnings, ENDCASE => ok]}; Ê T˜Jšœ™Jšœ4™4J™1J˜šÏk ˜ Jšœœœœ˜(Jšœ œœœ˜)Jšœ œœ˜)šœ œœ˜J˜A—šœ œœ˜J˜&J˜A—Jšœœœ˜(Jšœ œœ˜0Jšœ œœ.˜EJšœœœ=˜KJšœœœBœ˜kJšœ œœ˜-Jšœœœœ ˜5Jšœ œœ˜Jšœœœ˜0J˜—šœ œ˜š˜JšœMœ˜QJšœ ˜"—Jšœ˜ J˜J˜—Jšœ™˜Jšœœœœ˜Jšœœ˜JšœœÏc'˜6J˜Jš Ïn œœœœœ(˜PJ˜JšŸœœ˜$J˜šŸœœ œœ˜GJšœœ ˜Jšœ$˜$J˜)Jšœ˜J˜—šŸœœ œ˜$Jšœœ7œ˜PJš œ œ œœ œ˜QJšœ#˜#Jšœ!˜#Jšœ*˜*J˜—šŸ œœœ˜6Jšœ˜Jšœ"˜$Jš œœœœœ œ˜;Jšœœ œ˜%J˜—šŸ œœœœ˜)Jšœœ˜J˜)Jšœœ ˜#šœœ˜Jšœ#œ œ œ ˜LJšœœ œ ˜;Jšœœ ˜)—J˜J˜—šŸ œœ˜Jšœœœ-˜GJ˜—šŸ œœ˜šœœ˜Jšœœ˜ šœ˜J˜$J˜)J˜$Jšœ˜J˜———š Ÿ œœ œœœ˜=šœ-˜3J˜——š Ÿ œœœœœ˜Ešœ˜J˜Jšœ œœœ!˜FJšœœœœ˜@Jšœœ˜—Jšœ˜J˜J˜——Jšœ™˜šŸ œœ˜Jšœœ˜JšœA˜AJ˜"J˜&Jšœœ ˜/J˜—šŸœœ œ˜"Jšœœœœ˜2Jšœœœœ˜2Jš œœœœœ˜FJšœ,œ˜0Jšœœœœ˜;Jšœ œ˜Jšœœ œ"˜Gšœ œœ˜J˜GJ˜——šŸœœ˜Jš œœœœœ˜#Jšœ˜Jšœœ˜7J˜—šŸ œœ/œ˜IJšœœ˜Jšœœ˜Jšœ)˜)Jšœ œ/˜Ašœœ˜Jšœ œ˜Jšœ@˜@šœœ˜Jšœ œ˜JšœB˜B—J˜Jšœ*˜*—šœ˜Jšœ;˜;Jšœ*˜*šœœ˜Jšœ<˜