-- file Pass3.Mesa
-- last modified by Satterthwaite, October 30, 1979  2:51 PM

DIRECTORY
  ComData: FROM "comdata"
    USING [
      bodyRoot, importCtx, moduleCtx, monitored, outerCtx, stopping,
      textIndex],
  CompilerUtil: FROM "compilerutil" USING [MakeSwappable],
  Copier: FROM "copier"
    USING [
      CopierInit, CopierReset, FileProblem, FileVersion, FileVersionMix,
      ResetIncludeContexts, TableRelocated],
  Log: FROM "log" USING [ErrorHti, WarningTree],
  P3: FROM "p3"
    USING [
      Attr, BodyData,
      Pass3B, Pass3D, Pass3I, Pass3M, Pass3S, Pass3V,
      Pass3Xa, Pass3Xb, Pass3Xc,
      DeclNotify, IdNotify, MiscNotify, StmtNotify, ExpANotify, ExpBNotify,
      ExpInit, IdInit, IdFinish,
      BodyList, DeclList, Directory, ModulePrefix, Postlude, PopCtx, PushCtx],
  Symbols: FROM "symbols" USING [CSEIndex, RecordSEIndex, BTIndex],
  Table: FROM "table" USING [Base, Notifier, AddNotify, DropNotify],
  Tree: FROM "tree" USING [Link, Index, NullIndex, treeType],
  TreeOps: FROM "treeops" USING [GetNode, ScanList];

Pass3: PROGRAM
    IMPORTS
	CompilerUtil, Copier, Log, P3, Table, TreeOps,
	dataPtr: ComData
    EXPORTS CompilerUtil =
 PUBLIC
  BEGIN
  OPEN TreeOps;

  tb: PRIVATE Table.Base;	-- tree base (local copy)

  Pass3Notify: PRIVATE Table.Notifier =
    BEGIN  -- called by allocator whenever table area is repacked
    tb ← base[Tree.treeType];
    P3.DeclNotify[base];  P3.IdNotify[base];
    P3.MiscNotify[base];  P3.StmtNotify[base];
    P3.ExpANotify[base];  P3.ExpBNotify[base];
    END;


  implicitType: Symbols.CSEIndex;	-- assumed type of empty
  implicitTree: Tree.Link;		-- its tree
  implicitAttr: P3.Attr;		-- its atributes

  implicitRecord: Symbols.RecordSEIndex;-- type of extraction record

  currentBody: P3.BodyData;
  enclosingBody: Symbols.BTIndex;

  markCatch: BOOLEAN;		-- reset in Stmt, set in CatchPhrase
  continued: BOOLEAN;

  lockNode: Tree.Index;		-- lambda expr for monitor lock
  lockHeld: BOOLEAN;		-- within entry or internal procedure

 -- overall control

  P3Unit: PROCEDURE [unit: Tree.Link] RETURNS [Tree.Link] =
    BEGIN
    node: Tree.Index;
    Table.AddNotify[Pass3Notify];
    node ← GetNode[unit];
    Copier.CopierInit[];  P3.IdInit[];  P3.ExpInit[];
      BEGIN
      ENABLE
	BEGIN
	Copier.FileProblem =>
	  BEGIN Log.ErrorHti[fileName, hti]; RESUME [TRUE] END;
	Copier.FileVersion =>
	  BEGIN Log.ErrorHti[fileWrong, hti]; RESUME [TRUE] END;
	Copier.FileVersionMix =>
	  BEGIN Log.WarningTree[fileVersion, [hash[index: hti]]]; RESUME END;
	Copier.TableRelocated => RESUME;
	END;
      P3.Directory[tb[node].son[1]];
      P3.PushCtx[dataPtr.outerCtx];  P3.PushCtx[dataPtr.moduleCtx];
      ScanList[tb[node].son[2], Module];
      P3.PopCtx[];  P3.PopCtx[];
      P3.IdFinish[tb[node].son[1]];
      END;
    Copier.ResetIncludeContexts[];
    P3.Postlude[];
    Copier.CopierReset[];
    Table.DropNotify[Pass3Notify];
    RETURN [unit]
    END;

  Module: PRIVATE PROCEDURE [module: Tree.Link] =
    BEGIN
    node: Tree.Index = GetNode[module];
    saveIndex: CARDINAL = dataPtr.textIndex;
    dataPtr.stopping ← FALSE;
    dataPtr.textIndex ← tb[node].info;
    P3.ModulePrefix[module];
    P3.PushCtx[dataPtr.importCtx];
    lockNode ← IF ~dataPtr.monitored
		THEN Tree.NullIndex
		ELSE GetNode[tb[node].son[4]];
    P3.DeclList[tb[node].son[5]];
    P3.BodyList[dataPtr.bodyRoot];
    P3.PopCtx[];
    dataPtr.textIndex ← saveIndex;
    END;


 -- initialization code
  CompilerUtil.MakeSwappable[P3.Pass3B, pass3];
  CompilerUtil.MakeSwappable[P3.Pass3D, pass3];
  CompilerUtil.MakeSwappable[P3.Pass3I, pass3];
  CompilerUtil.MakeSwappable[P3.Pass3M, pass3];
  CompilerUtil.MakeSwappable[P3.Pass3S, pass3];
  CompilerUtil.MakeSwappable[P3.Pass3V, pass3];
  CompilerUtil.MakeSwappable[P3.Pass3Xa, pass3];
  CompilerUtil.MakeSwappable[P3.Pass3Xb, pass3];
  CompilerUtil.MakeSwappable[P3.Pass3Xc, pass3];

  END.