-- Stack.mesa
-- last edited by Sweet, 5-Mar-82 20:59:30
-- last edited by Satterthwaite, December 16, 1982 8:53 am

DIRECTORY
  Alloc: TYPE USING [Notifier],
  CodeDefs: TYPE USING [
    BYTE, DataStackIndex, StackBackup, StackIndex, StackLocRec, StackPos, VarComponent];

Stack: DEFINITIONS = {
  OPEN CodeDefs;

-- Interface Items
  
  stking: VAR BOOL;
  
  StackModelingError: SIGNAL;

  Above: PROC [s: StackIndex, count: CARDINAL←1, nullOk: BOOL←FALSE] RETURNS [StackIndex];
	-- the index of the word "count" above that at "s"
  Also: PROC [place: StackBackup, n: CARDINAL←1];
	-- record that the top "n" words on the stack are also in temps 
	--   requires that top "n" words are already onStack
  Check: PROC [b: BYTE];
	-- if stack in "On", assure that operands are loaded, reflect changes
	--   due to execution of instruction byte "b", check for overflow
  Clear: PROC;
	-- pop off all remaining words
  ComponentForBackup: PROC [sb: StackBackup, words: CARDINAL←1] 
    RETURNS [VarComponent];

  DataIndex: PUBLIC PROC [s: StackIndex] RETURNS [DataStackIndex];
	-- Discriminate on cb[s], insuring variant of data.
  Decr: PROC [count: CARDINAL←1];
	-- remove the "count" top words from the stack model
  DeleteToMark: PROC;
	-- ResetToMark, UnMark
  Depth: PROC RETURNS [d: StackPos];
	-- number of words actually on stack
  Dump: PROC;
	-- empty the stack into temporaries
  Dup: PROC [load: BOOL←FALSE];
	-- duplicate the top element on the stack
	-- if "load", load if top is in temp
  Exchange: PROC;
	-- exchange the top two elements on the stack
  Forget: PROC [s: StackIndex, count: CARDINAL←1];
	-- remove "count" words beginning at "a" from the stack model
  Incr: PROC [count: CARDINAL←1];
	-- add "count" words to the stack model
  Init: PROC;
   
  KeepOnly: PROC [s: StackIndex, count: CARDINAL];
        -- pop off anything above the "count" words at "s"
  Load: PROC [s: StackIndex, count: CARDINAL←1];
	-- put the "count" words beginning at "s" on top
  Loc: PROC [s: StackIndex, count: CARDINAL←1] RETURNS [StackLocRec];
	-- where are the "count" words beginning at "s"
  Mark: PROC;
	-- insert a mark, also a label for dumping previous contents
  MoveToTemp: PROC [firstIndex: StackIndex, count: CARDINAL←1, preChaff: CARDINAL←0]
      RETURNS [VarComponent];
        -- store "count" words from stack into contiguous temps
  New: PROC RETURNS [old: StackIndex];
    
  Off: PROC = INLINE {stking ← FALSE};

  On: PROC = INLINE {stking ← TRUE};

  Pop: PROC [count: CARDINAL←1];
	-- pop off the top "count" words (unless they are already in temps)
  Prefix: PROC [sti: StackIndex];
	-- link saved away stack item on front of model
  Require: PROC [count: StackPos];
	-- empty all but the top "count" words into temporaries
	-- the top "count" words may also be dumped if necessary
  Reset: PROC;
    
  ResetToMark: PROC;
	-- load items back to the first mark, remove from model
  Restore: PROC [s: StackIndex];
  RoomFor: PROC [n: CARDINAL] RETURNS [BOOL];
	-- will the stack overflow if n more words are loaded
  TempStore: PROC [count: CARDINAL←1] RETURNS [VarComponent];
	-- store the top "count" words into a temp
  Top: PROC [count: CARDINAL←1] RETURNS [StackIndex];
	-- the index of the word "count" down from the top
  UnMark: PROC;
	-- remove the topmost mark
  VDepth: PUBLIC PROC RETURNS [StackPos];
	-- the current depth of the virtual stack
  VDepthOf: PROC [s: StackIndex] RETURNS [d: StackPos];
	-- the virtual depth of the word at "s"

  StackImplNotify: Alloc.Notifier;

  }.