DIRECTORY
Alloc: TYPE USING [Notifier, AddNotify, DropNotify],
ComData: TYPE USING [matched, monitored, table, tC0, tC1, textIndex],
CompilerUtil: TYPE USING [],
P4:
TYPE
USING [
Attr, voidAttr,
BCDNotify, DeclNotify, LayoutNotify,
ExpANotify, ExpBNotify, ExpCNotify, OpsNotify, StmtNotify,
AssignEntries, AssignImports, Body, DeclItem, ExpInit, ExpReset,
FinishBCD, InitBCD, MatchBCD,
ProcessDirectory, ProcessExports, ProcessImports, VarInit],
Symbols:
TYPE
USING [
Base, CSEIndex, RecordSEIndex, RecordSENull, RootBti, typeANY],
Tree: TYPE USING [Base, Index, Link, NullIndex, treeType],
TreeOps: TYPE USING [FreeNode, GetNode];
Pass4:
PROGRAM
IMPORTS Alloc, TreeOps, P4, dataPtr: ComData
EXPORTS CompilerUtil = {
OPEN TreeOps, Symbols;
tb: Tree.Base; -- tree base address (local copy)
tTRUE: PUBLIC Tree.Link;
tFALSE: PUBLIC Tree.Link;
P4Notify:
PUBLIC Alloc.Notifier = {
called by allocator whenever table area is repacked
tb ← base[Tree.treeType];
P4.BCDNotify[base]; P4.DeclNotify[base];
P4.LayoutNotify[base];
P4.StmtNotify[base];
P4.OpsNotify[base];
P4.ExpANotify[base]; P4.ExpBNotify[base]; P4.ExpCNotify[base]};
intermediate result bookkeeping
returnRecord, resumeRecord: PUBLIC RecordSEIndex;
implicitType: PUBLIC CSEIndex; -- assumed type of empty
implicitBias: PUBLIC INTEGER; -- assumed bias of empty
implicitAttr: PUBLIC P4.Attr; -- assumed attributes of empty
lockNode: PUBLIC Tree.Index;
resident: PUBLIC BOOL;
overall control
P4Unit:
PUBLIC
PROC [unit: Tree.Link] = {
node: Tree.Index;
(dataPtr.table).AddNotify[P4Notify];
tTRUE ← dataPtr.tC1; tFALSE ← dataPtr.tC0;
implicitType ← typeANY; implicitBias ← 0; implicitAttr ← P4.voidAttr;
resumeRecord ← RecordSENull;
P4.ExpInit[];
node ← GetNode[unit];
Module[node ! P4.VarInit => {RESUME [TRUE]}];
P4.ExpReset[];
FreeNode[node];
(dataPtr.table).DropNotify[P4Notify]};
Module:
PROC [node: Tree.Index] = {
subNode: Tree.Index = GetNode[tb[node].son[6]];
saveIndex: CARDINAL = dataPtr.textIndex;
dataPtr.textIndex ← tb[subNode].info;
P4.InitBCD[tb[subNode].son[1]];
dataPtr.textIndex ← tb[node].info;
lockNode ← IF ~dataPtr.monitored THEN Tree.NullIndex ELSE GetNode[tb[node].son[5]];
resident ← tb[node].attr1;
P4.AssignEntries[Symbols.RootBti];
P4.AssignImports[tb[node].son[2]];
P4.DeclItem[tb[node].son[6]];
P4.Body[Symbols.RootBti];
P4.ProcessDirectory[tb[node].son[1]];
P4.ProcessImports[tb[node].son[2]];
tb[node].son[3] ← P4.ProcessExports[tb[node].son[3]];
P4.FinishBCD[tb[subNode].son[1]];
IF dataPtr.matched THEN dataPtr.matched ← P4.MatchBCD[];
dataPtr.textIndex ← saveIndex};
}.