<> <> <> 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"]}; <