1 /*******************************************************************
3 ** Forth Inspired Command Language
4 ** Author: John Sadler (john_sadler@alum.mit.edu)
5 ** Created: 16 Oct 1997
6 ** $Id: stack.c,v 1.10 2001/12/05 07:21:34 jsadler Exp $
7 *******************************************************************/
9 ** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
10 ** All rights reserved.
12 ** Get the latest Ficl release at http://ficl.sourceforge.net
14 ** I am interested in hearing from anyone who uses ficl. If you have
15 ** a problem, a success story, a defect, an enhancement request, or
16 ** if you would like to contribute to the ficl release, please
17 ** contact me by email at the address above.
19 ** L I C E N S E and D I S C L A I M E R
21 ** Redistribution and use in source and binary forms, with or without
22 ** modification, are permitted provided that the following conditions
24 ** 1. Redistributions of source code must retain the above copyright
25 ** notice, this list of conditions and the following disclaimer.
26 ** 2. Redistributions in binary form must reproduce the above copyright
27 ** notice, this list of conditions and the following disclaimer in the
28 ** documentation and/or other materials provided with the distribution.
30 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
31 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 ** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
34 ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36 ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37 ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38 ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39 ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * $FreeBSD: src/sys/boot/ficl/stack.c,v 1.5 2002/04/09 17:45:11 dcs Exp $
45 * $DragonFly: src/sys/boot/ficl/stack.c,v 1.3 2003/11/10 06:08:33 dillon Exp $
55 #define STKDEPTH(s) ((s)->sp - (s)->base)
58 ** N O T E: Stack convention:
60 ** sp points to the first available cell
61 ** push: store value at sp, increment sp
62 ** pop: decrement sp, fetch value at sp
63 ** Stack grows from low to high memory
66 /*******************************************************************
67 v m C h e c k S t a c k
68 ** Check the parameter stack for underflow or overflow.
69 ** nCells controls the type of check: if nCells is zero,
70 ** the function checks the stack state for underflow and overflow.
71 ** If nCells > 0, checks to see that the stack has room to push
72 ** that many cells. If less than zero, checks to see that the
73 ** stack has room to pop that many cells. If any test fails,
74 ** the function throws (via vmThrow) a VM_ERREXIT exception.
75 *******************************************************************/
76 void vmCheckStack(FICL_VM *pVM, int popCells, int pushCells)
78 FICL_STACK *pStack = pVM->pStack;
79 int nFree = pStack->base + pStack->nCells - pStack->sp;
81 if (popCells > STKDEPTH(pStack))
83 vmThrowErr(pVM, "Error: stack underflow");
86 if (nFree < pushCells - popCells)
88 vmThrowErr(pVM, "Error: stack overflow");
95 void vmCheckFStack(FICL_VM *pVM, int popCells, int pushCells)
97 FICL_STACK *fStack = pVM->fStack;
98 int nFree = fStack->base + fStack->nCells - fStack->sp;
100 if (popCells > STKDEPTH(fStack))
102 vmThrowErr(pVM, "Error: float stack underflow");
105 if (nFree < pushCells - popCells)
107 vmThrowErr(pVM, "Error: float stack overflow");
112 /*******************************************************************
113 s t a c k C r e a t e
115 *******************************************************************/
117 FICL_STACK *stackCreate(unsigned nCells)
119 size_t size = sizeof (FICL_STACK) + nCells * sizeof (CELL);
120 FICL_STACK *pStack = ficlMalloc(size);
123 assert (nCells != 0);
124 assert (pStack != NULL);
127 pStack->nCells = nCells;
128 pStack->sp = pStack->base;
129 pStack->pFrame = NULL;
134 /*******************************************************************
135 s t a c k D e l e t e
137 *******************************************************************/
139 void stackDelete(FICL_STACK *pStack)
147 /*******************************************************************
150 *******************************************************************/
152 int stackDepth(FICL_STACK *pStack)
154 return STKDEPTH(pStack);
157 /*******************************************************************
160 *******************************************************************/
162 void stackDrop(FICL_STACK *pStack, int n)
172 /*******************************************************************
175 *******************************************************************/
177 CELL stackFetch(FICL_STACK *pStack, int n)
179 return pStack->sp[-n-1];
182 void stackStore(FICL_STACK *pStack, int n, CELL c)
184 pStack->sp[-n-1] = c;
189 /*******************************************************************
190 s t a c k G e t T o p
192 *******************************************************************/
194 CELL stackGetTop(FICL_STACK *pStack)
196 return pStack->sp[-1];
200 /*******************************************************************
202 ** Link a frame using the stack's frame pointer. Allot space for
203 ** nCells cells in the frame
207 *******************************************************************/
209 void stackLink(FICL_STACK *pStack, int nCells)
211 stackPushPtr(pStack, pStack->pFrame);
212 pStack->pFrame = pStack->sp;
213 pStack->sp += nCells;
218 /*******************************************************************
219 s t a c k U n l i n k
220 ** Unink a stack frame previously created by stackLink
223 *******************************************************************/
225 void stackUnlink(FICL_STACK *pStack)
227 pStack->sp = pStack->pFrame;
228 pStack->pFrame = stackPopPtr(pStack);
233 /*******************************************************************
236 *******************************************************************/
238 void stackPick(FICL_STACK *pStack, int n)
240 stackPush(pStack, stackFetch(pStack, n));
245 /*******************************************************************
248 *******************************************************************/
250 CELL stackPop(FICL_STACK *pStack)
252 return *--pStack->sp;
255 void *stackPopPtr(FICL_STACK *pStack)
257 return (*--pStack->sp).p;
260 FICL_UNS stackPopUNS(FICL_STACK *pStack)
262 return (*--pStack->sp).u;
265 FICL_INT stackPopINT(FICL_STACK *pStack)
267 return (*--pStack->sp).i;
270 #if (FICL_WANT_FLOAT)
271 float stackPopFloat(FICL_STACK *pStack)
273 return (*(--pStack->sp)).f;
277 /*******************************************************************
280 *******************************************************************/
282 void stackPush(FICL_STACK *pStack, CELL c)
287 void stackPushPtr(FICL_STACK *pStack, void *ptr)
289 *pStack->sp++ = LVALUEtoCELL(ptr);
292 void stackPushUNS(FICL_STACK *pStack, FICL_UNS u)
294 *pStack->sp++ = LVALUEtoCELL(u);
297 void stackPushINT(FICL_STACK *pStack, FICL_INT i)
299 *pStack->sp++ = LVALUEtoCELL(i);
302 #if (FICL_WANT_FLOAT)
303 void stackPushFloat(FICL_STACK *pStack, FICL_FLOAT f)
305 *pStack->sp++ = LVALUEtoCELL(f);
309 /*******************************************************************
312 *******************************************************************/
314 void stackReset(FICL_STACK *pStack)
316 pStack->sp = pStack->base;
321 /*******************************************************************
323 ** Roll nth stack entry to the top (counting from zero), if n is
324 ** >= 0. Drop other entries as needed to fill the hole.
325 ** If n < 0, roll top-of-stack to nth entry, pushing others
326 ** upward as needed to fill the hole.
327 *******************************************************************/
329 void stackRoll(FICL_STACK *pStack, int n)
338 pCell = pStack->sp - n - 1;
341 for (;n > 0; --n, pCell++)
350 pCell = pStack->sp - 1;
353 for (; n < 0; ++n, pCell--)
364 /*******************************************************************
365 s t a c k S e t T o p
367 *******************************************************************/
369 void stackSetTop(FICL_STACK *pStack, CELL c)