
    <<Pass4.Mesa>>
        <<Copyright  1985 by Xerox Corporation.  All rights reserved.>>
        <<Satterthwaite, June 18, 1986 12:24:29 pm PDT>>
        <<Paul Rovner, September 7, 1983 1:10 pm>>
        <<Russ Atkinson (RRA) March 6, 1985 10:19:49 pm PST>>

    DIRECTORY
        Alloc: TYPE USING [Notifier, AddNotify, DropNotify],
        ComData: TYPE USING [matched, monitored, table, tC0, tC1, textIndex],
        CompilerUtil: TYPE USING [],
        P4: TYPE USING [AssignEntries, AssignImports, Attr, BCDNotify, Body, DeclItem, DeclNotify, ExpANotify, ExpBNotify, ExpCNotify, 
        ExpInit, ExpReset, FinishBCD, InitBCD, LayoutNotify, MatchBCD, OpsNotify, ProcessDirectory, ProcessExports, ProcessImports, 
        StmtNotify, VarInit, voidAttr],
        SourceMap: TYPE USING [Loc],
        Symbols: TYPE USING [Base, Type, RecordSEIndex, RecordSENull, RootBti, typeANY],
        Tree: TYPE USING [Base, Index, Link, nullIndex, treeType],
        TreeOps: TYPE USING [FreeNode, GetNode, ToLoc];

    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 Type;    -- 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: SourceMap.Loc = dataPtr.textIndex;
            dataPtr.textIndex _ ToLoc[tb[subNode].info];
            P4.InitBCD[tb[subNode].son[1]];
            dataPtr.textIndex _ ToLoc[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};

        }.


