-- file Pass4.Mesa
-- last modified by Satterthwaite, October 10, 1979  1:48 PM

DIRECTORY
  ComData: FROM "comdata"
    USING [bodyRoot, mainBody, monitored, tC0, tC1, textIndex],
  CompilerUtil: FROM "compilerutil" USING [MakeSwappable],
  P4: FROM "p4"
    USING [
      Repr, none,
      BCDNotify, DeclNotify, LayoutNotify,
      ExpANotify, ExpBNotify, OpsNotify, StmtNotify,
      AssignEntries, AssignImports, BodyList, DeclItem, DeclUpdate,
      FinishBCD, InitBCD, Pass4XInit, ProcessExports, ProcessImports, VarInit,
      Pass4B, Pass4D, Pass4L, Pass4Ops, Pass4S, Pass4Xa, Pass4Xb],
  Symbols: FROM "symbols"
    USING [CSEIndex, RecordSEIndex, RecordSENull, typeANY],
  Table: FROM "table" USING [Base, Notifier, AddNotify, DropNotify],
  Tree: FROM "tree" USING [treeType, Index, Link, Null, NullIndex],
  TreeOps: FROM "treeops" USING [FreeNode, GetNode, ScanList, UpdateList];

Pass4: PROGRAM
    IMPORTS
	CompilerUtil, Table, TreeOps, P4,
	dataPtr: ComData
    EXPORTS CompilerUtil =
 PUBLIC
  BEGIN
  OPEN TreeOps, Symbols;

  tb: Table.Base;	-- tree base address (local copy)
  seb: Table.Base;	-- se table base (local copy)
  ctxb: Table.Base;	-- context table base (local copy)

  tTRUE: Tree.Link;
  tFALSE: Tree.Link;


  P4Notify: Table.Notifier =
    BEGIN  -- 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];
    END;


 -- intermediate result bookkeeping

  returnRecord, resumeRecord: RecordSEIndex;

  implicitType: CSEIndex;		-- assumed type of empty
  implicitBias: INTEGER;		-- assumed bias of empty
  implicitRep: P4.Repr;	-- assumed representation of empty

  lockNode: Tree.Index;
  resident: BOOLEAN;

 -- overall control

  P4Unit: PROCEDURE [unit: Tree.Link] =
    BEGIN
    node: Tree.Index;
    Table.AddNotify[P4Notify];
    tTRUE ← dataPtr.tC1;  tFALSE ← dataPtr.tC0;
    P4.Pass4XInit[];  P4.InitBCD[];
    node ← GetNode[unit];
    tb[node].son[2] ← UpdateList[tb[node].son[2], Module
	! P4.VarInit => RESUME [TRUE]];
    FreeNode[node];
    P4.FinishBCD[];
    Table.DropNotify[P4Notify];
    END;

  Module: PRIVATE PROCEDURE [module: Tree.Link] RETURNS [Tree.Link] =
    BEGIN
    node: Tree.Index = GetNode[module];
    saveIndex: CARDINAL = dataPtr.textIndex;
    implicitType ← typeANY;  implicitBias ← 0;  implicitRep ← P4.none;
    resumeRecord ← RecordSENull;
    dataPtr.textIndex ← tb[node].info;
    lockNode ← IF ~dataPtr.monitored
		THEN Tree.NullIndex
		ELSE GetNode[tb[node].son[4]];
    resident ← tb[node].attr1;
    P4.AssignEntries[dataPtr.mainBody];
    P4.AssignImports[tb[node].son[1]];
    ScanList[tb[node].son[5], P4.DeclItem];
    P4.BodyList[dataPtr.bodyRoot];
    tb[node].son[5] ← UpdateList[tb[node].son[5], P4.DeclUpdate];
    P4.ProcessImports[tb[node].son[1]];
    tb[node].son[2] ← P4.ProcessExports[tb[node].son[2]];
    FreeNode[node];
    dataPtr.textIndex ← saveIndex;  RETURN [Tree.Null]
    END;


 -- initialization code
  CompilerUtil.MakeSwappable[P4.Pass4B, pass4];
  CompilerUtil.MakeSwappable[P4.Pass4D, pass4];
  CompilerUtil.MakeSwappable[P4.Pass4L, pass4];
  CompilerUtil.MakeSwappable[P4.Pass4S, pass4];
  CompilerUtil.MakeSwappable[P4.Pass4Ops, pass4];
  CompilerUtil.MakeSwappable[P4.Pass4Xa, pass4];
  CompilerUtil.MakeSwappable[P4.Pass4Xb, pass4];

  END.