3709192002-03-20Martin Nilsson #pike __REAL_VERSION__
22cabf2001-08-14Martin Nilsson //! This class implements a simple stack. Instead of adding and removing //! elements to an array, and thus making it vary in size for every push //! and pop operation, this stack tries to keep the stack size constant. //! If however the stack risks to overflow, it will allocate double its //! current size, i.e. pushing an element on an full 32 slot stack will //! result in a 64 slot stack with 33 elements.
2c4c6d2018-03-10Henrik Grubbström (Grubba) // NB: There's apparently quite a bit of code that accesses these // directly, so they can't be made protected directly. // Any accesses to ptr should be replaced with sizeof(), // and any to arr with values(). // // The pragma is to be removed when ptr and arr are declared protected. #pragma no_deprecation_warnings __deprecated__(int) ptr; __deprecated__(array) arr;
a470d72000-12-01Johan Schön 
22cabf2001-08-14Martin Nilsson //! Push an element on the top of the stack.
a470d72000-12-01Johan Schön void push(mixed val) { if(ptr == sizeof(arr)) { arr += allocate(ptr); } arr[ptr++] = val; }
22cabf2001-08-14Martin Nilsson //! Returns the top element from the stack, without //! popping it.
9304782002-03-25Martin Nilsson //! @throws //! Throws an error if called on an empty stack.
ea22682018-06-17Henrik Grubbström (Grubba) //! @seealso //! @[peek()]
a470d72000-12-01Johan Schön mixed top() { if (ptr) {
547fbc2003-08-22Martin Nilsson  return arr[ptr-1];
a470d72000-12-01Johan Schön  } error("Stack underflow\n"); }
ea22682018-06-17Henrik Grubbström (Grubba) //! Returns an element from the stack, without popping it. //! //! @param offset //! The number of elements from the top of the stack to skip. //! //! @throws //! Throws an error if called on an empty stack. //! //! @seealso //! @[top()] mixed peek(int|void offset) { if ((offset >= 0) && ((ptr-offset) > 0)) { return arr[ptr-offset-1]; } error("Stack underflow\n"); }
22cabf2001-08-14Martin Nilsson //! Pops @[val] entries from the stack, or one entry //! if no value is given. The popped entries are not //! actually freed, only the stack pointer is moved.
a470d72000-12-01Johan Schön void quick_pop(void|int val) { if (val) { if (ptr < val) { ptr = 0; } else { ptr -= val; } } else { if (ptr > 0) { ptr--; } } }
22cabf2001-08-14Martin Nilsson //! Pops and returns entry @[val] from the stack, counting //! from the top. If no value is given the top element is
11c0bb2002-03-18Martin Stjernholm //! popped and returned. All popped entries are freed from
22cabf2001-08-14Martin Nilsson //! the stack.
a470d72000-12-01Johan Schön mixed pop(void|int val) {
547fbc2003-08-22Martin Nilsson  mixed ret;
a470d72000-12-01Johan Schön  if (val) { if (ptr <= 0) { error("Stack underflow\n"); } if (ptr < val) { val = ptr; } ptr -= val;
547fbc2003-08-22Martin Nilsson  ret = arr[ptr..ptr + val - 1];
a470d72000-12-01Johan Schön  for (int i=0; i < val; i++) { arr[ptr + i] = 0; /* Don't waste references */ } } else { if(--ptr < 0) error("Stack underflow\n");
3524712015-05-26Martin Nilsson 
547fbc2003-08-22Martin Nilsson  ret = arr[ptr];
a470d72000-12-01Johan Schön  arr[ptr]=0; /* Don't waste references */ }
547fbc2003-08-22Martin Nilsson  return ret;
a470d72000-12-01Johan Schön }
22cabf2001-08-14Martin Nilsson //! Empties the stack, resets the stack pointer //! and shrinks the stack size to the given value //! or 32 if none is given. //! @seealso //! @[create]
a470d72000-12-01Johan Schön void reset(int|void initial_size) { arr = allocate(initial_size || 32); ptr = 0; }
22cabf2001-08-14Martin Nilsson //! An initial stack size can be given when //! a stack is cloned. The default value is //! 32.
a470d72000-12-01Johan Schön void create(int|void initial_size) { arr = allocate(initial_size || 32); }
9304782002-03-25Martin Nilsson 
5631ee2002-03-26Martin Nilsson //! Sets the stacks content to the provided array. void set_stack(array stack) { arr = stack; ptr = sizeof(arr); } //! @[sizeof] on a stack returns the number of entries //! in the stack.
9304782002-03-25Martin Nilsson int _sizeof() { return ptr; }
5631ee2002-03-26Martin Nilsson  //! @[values] on a stack returns all the entries in //! the stack, in order. array _values() { return arr[..ptr-1]; }
0e18c32011-12-03Henrik Grubbström (Grubba) //! Return the stack-depth to @[item]. //! //! This function makes it possible to use //! eg @[search()] and @[has_value()] on the stack. protected int _search(mixed item) { int i; for (i = ptr; i--;) { if (arr[i] == item) return ptr-(i+1); } return -1; }
eb78562018-03-04Henrik Grubbström (Grubba) //! A stack added with another stack yields a new //! stack with all the elements from both stacks, //! and the elements from the second stack at the //! top of the new stack.
c6088c2002-06-14Martin Nilsson this_program `+(this_program s) {
5631ee2002-03-26Martin Nilsson  array elem = arr[..ptr-1]+values(s);
c6088c2002-06-14Martin Nilsson  this_program ns = this_program(1);
5631ee2002-03-26Martin Nilsson  ns->set_stack(elem); return ns; }
7091062014-08-18Martin Nilsson protected mixed cast(string to) { if( to=="array" ) return _values(); return UNDEFINED;
faec7b2005-12-14Martin Nilsson }
5631ee2002-03-26Martin Nilsson string _sprintf(int t) {
1a38432002-11-29Martin Nilsson  return t=='O' && sprintf("%O%O", this_program, _values());
5631ee2002-03-26Martin Nilsson }