#include "lisp.h" /* stack routines for SIMULISP */ /* stack is implemented a linked list of pages each containing OBJPAGESIZE-1 * objects. The first entry in each page points to the last stack page, if * any. */ page *o_stack; /* pointer to current stack page */ int stack_index; /* index of top of stack */ /* initialize stack */ i_stack() { o_stack = NULL; stack_index = 0; } /* push object onto stack. returns its argument. */ object push(obj) object obj; { register page *current = o_stack; /* if we need new stack page, get one */ if (stack_index==OBJPAGESIZE-1 || current==NULL) { o_stack = al_page(0); (*o_stack)[0] = (object)current; current = o_stack; stack_index = 0; } /* there is room in current page, push object and return */ (*current)[++stack_index] = obj; return(obj); } /* pop n objects off the stack. returns former top of stack. */ object pop(n) register int n; { register page *current = o_stack; object tos; tos = (current==NULL)? NULL : (*current)[stack_index]; /* pop off pages til we get to the one we want */ while (n >= stack_index) { if (current == NULL) { error("; overpopped stack\n\n"); return(tos); } o_stack = (page *)((*current)[0]); n -= stack_index; fr_page(current); current = o_stack; stack_index = OBJPAGESIZE-1; } /* pop what we need to off this page, then we're done */ stack_index -= n; return(tos); } /* return nth object from top of stack. */ object nth_stack(n) register int n; { register page *current = o_stack; register int current_index = stack_index; /* run through pages til we get to the one we want */ while (n >= current_index) { if (current==NULL) { error(";looking too far into stack\n\n"); return(NULL); } n -= current_index; current = (page *)((*current)[0]); current_index = OBJPAGESIZE-1; } /* what we need is in this page */ return((*current)[current_index - n]); } /* replace nth object from top of stack with given object, returns what was there */ object nth_exch(n,obj) register int n; object obj; { register page *current = o_stack; register int current_index = stack_index; object old; /* run through pages til we get to the one we want */ while (n >= current_index) { if (current==NULL) { error(";looking too far into stack\n\n"); return(NULL); } current = (page *)((*current)[0]); n -= current_index; current_index = OBJPAGESIZE-1; } /* what we need is in this page */ old = (*current)[current_index - n]; (*current)[current_index - n] = obj; return(old); } /* mark stack for garbage collection */ m_stack() { register page *current = o_stack; register int current_index = stack_index; /* run through pages til we get to bottom of things */ while (current != NULL) { while (current_index) m_obj((*current)[current_index--]); current = (page *)((*current)[0]); current_index = OBJPAGESIZE-1; } }