1 /*******************************************************************
3 ** Forth Inspired Command Language
4 ** Author: John Sadler (john_sadler@alum.mit.edu)
5 ** Created: 16 Oct 1997
7 *******************************************************************/
9 /* $FreeBSD: src/sys/boot/ficl/stack.c,v 1.3 1999/09/29 04:43:07 dcs Exp $ */
18 #define STKDEPTH(s) ((s)->sp - (s)->base)
21 ** N O T E: Stack convention:
23 ** sp points to the first available cell
24 ** push: store value at sp, increment sp
25 ** pop: decrement sp, fetch value at sp
26 ** Stack grows from low to high memory
29 /*******************************************************************
30 v m C h e c k S t a c k
31 ** Check the parameter stack for underflow or overflow.
32 ** nCells controls the type of check: if nCells is zero,
33 ** the function checks the stack state for underflow and overflow.
34 ** If nCells > 0, checks to see that the stack has room to push
35 ** that many cells. If less than zero, checks to see that the
36 ** stack has room to pop that many cells. If any test fails,
37 ** the function throws (via vmThrow) a VM_ERREXIT exception.
38 *******************************************************************/
39 void vmCheckStack(FICL_VM *pVM, int popCells, int pushCells)
41 FICL_STACK *pStack = pVM->pStack;
42 int nFree = pStack->base + pStack->nCells - pStack->sp;
44 if (popCells > STKDEPTH(pStack))
46 vmThrowErr(pVM, "Error: stack underflow");
49 if (nFree < pushCells - popCells)
51 vmThrowErr(pVM, "Error: stack overflow");
57 /*******************************************************************
60 *******************************************************************/
62 FICL_STACK *stackCreate(unsigned nCells)
64 size_t size = sizeof (FICL_STACK) + nCells * sizeof (CELL);
65 FICL_STACK *pStack = ficlMalloc(size);
69 assert (pStack != NULL);
72 pStack->nCells = nCells;
73 pStack->sp = pStack->base;
74 pStack->pFrame = NULL;
79 /*******************************************************************
82 *******************************************************************/
84 void stackDelete(FICL_STACK *pStack)
92 /*******************************************************************
95 *******************************************************************/
97 int stackDepth(FICL_STACK *pStack)
99 return STKDEPTH(pStack);
102 /*******************************************************************
105 *******************************************************************/
107 void stackDrop(FICL_STACK *pStack, int n)
117 /*******************************************************************
120 *******************************************************************/
122 CELL stackFetch(FICL_STACK *pStack, int n)
124 return pStack->sp[-n-1];
127 void stackStore(FICL_STACK *pStack, int n, CELL c)
129 pStack->sp[-n-1] = c;
134 /*******************************************************************
135 s t a c k G e t T o p
137 *******************************************************************/
139 CELL stackGetTop(FICL_STACK *pStack)
141 return pStack->sp[-1];
145 /*******************************************************************
147 ** Link a frame using the stack's frame pointer. Allot space for
148 ** nCells cells in the frame
152 *******************************************************************/
154 void stackLink(FICL_STACK *pStack, int nCells)
156 stackPushPtr(pStack, pStack->pFrame);
157 pStack->pFrame = pStack->sp;
158 pStack->sp += nCells;
163 /*******************************************************************
164 s t a c k U n l i n k
165 ** Unink a stack frame previously created by stackLink
168 *******************************************************************/
170 void stackUnlink(FICL_STACK *pStack)
172 pStack->sp = pStack->pFrame;
173 pStack->pFrame = stackPopPtr(pStack);
178 /*******************************************************************
181 *******************************************************************/
183 void stackPick(FICL_STACK *pStack, int n)
185 stackPush(pStack, stackFetch(pStack, n));
190 /*******************************************************************
193 *******************************************************************/
195 CELL stackPop(FICL_STACK *pStack)
197 return *--pStack->sp;
200 void *stackPopPtr(FICL_STACK *pStack)
202 return (*--pStack->sp).p;
205 FICL_UNS stackPopUNS(FICL_STACK *pStack)
207 return (*--pStack->sp).u;
210 FICL_INT stackPopINT(FICL_STACK *pStack)
212 return (*--pStack->sp).i;
216 /*******************************************************************
219 *******************************************************************/
221 void stackPush(FICL_STACK *pStack, CELL c)
226 void stackPushPtr(FICL_STACK *pStack, void *ptr)
228 *pStack->sp++ = LVALUEtoCELL(ptr);
231 void stackPushUNS(FICL_STACK *pStack, FICL_UNS u)
233 *pStack->sp++ = LVALUEtoCELL(u);
236 void stackPushINT(FICL_STACK *pStack, FICL_INT i)
238 *pStack->sp++ = LVALUEtoCELL(i);
241 /*******************************************************************
244 *******************************************************************/
246 void stackReset(FICL_STACK *pStack)
248 pStack->sp = pStack->base;
253 /*******************************************************************
255 ** Roll nth stack entry to the top (counting from zero), if n is
256 ** >= 0. Drop other entries as needed to fill the hole.
257 ** If n < 0, roll top-of-stack to nth entry, pushing others
258 ** upward as needed to fill the hole.
259 *******************************************************************/
261 void stackRoll(FICL_STACK *pStack, int n)
270 pCell = pStack->sp - n - 1;
273 for (;n > 0; --n, pCell++)
282 pCell = pStack->sp - 1;
285 for (; n < 0; ++n, pCell--)
296 /*******************************************************************
297 s t a c k S e t T o p
299 *******************************************************************/
301 void stackSetTop(FICL_STACK *pStack, CELL c)