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