-- file Pass3.mesa
-- last modified by Satterthwaite, April 15, 1983 10:00 am

DIRECTORY
  A3: TYPE USING [TreeNotify, TypeNotify],
  Alloc: TYPE USING [Notifier, AddNotify, DropNotify],
  ComData: TYPE USING [
    importCtx, moduleCtx, monitored, outerCtx, stopping, switches, table, textIndex, zone],
  CompilerUtil: TYPE USING [],
  Copier: TYPE USING [
    CopierInit, CopierReset, FileProblem, FileVersion, FileVersionMix, TableRelocated],
  Log: TYPE USING [ErrorHti, WarningTree],
  P3: TYPE USING [
    DeclNotify, MiscNotify, StmtNotify, VRNotify, ExpANotify, ExpBNotify, ExpCNotify,
    ExpInit, ExpReset, IdInit, IdReset, BodyList, DeclList, Header, PopCtx, PushCtx],
  SymLiteralOps: TYPE USING [Reset],
  Symbols: TYPE USING [CSEIndex, CSENull, RootBti],
  Tree: TYPE USING [Base, Link, Index, NullIndex, treeType],
  TreeOps: TYPE USING [GetNode];

Pass3: PROGRAM
    IMPORTS
      A3, Alloc, Copier, Log, P3, SymLiteralOps, TreeOps,
      dataPtr: ComData
    EXPORTS CompilerUtil = PUBLIC {
  OPEN TreeOps;

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

  Pass3Notify: PRIVATE Alloc.Notifier = {
    tb ← base[Tree.treeType];
    A3.TreeNotify[base];  A3.TypeNotify[base];
    P3.DeclNotify[base];  P3.MiscNotify[base];  P3.StmtNotify[base];  P3.VRNotify[base];
    P3.ExpANotify[base];  P3.ExpBNotify[base];  P3.ExpCNotify[base]};


  lockNode: Tree.Index;			-- lambda expr for monitor lock

  checkedANY: Symbols.CSEIndex;		-- typeANY in CHECKED code
  
  -- overall control

  P3Unit: PROC [unit: Tree.Link] RETURNS [Tree.Link] = {
    node: Tree.Index;
    saveIndex: CARDINAL = dataPtr.textIndex;
    (dataPtr.table).AddNotify[Pass3Notify];
    checkedANY ← Symbols.CSENull;
    node ← GetNode[unit];
    dataPtr.textIndex ← tb[node].info;
    Copier.CopierInit[ownTable: dataPtr.table, symbolCachePages: 256];
    P3.IdInit[dataPtr.zone];  P3.ExpInit[dataPtr.zone];
      BEGIN
      ENABLE {
	Copier.FileProblem => {Log.ErrorHti[fileName, hti]; RESUME [TRUE]};
	Copier.FileVersion => {Log.ErrorHti[fileWrong, hti]; RESUME [TRUE]};
	Copier.FileVersionMix => {
	  Log.WarningTree[fileVersion, [hash[index: hti]]]; RESUME};
	Copier.TableRelocated => {RESUME}};
      dataPtr.stopping ← FALSE;
      P3.Header[node];
      P3.PushCtx[dataPtr.outerCtx];  P3.PushCtx[dataPtr.moduleCtx];
      P3.PushCtx[dataPtr.importCtx];
      lockNode ← IF ~dataPtr.monitored THEN Tree.NullIndex ELSE GetNode[tb[node].son[5]];
      P3.DeclList[tb[node].son[6]];
      P3.BodyList[Symbols.RootBti];
      P3.PopCtx[];	-- import context
      P3.PopCtx[];  P3.PopCtx[];
      P3.IdReset[tb[node].son[1]];  P3.ExpReset[];
      END;
    Copier.CopierReset[];  SymLiteralOps.Reset[pad: ~dataPtr.switches['s]];
    (dataPtr.table).DropNotify[Pass3Notify];
    dataPtr.textIndex ← saveIndex;
    RETURN [unit]};

  }.