| (* Copyright (C) 2015-2025 Free Software Foundation, Inc. *) |
| (* This file is part of GNU Modula-2. |
| |
| GNU Modula-2 is free software; you can redistribute it and/or modify it under |
| the terms of the GNU General Public License as published by the Free |
| Software Foundation; either version 3, or (at your option) any later |
| version. |
| |
| GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY |
| WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GCC; see the file COPYING3. If not see |
| <http://www.gnu.org/licenses/>. *) |
| |
| IMPLEMENTATION MODULE mcStack ; |
| |
| FROM Storage IMPORT ALLOCATE, DEALLOCATE ; |
| |
| FROM Indexing IMPORT Index, InitIndex, LowIndice, HighIndice, GetIndice, PutIndice, |
| DeleteIndice, KillIndex ; |
| |
| |
| TYPE |
| stack = POINTER TO RECORD |
| list : Index ; |
| count: CARDINAL ; |
| END ; |
| |
| (* |
| init - create and return a stack. |
| *) |
| |
| PROCEDURE init () : stack ; |
| VAR |
| s: stack ; |
| BEGIN |
| NEW (s) ; |
| WITH s^ DO |
| list := InitIndex (1) ; |
| count := 0 |
| END ; |
| RETURN s |
| END init ; |
| |
| |
| (* |
| kill - deletes stack, s. |
| *) |
| |
| PROCEDURE kill (VAR s: stack) ; |
| BEGIN |
| s^.list := KillIndex (s^.list) ; |
| DISPOSE (s) ; |
| s := NIL |
| END kill ; |
| |
| |
| (* |
| push - an address, a, onto the stack, s. |
| It returns, a. |
| *) |
| |
| PROCEDURE push (s: stack; a: ADDRESS) : ADDRESS ; |
| BEGIN |
| WITH s^ DO |
| IF count=0 |
| THEN |
| PutIndice (list, LowIndice (list), a) |
| ELSE |
| PutIndice (list, HighIndice (list)+1, a) |
| END ; |
| INC (count) |
| END ; |
| RETURN a |
| END push ; |
| |
| |
| (* |
| pop - and return the top element from stack, s. |
| *) |
| |
| PROCEDURE pop (s: stack) : ADDRESS ; |
| VAR |
| a: ADDRESS ; |
| BEGIN |
| WITH s^ DO |
| IF count = 0 |
| THEN |
| HALT |
| ELSE |
| DEC (count) ; |
| a := GetIndice (list, HighIndice (list)) ; |
| DeleteIndice (list, HighIndice (list)) ; |
| RETURN a |
| END |
| END |
| END pop ; |
| |
| |
| (* |
| replace - performs a pop; push (a); return a. |
| *) |
| |
| PROCEDURE replace (s: stack; a: ADDRESS) : ADDRESS ; |
| VAR |
| b: ADDRESS ; |
| BEGIN |
| b := pop (s) ; |
| RETURN push (s, a) |
| END replace ; |
| |
| |
| (* |
| depth - returns the depth of the stack. |
| *) |
| |
| PROCEDURE depth (s: stack) : CARDINAL ; |
| BEGIN |
| RETURN s^.count |
| END depth ; |
| |
| |
| (* |
| access - returns the, i, th stack element. |
| The top of stack is defined by: |
| |
| access (s, depth (s)). |
| *) |
| |
| PROCEDURE access (s: stack; i: CARDINAL) : ADDRESS ; |
| BEGIN |
| IF (i>s^.count) OR (i=0) |
| THEN |
| HALT |
| ELSE |
| RETURN GetIndice (s^.list, i) |
| END |
| END access ; |
| |
| |
| END mcStack. |