xref: /illumos-gate/usr/src/common/ficl/stack.c (revision afc2ba1d)
1*afc2ba1dSToomas Soome /*
2*afc2ba1dSToomas Soome  * s t a c k . c
3*afc2ba1dSToomas Soome  * Forth Inspired Command Language
4*afc2ba1dSToomas Soome  * Author: John Sadler (john_sadler@alum.mit.edu)
5*afc2ba1dSToomas Soome  * Created: 16 Oct 1997
6*afc2ba1dSToomas Soome  * $Id: stack.c,v 1.11 2010/08/12 13:57:22 asau Exp $
7*afc2ba1dSToomas Soome  */
8*afc2ba1dSToomas Soome /*
9*afc2ba1dSToomas Soome  * Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
10*afc2ba1dSToomas Soome  * All rights reserved.
11*afc2ba1dSToomas Soome  *
12*afc2ba1dSToomas Soome  * Get the latest Ficl release at http://ficl.sourceforge.net
13*afc2ba1dSToomas Soome  *
14*afc2ba1dSToomas Soome  * I am interested in hearing from anyone who uses Ficl. If you have
15*afc2ba1dSToomas Soome  * a problem, a success story, a defect, an enhancement request, or
16*afc2ba1dSToomas Soome  * if you would like to contribute to the Ficl release, please
17*afc2ba1dSToomas Soome  * contact me by email at the address above.
18*afc2ba1dSToomas Soome  *
19*afc2ba1dSToomas Soome  * L I C E N S E  and  D I S C L A I M E R
20*afc2ba1dSToomas Soome  *
21*afc2ba1dSToomas Soome  * Redistribution and use in source and binary forms, with or without
22*afc2ba1dSToomas Soome  * modification, are permitted provided that the following conditions
23*afc2ba1dSToomas Soome  * are met:
24*afc2ba1dSToomas Soome  * 1. Redistributions of source code must retain the above copyright
25*afc2ba1dSToomas Soome  *    notice, this list of conditions and the following disclaimer.
26*afc2ba1dSToomas Soome  * 2. Redistributions in binary form must reproduce the above copyright
27*afc2ba1dSToomas Soome  *    notice, this list of conditions and the following disclaimer in the
28*afc2ba1dSToomas Soome  *    documentation and/or other materials provided with the distribution.
29*afc2ba1dSToomas Soome  *
30*afc2ba1dSToomas Soome  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
31*afc2ba1dSToomas Soome  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32*afc2ba1dSToomas Soome  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33*afc2ba1dSToomas Soome  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
34*afc2ba1dSToomas Soome  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35*afc2ba1dSToomas Soome  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36*afc2ba1dSToomas Soome  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37*afc2ba1dSToomas Soome  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38*afc2ba1dSToomas Soome  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39*afc2ba1dSToomas Soome  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40*afc2ba1dSToomas Soome  * SUCH DAMAGE.
41*afc2ba1dSToomas Soome  */
42*afc2ba1dSToomas Soome 
43*afc2ba1dSToomas Soome #include "ficl.h"
44*afc2ba1dSToomas Soome 
45*afc2ba1dSToomas Soome #define	STKDEPTH(s)	(((s)->top - (s)->base) + 1)
46*afc2ba1dSToomas Soome 
47*afc2ba1dSToomas Soome /*
48*afc2ba1dSToomas Soome  * N O T E: Stack convention:
49*afc2ba1dSToomas Soome  *
50*afc2ba1dSToomas Soome  * THIS CHANGED IN FICL 4.0!
51*afc2ba1dSToomas Soome  *
52*afc2ba1dSToomas Soome  * top points to the *current* top data value
53*afc2ba1dSToomas Soome  * push: increment top, store value at top
54*afc2ba1dSToomas Soome  * pop:  fetch value at top, decrement top
55*afc2ba1dSToomas Soome  * Stack grows from low to high memory
56*afc2ba1dSToomas Soome  */
57*afc2ba1dSToomas Soome 
58*afc2ba1dSToomas Soome /*
59*afc2ba1dSToomas Soome  * v m C h e c k S t a c k
60*afc2ba1dSToomas Soome  * Check the parameter stack for underflow or overflow.
61*afc2ba1dSToomas Soome  * size controls the type of check: if size is zero,
62*afc2ba1dSToomas Soome  * the function checks the stack state for underflow and overflow.
63*afc2ba1dSToomas Soome  * If size > 0, checks to see that the stack has room to push
64*afc2ba1dSToomas Soome  * that many cells. If less than zero, checks to see that the
65*afc2ba1dSToomas Soome  * stack has room to pop that many cells. If any test fails,
66*afc2ba1dSToomas Soome  * the function throws (via vmThrow) a VM_ERREXIT exception.
67*afc2ba1dSToomas Soome  */
68*afc2ba1dSToomas Soome void
ficlStackCheck(ficlStack * stack,int popCells,int pushCells)69*afc2ba1dSToomas Soome ficlStackCheck(ficlStack *stack, int popCells, int pushCells)
70*afc2ba1dSToomas Soome {
71*afc2ba1dSToomas Soome #if FICL_ROBUST >= 1
72*afc2ba1dSToomas Soome 	int nFree = stack->size - STKDEPTH(stack);
73*afc2ba1dSToomas Soome 
74*afc2ba1dSToomas Soome 	if (popCells > STKDEPTH(stack))
75*afc2ba1dSToomas Soome 		ficlVmThrowError(stack->vm, "Error: %s stack underflow",
76*afc2ba1dSToomas Soome 		    stack->name);
77*afc2ba1dSToomas Soome 
78*afc2ba1dSToomas Soome 	if (nFree < pushCells - popCells)
79*afc2ba1dSToomas Soome 		ficlVmThrowError(stack->vm, "Error: %s stack overflow",
80*afc2ba1dSToomas Soome 		    stack->name);
81*afc2ba1dSToomas Soome #else /* FICL_ROBUST >= 1 */
82*afc2ba1dSToomas Soome 	FICL_IGNORE(stack);
83*afc2ba1dSToomas Soome 	FICL_IGNORE(popCells);
84*afc2ba1dSToomas Soome 	FICL_IGNORE(pushCells);
85*afc2ba1dSToomas Soome #endif /* FICL_ROBUST >= 1 */
86*afc2ba1dSToomas Soome }
87*afc2ba1dSToomas Soome 
88*afc2ba1dSToomas Soome /*
89*afc2ba1dSToomas Soome  * s t a c k C r e a t e
90*afc2ba1dSToomas Soome  */
91*afc2ba1dSToomas Soome 
92*afc2ba1dSToomas Soome ficlStack *
ficlStackCreate(ficlVm * vm,char * name,unsigned size)93*afc2ba1dSToomas Soome ficlStackCreate(ficlVm *vm, char *name, unsigned size)
94*afc2ba1dSToomas Soome {
95*afc2ba1dSToomas Soome 	size_t totalSize = sizeof (ficlStack) + (size * sizeof (ficlCell));
96*afc2ba1dSToomas Soome 	ficlStack *stack = ficlMalloc(totalSize);
97*afc2ba1dSToomas Soome 
98*afc2ba1dSToomas Soome 	FICL_VM_ASSERT(vm, size != 0);
99*afc2ba1dSToomas Soome 	FICL_VM_ASSERT(vm, stack != NULL);
100*afc2ba1dSToomas Soome 
101*afc2ba1dSToomas Soome 	stack->size = size;
102*afc2ba1dSToomas Soome 	stack->frame = NULL;
103*afc2ba1dSToomas Soome 
104*afc2ba1dSToomas Soome 	stack->vm = vm;
105*afc2ba1dSToomas Soome 	stack->name = name;
106*afc2ba1dSToomas Soome 
107*afc2ba1dSToomas Soome 	ficlStackReset(stack);
108*afc2ba1dSToomas Soome 	return (stack);
109*afc2ba1dSToomas Soome }
110*afc2ba1dSToomas Soome 
111*afc2ba1dSToomas Soome /*
112*afc2ba1dSToomas Soome  *                  s t a c k D e l e t e
113*afc2ba1dSToomas Soome  */
114*afc2ba1dSToomas Soome void
ficlStackDestroy(ficlStack * stack)115*afc2ba1dSToomas Soome ficlStackDestroy(ficlStack *stack)
116*afc2ba1dSToomas Soome {
117*afc2ba1dSToomas Soome 	if (stack)
118*afc2ba1dSToomas Soome 		ficlFree(stack);
119*afc2ba1dSToomas Soome }
120*afc2ba1dSToomas Soome 
121*afc2ba1dSToomas Soome /*
122*afc2ba1dSToomas Soome  * s t a c k D e p t h
123*afc2ba1dSToomas Soome  */
124*afc2ba1dSToomas Soome int
ficlStackDepth(ficlStack * stack)125*afc2ba1dSToomas Soome ficlStackDepth(ficlStack *stack)
126*afc2ba1dSToomas Soome {
127*afc2ba1dSToomas Soome 	return (STKDEPTH(stack));
128*afc2ba1dSToomas Soome }
129*afc2ba1dSToomas Soome 
130*afc2ba1dSToomas Soome /*
131*afc2ba1dSToomas Soome  * s t a c k D r o p
132*afc2ba1dSToomas Soome  */
133*afc2ba1dSToomas Soome void
ficlStackDrop(ficlStack * stack,int n)134*afc2ba1dSToomas Soome ficlStackDrop(ficlStack *stack, int n)
135*afc2ba1dSToomas Soome {
136*afc2ba1dSToomas Soome 	FICL_VM_ASSERT(stack->vm, n > 0);
137*afc2ba1dSToomas Soome 	stack->top -= n;
138*afc2ba1dSToomas Soome }
139*afc2ba1dSToomas Soome 
140*afc2ba1dSToomas Soome /*
141*afc2ba1dSToomas Soome  * s t a c k F e t c h
142*afc2ba1dSToomas Soome  */
143*afc2ba1dSToomas Soome ficlCell
ficlStackFetch(ficlStack * stack,int n)144*afc2ba1dSToomas Soome ficlStackFetch(ficlStack *stack, int n)
145*afc2ba1dSToomas Soome {
146*afc2ba1dSToomas Soome 	return (stack->top[-n]);
147*afc2ba1dSToomas Soome }
148*afc2ba1dSToomas Soome 
149*afc2ba1dSToomas Soome void
ficlStackStore(ficlStack * stack,int n,ficlCell c)150*afc2ba1dSToomas Soome ficlStackStore(ficlStack *stack, int n, ficlCell c)
151*afc2ba1dSToomas Soome {
152*afc2ba1dSToomas Soome 	stack->top[-n] = c;
153*afc2ba1dSToomas Soome }
154*afc2ba1dSToomas Soome 
155*afc2ba1dSToomas Soome /*
156*afc2ba1dSToomas Soome  * s t a c k G e t T o p
157*afc2ba1dSToomas Soome  */
158*afc2ba1dSToomas Soome ficlCell
ficlStackGetTop(ficlStack * stack)159*afc2ba1dSToomas Soome ficlStackGetTop(ficlStack *stack)
160*afc2ba1dSToomas Soome {
161*afc2ba1dSToomas Soome 	return (stack->top[0]);
162*afc2ba1dSToomas Soome }
163*afc2ba1dSToomas Soome 
164*afc2ba1dSToomas Soome #if FICL_WANT_LOCALS
165*afc2ba1dSToomas Soome /*
166*afc2ba1dSToomas Soome  * s t a c k L i n k
167*afc2ba1dSToomas Soome  * Link a frame using the stack's frame pointer. Allot space for
168*afc2ba1dSToomas Soome  * size cells in the frame
169*afc2ba1dSToomas Soome  * 1) Push frame
170*afc2ba1dSToomas Soome  * 2) frame = top
171*afc2ba1dSToomas Soome  * 3) top += size
172*afc2ba1dSToomas Soome  */
173*afc2ba1dSToomas Soome void
ficlStackLink(ficlStack * stack,int size)174*afc2ba1dSToomas Soome ficlStackLink(ficlStack *stack, int size)
175*afc2ba1dSToomas Soome {
176*afc2ba1dSToomas Soome 	ficlStackPushPointer(stack, stack->frame);
177*afc2ba1dSToomas Soome 	stack->frame = stack->top + 1;
178*afc2ba1dSToomas Soome 	stack->top += size;
179*afc2ba1dSToomas Soome }
180*afc2ba1dSToomas Soome 
181*afc2ba1dSToomas Soome /*
182*afc2ba1dSToomas Soome  * s t a c k U n l i n k
183*afc2ba1dSToomas Soome  * Unink a stack frame previously created by stackLink
184*afc2ba1dSToomas Soome  * 1) top = frame
185*afc2ba1dSToomas Soome  * 2) frame = pop()
186*afc2ba1dSToomas Soome  */
187*afc2ba1dSToomas Soome void
ficlStackUnlink(ficlStack * stack)188*afc2ba1dSToomas Soome ficlStackUnlink(ficlStack *stack)
189*afc2ba1dSToomas Soome {
190*afc2ba1dSToomas Soome 	stack->top = stack->frame - 1;
191*afc2ba1dSToomas Soome 	stack->frame = ficlStackPopPointer(stack);
192*afc2ba1dSToomas Soome }
193*afc2ba1dSToomas Soome #endif /* FICL_WANT_LOCALS */
194*afc2ba1dSToomas Soome 
195*afc2ba1dSToomas Soome /*
196*afc2ba1dSToomas Soome  *                  s t a c k P i c k
197*afc2ba1dSToomas Soome  */
198*afc2ba1dSToomas Soome void
ficlStackPick(ficlStack * stack,int n)199*afc2ba1dSToomas Soome ficlStackPick(ficlStack *stack, int n)
200*afc2ba1dSToomas Soome {
201*afc2ba1dSToomas Soome 	ficlStackPush(stack, ficlStackFetch(stack, n));
202*afc2ba1dSToomas Soome }
203*afc2ba1dSToomas Soome 
204*afc2ba1dSToomas Soome /*
205*afc2ba1dSToomas Soome  * s t a c k P o p
206*afc2ba1dSToomas Soome  */
207*afc2ba1dSToomas Soome ficlCell
ficlStackPop(ficlStack * stack)208*afc2ba1dSToomas Soome ficlStackPop(ficlStack *stack)
209*afc2ba1dSToomas Soome {
210*afc2ba1dSToomas Soome 	return (*stack->top--);
211*afc2ba1dSToomas Soome }
212*afc2ba1dSToomas Soome 
213*afc2ba1dSToomas Soome void *
ficlStackPopPointer(ficlStack * stack)214*afc2ba1dSToomas Soome ficlStackPopPointer(ficlStack *stack)
215*afc2ba1dSToomas Soome {
216*afc2ba1dSToomas Soome 	return ((*stack->top--).p);
217*afc2ba1dSToomas Soome }
218*afc2ba1dSToomas Soome 
219*afc2ba1dSToomas Soome ficlUnsigned
ficlStackPopUnsigned(ficlStack * stack)220*afc2ba1dSToomas Soome ficlStackPopUnsigned(ficlStack *stack)
221*afc2ba1dSToomas Soome {
222*afc2ba1dSToomas Soome 	return ((*stack->top--).u);
223*afc2ba1dSToomas Soome }
224*afc2ba1dSToomas Soome 
225*afc2ba1dSToomas Soome ficlInteger
ficlStackPopInteger(ficlStack * stack)226*afc2ba1dSToomas Soome ficlStackPopInteger(ficlStack *stack)
227*afc2ba1dSToomas Soome {
228*afc2ba1dSToomas Soome 	return ((*stack->top--).i);
229*afc2ba1dSToomas Soome }
230*afc2ba1dSToomas Soome 
231*afc2ba1dSToomas Soome ficl2Integer
ficlStackPop2Integer(ficlStack * stack)232*afc2ba1dSToomas Soome ficlStackPop2Integer(ficlStack *stack)
233*afc2ba1dSToomas Soome {
234*afc2ba1dSToomas Soome 	ficl2Integer ret;
235*afc2ba1dSToomas Soome 	ficlInteger high = ficlStackPopInteger(stack);
236*afc2ba1dSToomas Soome 	ficlInteger low = ficlStackPopInteger(stack);
237*afc2ba1dSToomas Soome 	FICL_2INTEGER_SET(high, low, ret);
238*afc2ba1dSToomas Soome 	return (ret);
239*afc2ba1dSToomas Soome }
240*afc2ba1dSToomas Soome 
241*afc2ba1dSToomas Soome ficl2Unsigned
ficlStackPop2Unsigned(ficlStack * stack)242*afc2ba1dSToomas Soome ficlStackPop2Unsigned(ficlStack *stack)
243*afc2ba1dSToomas Soome {
244*afc2ba1dSToomas Soome 	ficl2Unsigned ret;
245*afc2ba1dSToomas Soome 	ficlUnsigned high = ficlStackPopUnsigned(stack);
246*afc2ba1dSToomas Soome 	ficlUnsigned low = ficlStackPopUnsigned(stack);
247*afc2ba1dSToomas Soome 	FICL_2UNSIGNED_SET(high, low, ret);
248*afc2ba1dSToomas Soome 	return (ret);
249*afc2ba1dSToomas Soome }
250*afc2ba1dSToomas Soome 
251*afc2ba1dSToomas Soome #if (FICL_WANT_FLOAT)
252*afc2ba1dSToomas Soome ficlFloat
ficlStackPopFloat(ficlStack * stack)253*afc2ba1dSToomas Soome ficlStackPopFloat(ficlStack *stack)
254*afc2ba1dSToomas Soome {
255*afc2ba1dSToomas Soome 	return ((*stack->top--).f);
256*afc2ba1dSToomas Soome }
257*afc2ba1dSToomas Soome #endif
258*afc2ba1dSToomas Soome 
259*afc2ba1dSToomas Soome /*
260*afc2ba1dSToomas Soome  * s t a c k P u s h
261*afc2ba1dSToomas Soome  */
262*afc2ba1dSToomas Soome void
ficlStackPush(ficlStack * stack,ficlCell c)263*afc2ba1dSToomas Soome ficlStackPush(ficlStack *stack, ficlCell c)
264*afc2ba1dSToomas Soome {
265*afc2ba1dSToomas Soome 	*++stack->top = c;
266*afc2ba1dSToomas Soome }
267*afc2ba1dSToomas Soome 
268*afc2ba1dSToomas Soome void
ficlStackPushPointer(ficlStack * stack,void * ptr)269*afc2ba1dSToomas Soome ficlStackPushPointer(ficlStack *stack, void *ptr)
270*afc2ba1dSToomas Soome {
271*afc2ba1dSToomas Soome 	ficlCell c;
272*afc2ba1dSToomas Soome 
273*afc2ba1dSToomas Soome 	c.p = ptr;
274*afc2ba1dSToomas Soome 	*++stack->top = c;
275*afc2ba1dSToomas Soome }
276*afc2ba1dSToomas Soome 
277*afc2ba1dSToomas Soome void
ficlStackPushInteger(ficlStack * stack,ficlInteger i)278*afc2ba1dSToomas Soome ficlStackPushInteger(ficlStack *stack, ficlInteger i)
279*afc2ba1dSToomas Soome {
280*afc2ba1dSToomas Soome 	ficlCell c;
281*afc2ba1dSToomas Soome 
282*afc2ba1dSToomas Soome 	c.i = i;
283*afc2ba1dSToomas Soome 	*++stack->top = c;
284*afc2ba1dSToomas Soome }
285*afc2ba1dSToomas Soome 
286*afc2ba1dSToomas Soome void
ficlStackPushUnsigned(ficlStack * stack,ficlUnsigned u)287*afc2ba1dSToomas Soome ficlStackPushUnsigned(ficlStack *stack, ficlUnsigned u)
288*afc2ba1dSToomas Soome {
289*afc2ba1dSToomas Soome 	ficlCell c;
290*afc2ba1dSToomas Soome 
291*afc2ba1dSToomas Soome 	c.u = u;
292*afc2ba1dSToomas Soome 	*++stack->top = c;
293*afc2ba1dSToomas Soome }
294*afc2ba1dSToomas Soome 
295*afc2ba1dSToomas Soome void
ficlStackPush2Unsigned(ficlStack * stack,ficl2Unsigned du)296*afc2ba1dSToomas Soome ficlStackPush2Unsigned(ficlStack *stack, ficl2Unsigned du)
297*afc2ba1dSToomas Soome {
298*afc2ba1dSToomas Soome 	ficlStackPushUnsigned(stack, FICL_2UNSIGNED_GET_LOW(du));
299*afc2ba1dSToomas Soome 	ficlStackPushUnsigned(stack, FICL_2UNSIGNED_GET_HIGH(du));
300*afc2ba1dSToomas Soome }
301*afc2ba1dSToomas Soome 
302*afc2ba1dSToomas Soome void
ficlStackPush2Integer(ficlStack * stack,ficl2Integer di)303*afc2ba1dSToomas Soome ficlStackPush2Integer(ficlStack *stack, ficl2Integer di)
304*afc2ba1dSToomas Soome {
305*afc2ba1dSToomas Soome 	ficl2Unsigned du;
306*afc2ba1dSToomas Soome 	FICL_2UNSIGNED_SET(FICL_2UNSIGNED_GET_HIGH(di),
307*afc2ba1dSToomas Soome 	    FICL_2UNSIGNED_GET_LOW(di), du);
308*afc2ba1dSToomas Soome 	ficlStackPush2Unsigned(stack, du);
309*afc2ba1dSToomas Soome }
310*afc2ba1dSToomas Soome 
311*afc2ba1dSToomas Soome #if (FICL_WANT_FLOAT)
312*afc2ba1dSToomas Soome void
ficlStackPushFloat(ficlStack * stack,ficlFloat f)313*afc2ba1dSToomas Soome ficlStackPushFloat(ficlStack *stack, ficlFloat f)
314*afc2ba1dSToomas Soome {
315*afc2ba1dSToomas Soome 	ficlCell c;
316*afc2ba1dSToomas Soome 
317*afc2ba1dSToomas Soome 	c.f = f;
318*afc2ba1dSToomas Soome 	*++stack->top = c;
319*afc2ba1dSToomas Soome }
320*afc2ba1dSToomas Soome #endif
321*afc2ba1dSToomas Soome 
322*afc2ba1dSToomas Soome /*
323*afc2ba1dSToomas Soome  * s t a c k R e s e t
324*afc2ba1dSToomas Soome  */
325*afc2ba1dSToomas Soome void
ficlStackReset(ficlStack * stack)326*afc2ba1dSToomas Soome ficlStackReset(ficlStack *stack)
327*afc2ba1dSToomas Soome {
328*afc2ba1dSToomas Soome 	stack->top = stack->base - 1;
329*afc2ba1dSToomas Soome }
330*afc2ba1dSToomas Soome 
331*afc2ba1dSToomas Soome /*
332*afc2ba1dSToomas Soome  * s t a c k R o l l
333*afc2ba1dSToomas Soome  * Roll nth stack entry to the top (counting from zero), if n is
334*afc2ba1dSToomas Soome  * >= 0. Drop other entries as needed to fill the hole.
335*afc2ba1dSToomas Soome  * If n < 0, roll top-of-stack to nth entry, pushing others
336*afc2ba1dSToomas Soome  * upward as needed to fill the hole.
337*afc2ba1dSToomas Soome  */
338*afc2ba1dSToomas Soome void
ficlStackRoll(ficlStack * stack,int n)339*afc2ba1dSToomas Soome ficlStackRoll(ficlStack *stack, int n)
340*afc2ba1dSToomas Soome {
341*afc2ba1dSToomas Soome 	ficlCell c;
342*afc2ba1dSToomas Soome 	ficlCell *cell;
343*afc2ba1dSToomas Soome 
344*afc2ba1dSToomas Soome 	if (n == 0)
345*afc2ba1dSToomas Soome 		return;
346*afc2ba1dSToomas Soome 	else if (n > 0) {
347*afc2ba1dSToomas Soome 		cell = stack->top - n;
348*afc2ba1dSToomas Soome 		c = *cell;
349*afc2ba1dSToomas Soome 
350*afc2ba1dSToomas Soome 		for (; n > 0; --n, cell++) {
351*afc2ba1dSToomas Soome 			*cell = cell[1];
352*afc2ba1dSToomas Soome 		}
353*afc2ba1dSToomas Soome 
354*afc2ba1dSToomas Soome 		*cell = c;
355*afc2ba1dSToomas Soome 	} else {
356*afc2ba1dSToomas Soome 		cell = stack->top;
357*afc2ba1dSToomas Soome 		c = *cell;
358*afc2ba1dSToomas Soome 
359*afc2ba1dSToomas Soome 		for (; n < 0; ++n, cell--) {
360*afc2ba1dSToomas Soome 			*cell = cell[-1];
361*afc2ba1dSToomas Soome 		}
362*afc2ba1dSToomas Soome 
363*afc2ba1dSToomas Soome 		*cell = c;
364*afc2ba1dSToomas Soome 	}
365*afc2ba1dSToomas Soome }
366*afc2ba1dSToomas Soome 
367*afc2ba1dSToomas Soome /*
368*afc2ba1dSToomas Soome  * s t a c k S e t T o p
369*afc2ba1dSToomas Soome  */
370*afc2ba1dSToomas Soome void
ficlStackSetTop(ficlStack * stack,ficlCell c)371*afc2ba1dSToomas Soome ficlStackSetTop(ficlStack *stack, ficlCell c)
372*afc2ba1dSToomas Soome {
373*afc2ba1dSToomas Soome 	FICL_STACK_CHECK(stack, 1, 1);
374*afc2ba1dSToomas Soome 	stack->top[0] = c;
375*afc2ba1dSToomas Soome }
376*afc2ba1dSToomas Soome 
377*afc2ba1dSToomas Soome void
ficlStackWalk(ficlStack * stack,ficlStackWalkFunction callback,void * context,ficlInteger bottomToTop)378*afc2ba1dSToomas Soome ficlStackWalk(ficlStack *stack, ficlStackWalkFunction callback,
379*afc2ba1dSToomas Soome     void *context, ficlInteger bottomToTop)
380*afc2ba1dSToomas Soome {
381*afc2ba1dSToomas Soome 	int i;
382*afc2ba1dSToomas Soome 	int depth;
383*afc2ba1dSToomas Soome 	ficlCell *cell;
384*afc2ba1dSToomas Soome 	FICL_STACK_CHECK(stack, 0, 0);
385*afc2ba1dSToomas Soome 
386*afc2ba1dSToomas Soome 	depth = ficlStackDepth(stack);
387*afc2ba1dSToomas Soome 	cell = bottomToTop ? stack->base : stack->top;
388*afc2ba1dSToomas Soome 	for (i = 0; i < depth; i++) {
389*afc2ba1dSToomas Soome 		if (callback(context, cell) == FICL_FALSE)
390*afc2ba1dSToomas Soome 			break;
391*afc2ba1dSToomas Soome 		cell += bottomToTop ? 1 : -1;
392*afc2ba1dSToomas Soome 	}
393*afc2ba1dSToomas Soome }
394