DIRECTORY Basics USING [LowHalf], JaMBasic USING [Object], JaMInternal USING [Frame, Node, NodeSequence, Stack, StackRecord], JaMOps USING [APut, Array, Error, Install, InstallReason, MakeName, nullOb, Overflow, Pop, PopCardinal, PopInteger, Push, PushCardinal, rangechk, RegisterExplicit, StackOverflow, Top, Underflow], JaMStorage USING [Zone]; JaMStackImpl: MONITOR IMPORTS JaMOps, JaMStorage, Basics EXPORTS JaMOps = { OPEN JaMOps, JaMInternal, JaMBasic; zone: UNCOUNTED ZONE = JaMStorage.Zone[]; stkundflw,stkovrflw: name Object; Underflow: PUBLIC PROC[stack: Stack] = { ERROR Error[stkundflw] }; Overflow: PUBLIC PROC[stack: Stack] = { ERROR StackOverflow[stack] }; Restore: PUBLIC PROC[stack: Stack, mark: Node] = { FOR node: Node _ stack.free, node.next UNTIL node=NIL DO IF node=mark THEN EXIT; REPEAT FINISHED => RETURN; -- not found ENDLOOP; UNTIL stack.free=mark DO node: Node _ stack.free; stack.free _ node.next; node.next _ stack.head; stack.head _ node; ENDLOOP; }; NewStack: PUBLIC PROC[n: CARDINAL] RETURNS[Stack] = { nodes: LONG POINTER TO NodeSequence _ zone.NEW[NodeSequence[n]]; stack: Stack _ zone.NEW[StackRecord _ [head: NIL, free: NIL, nodes: nodes]]; FOR i: CARDINAL IN[0..n) DO node: Node _ @nodes[i]; node^ _ [next: stack.free, ob: nullOb]; stack.free _ node; ENDLOOP; RETURN[stack]; }; FreeStack: PUBLIC PROC[stack: Stack] = { zone.FREE[@stack.nodes]; zone.FREE[@stack]; }; Dup: PUBLIC PROC[stack: Stack] = { ob: Object _ Top[stack]; Push[stack,ob] }; Exch: PUBLIC PROC[stack: Stack] = { ob1: Object _ Pop[stack]; ob2: Object _ Pop[stack]; Push[stack,ob1]; Push[stack,ob2] }; Count: PROC[head: Node, max: CARDINAL _ LAST[CARDINAL]] RETURNS[CARDINAL] = INLINE { FOR i: CARDINAL IN[0..max) DO IF head=NIL THEN RETURN[i] ELSE head _ head.next; ENDLOOP; RETURN[max] }; Copy: PUBLIC PROC[stack: Stack, n: CARDINAL] = { head: Node _ NIL; -- will be new head of stack last: LONG POINTER TO Node _ @head; -- last link field temp: Node _ stack.head; IF n=0 THEN RETURN; IF Count[stack.head,n] { stkundflw _ MakeName[".stkundflw"L]; stkovrflw _ MakeName[".stkovrflw"L]; RegisterExplicit[frame, ".pop"L, JPop]; RegisterExplicit[frame, ".exch"L, JExch]; RegisterExplicit[frame, ".dup"L, JDup]; RegisterExplicit[frame, ".clrstk"L, JClrStk]; RegisterExplicit[frame, ".copy"L, JCopy]; RegisterExplicit[frame, ".roll"L, JRoll]; RegisterExplicit[frame, ".cntstk"L, JCntStk]; RegisterExplicit[frame, ".cnttomrk"L, JCntToMrk]; RegisterExplicit[frame, ".clrtomrk"L, JClrToMrk]; RegisterExplicit[frame, ".mark"L, JMark]; RegisterExplicit[frame, ".index"L, JIndex]; RegisterExplicit[frame, ".execstk"L, JExecStk]; RegisterExplicit[frame, ".dictstk"L, JDictStk]; }; ENDCASE; }; Install[InstallStack]; }. JaMStackImpl.mesa Original version by John Warnock, December 1978. Last changed by Bill Paxton, January 21, 1:09 PM Last changed by Doug Wyatt, 7-Oct-81 11:07:22 Russ Atkinson, July 22, 1983 7:16 pm Globals Error handling try to restore the stack so that mark is the head of the free list first, be sure the marked node is in the free list move nodes from the free list back onto the stack Stack allocation Stack operations Returns MIN[,max] Copy the top n entries Now do it Roll the top n entries by k places (in the "Pop" direction) Return the ith stack element, counting from 0. Execute the given procedure for each element on the given stack Stop the enumeration and return TRUE if the procedure returns TRUE. Stack intrinsics Initialization Ê %˜šœ™Jšœ0™0Jšœ0™0Jšœ.™.J™$—J˜šÏk ˜ Jšœœ ˜Jšœ œ ˜Jšœ œ1˜Bšœœ?˜KJ˜EJ˜1—Jšœ œ˜J˜—Jšœ˜Jšœ˜"Jšœ ˜Jšœ˜#J˜Jšœ™J˜Jšœ œœ˜)J˜J˜!J˜Jšœ™J˜JšÏn œœœœ˜BJ˜Jšžœœœœ˜EJ˜šžœœœ˜2JšœB™BJšœ2™2šœ$œœ˜8Jšœ œœ˜JšœœœÏc ˜'Jšœ˜—Jšœ1™1šœ˜J˜0J˜*Jšœ˜—J˜J˜—Jšœ™J˜š žœœœœœ ˜5Jš œœœœœ˜@Jšœœœœ˜Lšœœœ˜J˜J˜'J˜Jšœ˜—Jšœ˜J˜J˜—šž œœœ˜(Jšœœ˜Jšœœ ˜J˜J˜—Jšœ™J˜šžœœœ˜"J˜*J˜—šžœœœ˜#J˜3J˜#J˜—Jšœ ™ š žœœœœœ˜7Jšœœœ˜šœœœ ˜Jš œœœœœ˜1Jšœ˜—Jšœ˜J˜—Jšœ™šžœœœœ˜0Jšœ œŸ˜.JšœœœœŸ˜6J˜Jšœœœ˜JšœœŸ˜GJšœœŸ˜JJšœ ™ šœ˜J˜0J˜ J˜$Jšœ˜—J˜&J˜J˜—Jšœ;™;šžœœœœ˜2J˜Jš œœœœœ˜&Jšœœœœ˜3šœ œœ˜+Jšœœœœ˜)—šœ œœ˜+Jšœœœœ˜)—J˜;J˜J˜—š ž œœœœœœ˜EJšœœœ˜6J˜—šž œœœ˜)šœ œ˜J˜0J˜*Jšœ˜—J˜J˜—š ž œœœœœ˜