DIRECTORY
BasicTime: TYPE USING [],
Alloc:
TYPE
USING [
Handle, Selector, TableInfo, Chunkify, Create, Destroy, Failure, Reset],
CBinary: TYPE USING [DebugTab, ErrorTab, MesaTab],
CompilerOps: TYPE USING [LetterSwitches, StreamId, Transaction],
CompilerUtil:
TYPE
USING [
TableId,
InstallParseTables, PrefillSymbols, P1Unit, P2Unit, P3Unit, P3Postlude, P4Unit, P5module,
EndObjectFile, PrintBodies, PrintSymbols, PrintTree, StartObjectFile, TableOut],
ComData:
TYPE
USING [
bcdSeg, codeSeg, compilerVersion, globalFrameSize, interface, linkCount, matched,
nErrors, nWarnings, objectBytes, objectStamp, objectVersion,
ownSymbols, pattern, source, sourceTokens, symSeg, switches, table, textIndex],
Copier: TYPE USING [FileInit, FileReset],
DebuggerSwap: TYPE USING [CallDebugger],
FS: TYPE USING [StreamFromOpenFile, nullOpenFile],
FileParmOps: TYPE USING [AcquireOutput, ReleaseOutput],
IO: TYPE USING [Close, Flush, PutChar, Put, PutRope, rope, STREAM, time, Error],
LiteralOps: TYPE USING [Initialize, Finalize],
Loader: TYPE USING [BCDBuildTime],
Log: TYPE USING [Error],
OSMiscOps:
TYPE
USING [
GenerateUniqueId, MergeStamps, StampToTime, TimeToStamp],
PrincOpsUtils: TYPE USING [Codebase],
Rope: TYPE USING [ROPE],
RuntimeError: TYPE USING [UNCAUGHT],
SymLiteralOps: TYPE USING [Finalize, Initialize],
SymbolPack: TYPE,
SymbolOps: TYPE USING [Finalize, Initialize],
SymbolSegment: TYPE USING [Tables, treeType],
TimeStamp: TYPE USING [Stamp],
Tree: TYPE USING [Link],
TreeOps: TYPE USING [Finalize, Initialize, PopTree, Reset];
Sequencer:
MONITOR
IMPORTS
Alloc, CBinary, CompilerUtil, Copier, DebuggerSwap, FS, FileParmOps, IO, Log,
LiteralOps, Loader, OSMiscOps, PrincOpsUtils, RuntimeError, SymLiteralOps, SymbolOps, TreeOps,
ownSymbols: SymbolPack, dataPtr: ComData
EXPORTS CompilerOps, CompilerUtil = {
table: Alloc.Handle ← NIL;
pass: CHARACTER ['1..'5];
ExtendedTables: TYPE = Alloc.Selector[SymbolSegment.Tables.FIRST .. SymbolSegment.Tables.LAST+1];
Initialize:
PROC = {
weights:
ARRAY ExtendedTables
OF Alloc.TableInfo ← [
[30], [20], [4], [4], [4], [2], [4], [1], [2], [1], [2], [2], [20]]; -- empirical
IF table =
NIL
THEN {
table ← Alloc.Create[weights: DESCRIPTOR[weights]];
table.Chunkify[SymbolSegment.treeType];
table.Chunkify[SymbolSegment.Tables.LAST+1]} -- codeType
ELSE table.Reset[];
SymbolOps.Initialize[table, NIL]; LiteralOps.Initialize[table];
TreeOps.Initialize[table]};
Finalize:
PROC [parms: TransactionPtr, ownedObject:
BOOL] = {
parms.objectVersion ← dataPtr.objectVersion;
parms.interface ← dataPtr.interface;
parms.matched ← dataPtr.matched AND (dataPtr.nErrors = 0);
parms.sourceTokens ← dataPtr.sourceTokens;
parms.nErrors ← dataPtr.nErrors; parms.nWarnings ← dataPtr.nWarnings;
parms.objectBytes ← dataPtr.objectBytes;
parms.objectFrameSize ← dataPtr.globalFrameSize;
parms.linkCount ← dataPtr.linkCount;
parms.bcdPages ← [base: dataPtr.bcdSeg.base, pages: dataPtr.bcdSeg.pages];
parms.codePages ← [base: dataPtr.codeSeg.base, pages: dataPtr.codeSeg.pages];
parms.symbolPages ← [base: dataPtr.symSeg.base, pages: dataPtr.symSeg.pages];
CompilerUtil.EndObjectFile[dataPtr.nErrors=0];
IF streamInfo[$object].stream #
NIL
THEN {
IO.Close[streamInfo[$object].stream ! IO.Error => CONTINUE];
streamInfo[$object].stream ← NIL};
IF ownedObject
THEN {
IF parms.objectFile =
FS.nullOpenFile
THEN DebuggerSwap.CallDebugger["Compiler bug: please call Paul Rovner"];
FileParmOps.ReleaseOutput[parms.objectFile];
};
TreeOps.Finalize[]; LiteralOps.Finalize[]; SymbolOps.Finalize[];
table.Reset[]};
Debug:
PROC [tree, symbols:
PROC [Alloc.Handle]] = {
tree[table]; symbols[table]};
Punt: PUBLIC ERROR = CODE;
started: BOOL ← FALSE;
Start:
PUBLIC
ENTRY
PROC = {
ENABLE UNWIND => NULL;
IF started AND table # NIL THEN Alloc.Destroy[table];
table ← NIL;
started ← TRUE};
Stop:
PUBLIC
ENTRY
PROC = {
ENABLE UNWIND => NULL;
IF started
THEN {
IF table # NIL THEN {Alloc.Destroy[table]; table ← NIL};
started ← FALSE}};
DoTransaction:
PUBLIC
ENTRY
PROC [parms: TransactionPtr] = {
ENABLE UNWIND => NULL;
root: Tree.Link;
debug: BOOL;
nParseErrors: CARDINAL;
parsed, aborted: BOOL;
ownedObject: BOOL ← FALSE;
PrintTreeRoot: PROC [table: Alloc.Handle] = {CompilerUtil.PrintTree[table, root]};
PrintSymbols:
PROC [table: Alloc.Handle] = {
CompilerUtil.PrintSymbols[table, dataPtr.interface]};
IF ~started THEN RETURN WITH ERROR Punt[];
getStream ← parms.getStream;
dataPtr.source ← parms.source;
dataPtr.switches ← parms.switches;
dataPtr.matched ← parms.op = replace;
dataPtr.pattern ← parms.pattern;
debug ← dataPtr.switches['d]; dataPtr.switches['d] ← FALSE;
dataPtr.objectVersion ← OSMiscOps.GenerateUniqueId[];
dataPtr.objectStamp ← OSMiscOps.TimeToStamp[dataPtr.source.version];
encode switches, compiler version (see DIRECTORY processing also)
dataPtr.objectStamp ← OSMiscOps.MergeStamps[
dataPtr.objectStamp, OSMiscOps.TimeToStamp[[0, 0, LOOPHOLE[dataPtr.switches]]]];
dataPtr.objectStamp ← OSMiscOps.MergeStamps[
dataPtr.objectStamp, OSMiscOps.TimeToStamp[dataPtr.compilerVersion]];
dataPtr.nErrors ← dataPtr.nWarnings ← 0; aborted ← FALSE;
streamInfo[$source] ←
[access: $read, stream: parms.sourceStream, status: [count: 0, open: FALSE]];
streamInfo[$object] ← streamInfo[$log] ←
[access: $write, stream: NIL, status: [count: 0, open: FALSE]];
Initialize[];
{
ENABLE {
ABORTED => NULL;
UNWIND => Finalize[parms, ownedObject];
Alloc.Failure => {IF ~debug THEN GOTO storageFull};
RuntimeError.UNCAUGHT => IF ~debug THEN GOTO uncaughtSignal;
};
dataPtr.table ← table;
CompilerUtil.PrefillSymbols[];
first pass
IF parms.startPass # NIL AND ~parms.startPass[1] THEN GOTO cancel;
pass ← '1;
parsed ← CompilerUtil.P1Unit[];
nParseErrors ← dataPtr.nErrors;
IF ~parsed THEN GOTO failed;
root ← TreeOps.PopTree[]; TreeOps.Reset[];
IF parms.debugPass <= 1
THEN Debug[PrintTreeRoot, PrintSymbols];
second pass
IF parms.startPass # NIL AND ~parms.startPass[2] THEN GOTO cancel;
pass ← '2;
root ← CompilerUtil.P2Unit[root];
IF parms.debugPass <= 2
THEN Debug[PrintTreeRoot, PrintSymbols];
third and fourth passes
IF parms.startPass # NIL AND ~parms.startPass[3] THEN GOTO cancel;
SymLiteralOps.Initialize[table];
{
ENABLE
UNWIND => SymLiteralOps.Finalize[];
Copier.FileInit[[dataPtr.objectVersion, parms.objectName], table, parms.fileParms];
{
ENABLE
UNWIND => Copier.FileReset[];
BEGIN
ENABLE Alloc.Failure => {Copier.FileReset[]; SymLiteralOps.Finalize[]; GOTO storageFull};
pass ← '3;
root ← CompilerUtil.P3Unit[root];
CompilerUtil.P3Postlude[dataPtr.nErrors <= nParseErrors];
IF parms.debugPass <= 3 THEN Debug[PrintTreeRoot, PrintSymbols];
IF dataPtr.nErrors > nParseErrors THEN GOTO deleteFiles;
dataPtr.objectVersion ← OSMiscOps.StampToTime[dataPtr.objectStamp];
parms.fileParms.Forget[[dataPtr.objectVersion, parms.objectName]];
IF parms.objectFile #
FS.nullOpenFile
THEN DebuggerSwap.CallDebugger["Compiler bug: please call Paul Rovner"];
SymbolTable.Forget[[parms.objectFile, SymbolTable.anySpan]];
parms.objectFile ← FileParmOps.AcquireOutput[parms.objectName];
ownedObject ← TRUE;
IF parms.objectFile =
FS.nullOpenFile
THEN DebuggerSwap.CallDebugger["Compiler bug: please call Paul Rovner"];
streamInfo[$object].stream
← FS.StreamFromOpenFile[openFile: parms.objectFile, accessRights: $write];
IF parms.startPass #
NIL
AND ~parms.startPass[4]
THEN {Copier.FileReset[]; SymLiteralOps.Finalize[]; GOTO cancel};
pass ← '4;
CompilerUtil.StartObjectFile[AcquireStream[$object]];
CompilerUtil.P4Unit[root];
IF parms.debugPass <= 4 THEN Debug[CompilerUtil.PrintBodies, PrintSymbols];
EXITS
deleteFiles => NULL;
END;
};
-- end ENABLE UNWIND => Copier.FileReset[];
IF dataPtr.nErrors # 0
THEN {SymLiteralOps.Finalize[];
GOTO failed};
fifth pass
IF ~dataPtr.interface
THEN {
IF parms.startPass #
NIL
AND ~parms.startPass[5]
THEN {SymLiteralOps.Finalize[]; GOTO cancel};
pass ← '5;
CompilerUtil.P5module[];
};
};
-- end ENABLE UNWIND => SymLiteralOps.Finalize[];
SymLiteralOps.Finalize[];
IF parms.startPass # NIL AND ~parms.startPass[6] THEN GOTO cancel;
CompilerUtil.TableOut[table];
IF parms.startPass # NIL THEN [] ← parms.startPass[0];
IF dataPtr.nErrors # 0 THEN aborted ← TRUE;
EXITS
failed => aborted ← TRUE;
cancel => {Log.Error[aborted]; aborted ← TRUE};
uncaughtSignal => {
errorStream: IO.STREAM = AcquireStream[$log];
aborted ← TRUE;
Log.Error[compilerError];
IO.PutRope[errorStream, "in Pass "]; IO.PutChar[errorStream, pass];
IO.PutChar[errorStream, '\n];
ReleaseStream[$log];
Finalize[parms, ownedObject];
RETURN WITH ERROR Punt[];
};
storageFull => {
errorStream: IO.STREAM = AcquireStream[$log];
aborted ← TRUE;
dataPtr.nErrors ← dataPtr.nErrors+1;
IO.PutRope[errorStream, "\nStorage "]; IO.PutRope[errorStream, "overflow"];
IO.PutRope[errorStream, " in Pass "]; IO.PutChar[errorStream, pass];
IO.PutChar[errorStream, '\n];
ReleaseStream[$log];
};
}; -- end ENABLE UNWIND => Finalize[parms, ownedObject]; etc.
Finalize[parms, ownedObject];
}; -- end DoTransaction
START dataPtr; -- initialize STRING variables, etc.
START ownSymbols;
dataPtr.ownSymbols ← ownSymbols;
dataPtr.compilerVersion ← [net: 0Ch, host: 0Ch, time: 0F0010004h]; -- Cedar release
CompilerUtil.InstallParseTables[PrincOpsUtils.Codebase[LOOPHOLE[CBinary.MesaTab]]] ;
tableBase[$error] ← PrincOpsUtils.Codebase[LOOPHOLE[CBinary.ErrorTab]];
tableBase[$debug] ← PrincOpsUtils.Codebase[LOOPHOLE[CBinary.DebugTab]];
}.