Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / sys / boot / ficl / stack.c
1 /*******************************************************************
2 ** s t a c k . c
3 ** Forth Inspired Command Language
4 ** Author: John Sadler (john_sadler@alum.mit.edu)
5 ** Created: 16 Oct 1997
6 ** 
7 *******************************************************************/
8
9 /* $FreeBSD: src/sys/boot/ficl/stack.c,v 1.3 1999/09/29 04:43:07 dcs Exp $ */
10 /* $DragonFly: src/sys/boot/ficl/stack.c,v 1.2 2003/06/17 04:28:17 dillon Exp $ */
11
12 #ifdef TESTMAIN
13 #include <stdlib.h>
14 #else
15 #include <stand.h>
16 #endif
17 #include "ficl.h"
18
19 #define STKDEPTH(s) ((s)->sp - (s)->base)
20
21 /*
22 ** N O T E: Stack convention:
23 **
24 ** sp points to the first available cell
25 ** push: store value at sp, increment sp
26 ** pop:  decrement sp, fetch value at sp
27 ** Stack grows from low to high memory
28 */
29
30 /*******************************************************************
31                     v m C h e c k S t a c k
32 ** Check the parameter stack for underflow or overflow.
33 ** nCells controls the type of check: if nCells is zero,
34 ** the function checks the stack state for underflow and overflow.
35 ** If nCells > 0, checks to see that the stack has room to push
36 ** that many cells. If less than zero, checks to see that the
37 ** stack has room to pop that many cells. If any test fails,
38 ** the function throws (via vmThrow) a VM_ERREXIT exception.
39 *******************************************************************/
40 void vmCheckStack(FICL_VM *pVM, int popCells, int pushCells)
41 {
42     FICL_STACK *pStack = pVM->pStack;
43     int nFree = pStack->base + pStack->nCells - pStack->sp;
44
45     if (popCells > STKDEPTH(pStack))
46     {
47         vmThrowErr(pVM, "Error: stack underflow");
48     }
49
50     if (nFree < pushCells - popCells)
51     {
52         vmThrowErr(pVM, "Error: stack overflow");
53     }
54
55     return;
56 }
57
58 /*******************************************************************
59                     s t a c k C r e a t e
60 ** 
61 *******************************************************************/
62
63 FICL_STACK *stackCreate(unsigned nCells)
64 {
65     size_t size = sizeof (FICL_STACK) + nCells * sizeof (CELL);
66     FICL_STACK *pStack = ficlMalloc(size);
67
68 #if FICL_ROBUST
69     assert (nCells != 0);
70     assert (pStack != NULL);
71 #endif
72
73     pStack->nCells = nCells;
74     pStack->sp     = pStack->base;
75     pStack->pFrame = NULL;
76     return pStack;
77 }
78
79
80 /*******************************************************************
81                     s t a c k D e l e t e
82 ** 
83 *******************************************************************/
84
85 void stackDelete(FICL_STACK *pStack)
86 {
87     if (pStack)
88         ficlFree(pStack);
89     return;
90 }
91
92
93 /*******************************************************************
94                     s t a c k D e p t h 
95 ** 
96 *******************************************************************/
97
98 int stackDepth(FICL_STACK *pStack)
99 {
100     return STKDEPTH(pStack);
101 }
102
103 /*******************************************************************
104                     s t a c k D r o p
105 ** 
106 *******************************************************************/
107
108 void stackDrop(FICL_STACK *pStack, int n)
109 {
110 #if FICL_ROBUST
111     assert(n > 0);
112 #endif
113     pStack->sp -= n;
114     return;
115 }
116
117
118 /*******************************************************************
119                     s t a c k F e t c h
120 ** 
121 *******************************************************************/
122
123 CELL stackFetch(FICL_STACK *pStack, int n)
124 {
125     return pStack->sp[-n-1];
126 }
127
128 void stackStore(FICL_STACK *pStack, int n, CELL c)
129 {
130     pStack->sp[-n-1] = c;
131     return;
132 }
133
134
135 /*******************************************************************
136                     s t a c k G e t T o p
137 ** 
138 *******************************************************************/
139
140 CELL stackGetTop(FICL_STACK *pStack)
141 {
142     return pStack->sp[-1];
143 }
144
145
146 /*******************************************************************
147                     s t a c k L i n k
148 ** Link a frame using the stack's frame pointer. Allot space for
149 ** nCells cells in the frame
150 ** 1) Push pFrame
151 ** 2) pFrame = sp
152 ** 3) sp += nCells
153 *******************************************************************/
154
155 void stackLink(FICL_STACK *pStack, int nCells)
156 {
157     stackPushPtr(pStack, pStack->pFrame);
158     pStack->pFrame = pStack->sp;
159     pStack->sp += nCells;
160     return;
161 }
162
163
164 /*******************************************************************
165                     s t a c k U n l i n k
166 ** Unink a stack frame previously created by stackLink
167 ** 1) sp = pFrame
168 ** 2) pFrame = pop()
169 *******************************************************************/
170
171 void stackUnlink(FICL_STACK *pStack)
172 {
173     pStack->sp = pStack->pFrame;
174     pStack->pFrame = stackPopPtr(pStack);
175     return;
176 }
177
178
179 /*******************************************************************
180                     s t a c k P i c k
181 ** 
182 *******************************************************************/
183
184 void stackPick(FICL_STACK *pStack, int n)
185 {
186     stackPush(pStack, stackFetch(pStack, n));
187     return;
188 }
189
190
191 /*******************************************************************
192                     s t a c k P o p
193 ** 
194 *******************************************************************/
195
196 CELL stackPop(FICL_STACK *pStack)
197 {
198     return *--pStack->sp;
199 }
200
201 void *stackPopPtr(FICL_STACK *pStack)
202 {
203     return (*--pStack->sp).p;
204 }
205
206 FICL_UNS stackPopUNS(FICL_STACK *pStack)
207 {
208     return (*--pStack->sp).u;
209 }
210
211 FICL_INT stackPopINT(FICL_STACK *pStack)
212 {
213     return (*--pStack->sp).i;
214 }
215
216
217 /*******************************************************************
218                     s t a c k P u s h
219 ** 
220 *******************************************************************/
221
222 void stackPush(FICL_STACK *pStack, CELL c)
223 {
224     *pStack->sp++ = c;
225 }
226
227 void stackPushPtr(FICL_STACK *pStack, void *ptr)
228 {
229     *pStack->sp++ = LVALUEtoCELL(ptr);
230 }
231
232 void stackPushUNS(FICL_STACK *pStack, FICL_UNS u)
233 {
234     *pStack->sp++ = LVALUEtoCELL(u);
235 }
236
237 void stackPushINT(FICL_STACK *pStack, FICL_INT i)
238 {
239     *pStack->sp++ = LVALUEtoCELL(i);
240 }
241
242 /*******************************************************************
243                     s t a c k R e s e t
244 ** 
245 *******************************************************************/
246
247 void stackReset(FICL_STACK *pStack)
248 {
249     pStack->sp = pStack->base;
250     return;
251 }
252
253
254 /*******************************************************************
255                     s t a c k R o l l 
256 ** Roll nth stack entry to the top (counting from zero), if n is 
257 ** >= 0. Drop other entries as needed to fill the hole.
258 ** If n < 0, roll top-of-stack to nth entry, pushing others
259 ** upward as needed to fill the hole.
260 *******************************************************************/
261
262 void stackRoll(FICL_STACK *pStack, int n)
263 {
264     CELL c;
265     CELL *pCell;
266
267     if (n == 0)
268         return;
269     else if (n > 0)
270     {
271         pCell = pStack->sp - n - 1;
272         c = *pCell;
273
274         for (;n > 0; --n, pCell++)
275         {
276             *pCell = pCell[1];
277         }
278
279         *pCell = c;
280     }
281     else
282     {
283         pCell = pStack->sp - 1;
284         c = *pCell;
285
286         for (; n < 0; ++n, pCell--)
287         {
288             *pCell = pCell[-1];
289         }
290
291         *pCell = c;
292     }
293     return;
294 }
295
296
297 /*******************************************************************
298                     s t a c k S e t T o p
299 ** 
300 *******************************************************************/
301
302 void stackSetTop(FICL_STACK *pStack, CELL c)
303 {
304     pStack->sp[-1] = c;
305     return;
306 }
307
308