stack.c revision 76116
140843Smsmith/******************************************************************* 240843Smsmith** s t a c k . c 340843Smsmith** Forth Inspired Command Language 440843Smsmith** Author: John Sadler (john_sadler@alum.mit.edu) 540843Smsmith** Created: 16 Oct 1997 676116Sdcs** $Id: stack.c,v 1.5 2001-04-26 21:41:29-07 jsadler Exp jsadler $ 776116Sdcs*******************************************************************/ 876116Sdcs/* 976116Sdcs** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu) 1076116Sdcs** All rights reserved. 1176116Sdcs** 1276116Sdcs** Get the latest Ficl release at http://ficl.sourceforge.net 1376116Sdcs** 1476116Sdcs** L I C E N S E and D I S C L A I M E R 1540843Smsmith** 1676116Sdcs** Redistribution and use in source and binary forms, with or without 1776116Sdcs** modification, are permitted provided that the following conditions 1876116Sdcs** are met: 1976116Sdcs** 1. Redistributions of source code must retain the above copyright 2076116Sdcs** notice, this list of conditions and the following disclaimer. 2176116Sdcs** 2. Redistributions in binary form must reproduce the above copyright 2276116Sdcs** notice, this list of conditions and the following disclaimer in the 2376116Sdcs** documentation and/or other materials provided with the distribution. 2476116Sdcs** 2576116Sdcs** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2676116Sdcs** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2776116Sdcs** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2876116Sdcs** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2976116Sdcs** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3076116Sdcs** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3176116Sdcs** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3276116Sdcs** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3376116Sdcs** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3476116Sdcs** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3576116Sdcs** SUCH DAMAGE. 3676116Sdcs** 3776116Sdcs** I am interested in hearing from anyone who uses ficl. If you have 3876116Sdcs** a problem, a success story, a defect, an enhancement request, or 3976116Sdcs** if you would like to contribute to the ficl release, please send 4076116Sdcs** contact me by email at the address above. 4176116Sdcs** 4276116Sdcs** $Id: stack.c,v 1.5 2001-04-26 21:41:29-07 jsadler Exp jsadler $ 4376116Sdcs*/ 4440883Smsmith 4551786Sdcs/* $FreeBSD: head/sys/boot/ficl/stack.c 76116 2001-04-29 02:36:36Z dcs $ */ 4651786Sdcs 4740883Smsmith#ifdef TESTMAIN 4840843Smsmith#include <stdlib.h> 4940883Smsmith#else 5040883Smsmith#include <stand.h> 5140883Smsmith#endif 5240843Smsmith#include "ficl.h" 5340843Smsmith 5440843Smsmith#define STKDEPTH(s) ((s)->sp - (s)->base) 5540843Smsmith 5640843Smsmith/* 5740843Smsmith** N O T E: Stack convention: 5840843Smsmith** 5940843Smsmith** sp points to the first available cell 6040843Smsmith** push: store value at sp, increment sp 6140843Smsmith** pop: decrement sp, fetch value at sp 6240843Smsmith** Stack grows from low to high memory 6340843Smsmith*/ 6440843Smsmith 6540843Smsmith/******************************************************************* 6640843Smsmith v m C h e c k S t a c k 6740843Smsmith** Check the parameter stack for underflow or overflow. 6840843Smsmith** nCells controls the type of check: if nCells is zero, 6940843Smsmith** the function checks the stack state for underflow and overflow. 7040843Smsmith** If nCells > 0, checks to see that the stack has room to push 7140843Smsmith** that many cells. If less than zero, checks to see that the 7240843Smsmith** stack has room to pop that many cells. If any test fails, 7340843Smsmith** the function throws (via vmThrow) a VM_ERREXIT exception. 7440843Smsmith*******************************************************************/ 7540843Smsmithvoid vmCheckStack(FICL_VM *pVM, int popCells, int pushCells) 7640843Smsmith{ 7740843Smsmith FICL_STACK *pStack = pVM->pStack; 7840843Smsmith int nFree = pStack->base + pStack->nCells - pStack->sp; 7940843Smsmith 8040843Smsmith if (popCells > STKDEPTH(pStack)) 8140843Smsmith { 8240843Smsmith vmThrowErr(pVM, "Error: stack underflow"); 8340843Smsmith } 8440843Smsmith 8540843Smsmith if (nFree < pushCells - popCells) 8640843Smsmith { 8740843Smsmith vmThrowErr(pVM, "Error: stack overflow"); 8840843Smsmith } 8940843Smsmith 9040843Smsmith return; 9140843Smsmith} 9240843Smsmith 9376116Sdcs#if FICL_WANT_FLOAT 9476116Sdcsvoid vmCheckFStack(FICL_VM *pVM, int popCells, int pushCells) 9576116Sdcs{ 9676116Sdcs FICL_STACK *fStack = pVM->fStack; 9776116Sdcs int nFree = fStack->base + fStack->nCells - fStack->sp; 9876116Sdcs 9976116Sdcs if (popCells > STKDEPTH(fStack)) 10076116Sdcs { 10176116Sdcs vmThrowErr(pVM, "Error: float stack underflow"); 10276116Sdcs } 10376116Sdcs 10476116Sdcs if (nFree < pushCells - popCells) 10576116Sdcs { 10676116Sdcs vmThrowErr(pVM, "Error: float stack overflow"); 10776116Sdcs } 10876116Sdcs} 10976116Sdcs#endif 11076116Sdcs 11140843Smsmith/******************************************************************* 11240843Smsmith s t a c k C r e a t e 11340843Smsmith** 11440843Smsmith*******************************************************************/ 11540843Smsmith 11640843SmsmithFICL_STACK *stackCreate(unsigned nCells) 11740843Smsmith{ 11840843Smsmith size_t size = sizeof (FICL_STACK) + nCells * sizeof (CELL); 11940843Smsmith FICL_STACK *pStack = ficlMalloc(size); 12040843Smsmith 12140843Smsmith#if FICL_ROBUST 12240843Smsmith assert (nCells != 0); 12340843Smsmith assert (pStack != NULL); 12440843Smsmith#endif 12540843Smsmith 12640843Smsmith pStack->nCells = nCells; 12740843Smsmith pStack->sp = pStack->base; 12840843Smsmith pStack->pFrame = NULL; 12940843Smsmith return pStack; 13040843Smsmith} 13140843Smsmith 13240843Smsmith 13340843Smsmith/******************************************************************* 13440843Smsmith s t a c k D e l e t e 13540843Smsmith** 13640843Smsmith*******************************************************************/ 13740843Smsmith 13840843Smsmithvoid stackDelete(FICL_STACK *pStack) 13940843Smsmith{ 14040843Smsmith if (pStack) 14140843Smsmith ficlFree(pStack); 14240843Smsmith return; 14340843Smsmith} 14440843Smsmith 14540843Smsmith 14640843Smsmith/******************************************************************* 14740843Smsmith s t a c k D e p t h 14840843Smsmith** 14940843Smsmith*******************************************************************/ 15040843Smsmith 15140843Smsmithint stackDepth(FICL_STACK *pStack) 15240843Smsmith{ 15340843Smsmith return STKDEPTH(pStack); 15440843Smsmith} 15540843Smsmith 15640843Smsmith/******************************************************************* 15740843Smsmith s t a c k D r o p 15840843Smsmith** 15940843Smsmith*******************************************************************/ 16040843Smsmith 16140843Smsmithvoid stackDrop(FICL_STACK *pStack, int n) 16240843Smsmith{ 16340843Smsmith#if FICL_ROBUST 16440843Smsmith assert(n > 0); 16540843Smsmith#endif 16640843Smsmith pStack->sp -= n; 16740843Smsmith return; 16840843Smsmith} 16940843Smsmith 17040843Smsmith 17140843Smsmith/******************************************************************* 17240843Smsmith s t a c k F e t c h 17340843Smsmith** 17440843Smsmith*******************************************************************/ 17540843Smsmith 17640843SmsmithCELL stackFetch(FICL_STACK *pStack, int n) 17740843Smsmith{ 17840843Smsmith return pStack->sp[-n-1]; 17940843Smsmith} 18040843Smsmith 18140843Smsmithvoid stackStore(FICL_STACK *pStack, int n, CELL c) 18240843Smsmith{ 18340843Smsmith pStack->sp[-n-1] = c; 18440843Smsmith return; 18540843Smsmith} 18640843Smsmith 18740843Smsmith 18840843Smsmith/******************************************************************* 18940843Smsmith s t a c k G e t T o p 19040843Smsmith** 19140843Smsmith*******************************************************************/ 19240843Smsmith 19340843SmsmithCELL stackGetTop(FICL_STACK *pStack) 19440843Smsmith{ 19540843Smsmith return pStack->sp[-1]; 19640843Smsmith} 19740843Smsmith 19840843Smsmith 19940843Smsmith/******************************************************************* 20040843Smsmith s t a c k L i n k 20140843Smsmith** Link a frame using the stack's frame pointer. Allot space for 20240843Smsmith** nCells cells in the frame 20340843Smsmith** 1) Push pFrame 20440843Smsmith** 2) pFrame = sp 20540843Smsmith** 3) sp += nCells 20640843Smsmith*******************************************************************/ 20740843Smsmith 20840843Smsmithvoid stackLink(FICL_STACK *pStack, int nCells) 20940843Smsmith{ 21040843Smsmith stackPushPtr(pStack, pStack->pFrame); 21140843Smsmith pStack->pFrame = pStack->sp; 21240843Smsmith pStack->sp += nCells; 21340843Smsmith return; 21440843Smsmith} 21540843Smsmith 21640843Smsmith 21740843Smsmith/******************************************************************* 21840843Smsmith s t a c k U n l i n k 21940843Smsmith** Unink a stack frame previously created by stackLink 22040843Smsmith** 1) sp = pFrame 22140843Smsmith** 2) pFrame = pop() 22240843Smsmith*******************************************************************/ 22340843Smsmith 22440843Smsmithvoid stackUnlink(FICL_STACK *pStack) 22540843Smsmith{ 22640843Smsmith pStack->sp = pStack->pFrame; 22740843Smsmith pStack->pFrame = stackPopPtr(pStack); 22840843Smsmith return; 22940843Smsmith} 23040843Smsmith 23140843Smsmith 23240843Smsmith/******************************************************************* 23340843Smsmith s t a c k P i c k 23440843Smsmith** 23540843Smsmith*******************************************************************/ 23640843Smsmith 23740843Smsmithvoid stackPick(FICL_STACK *pStack, int n) 23840843Smsmith{ 23940843Smsmith stackPush(pStack, stackFetch(pStack, n)); 24040843Smsmith return; 24140843Smsmith} 24240843Smsmith 24340843Smsmith 24440843Smsmith/******************************************************************* 24540843Smsmith s t a c k P o p 24640843Smsmith** 24740843Smsmith*******************************************************************/ 24840843Smsmith 24940843SmsmithCELL stackPop(FICL_STACK *pStack) 25040843Smsmith{ 25140843Smsmith return *--pStack->sp; 25240843Smsmith} 25340843Smsmith 25440843Smsmithvoid *stackPopPtr(FICL_STACK *pStack) 25540843Smsmith{ 25640843Smsmith return (*--pStack->sp).p; 25740843Smsmith} 25840843Smsmith 25951786SdcsFICL_UNS stackPopUNS(FICL_STACK *pStack) 26040843Smsmith{ 26140843Smsmith return (*--pStack->sp).u; 26240843Smsmith} 26340843Smsmith 26451786SdcsFICL_INT stackPopINT(FICL_STACK *pStack) 26540843Smsmith{ 26640843Smsmith return (*--pStack->sp).i; 26740843Smsmith} 26840843Smsmith 26976116Sdcs#if (FICL_WANT_FLOAT) 27076116Sdcsfloat stackPopFloat(FICL_STACK *pStack) 27176116Sdcs{ 27276116Sdcs return (*(--pStack->sp)).f; 27376116Sdcs} 27476116Sdcs#endif 27540843Smsmith 27640843Smsmith/******************************************************************* 27740843Smsmith s t a c k P u s h 27840843Smsmith** 27940843Smsmith*******************************************************************/ 28040843Smsmith 28140843Smsmithvoid stackPush(FICL_STACK *pStack, CELL c) 28240843Smsmith{ 28340843Smsmith *pStack->sp++ = c; 28440843Smsmith} 28540843Smsmith 28640843Smsmithvoid stackPushPtr(FICL_STACK *pStack, void *ptr) 28740843Smsmith{ 28840843Smsmith *pStack->sp++ = LVALUEtoCELL(ptr); 28940843Smsmith} 29040843Smsmith 29151786Sdcsvoid stackPushUNS(FICL_STACK *pStack, FICL_UNS u) 29240843Smsmith{ 29340843Smsmith *pStack->sp++ = LVALUEtoCELL(u); 29440843Smsmith} 29540843Smsmith 29651786Sdcsvoid stackPushINT(FICL_STACK *pStack, FICL_INT i) 29740843Smsmith{ 29840843Smsmith *pStack->sp++ = LVALUEtoCELL(i); 29940843Smsmith} 30040843Smsmith 30176116Sdcs#if (FICL_WANT_FLOAT) 30276116Sdcsvoid stackPushFloat(FICL_STACK *pStack, float f) 30376116Sdcs{ 30476116Sdcs *pStack->sp++ = LVALUEtoCELL(f); 30576116Sdcs} 30676116Sdcs#endif 30776116Sdcs 30840843Smsmith/******************************************************************* 30940843Smsmith s t a c k R e s e t 31040843Smsmith** 31140843Smsmith*******************************************************************/ 31240843Smsmith 31340843Smsmithvoid stackReset(FICL_STACK *pStack) 31440843Smsmith{ 31540843Smsmith pStack->sp = pStack->base; 31640843Smsmith return; 31740843Smsmith} 31840843Smsmith 31940843Smsmith 32040843Smsmith/******************************************************************* 32140843Smsmith s t a c k R o l l 32240843Smsmith** Roll nth stack entry to the top (counting from zero), if n is 32340843Smsmith** >= 0. Drop other entries as needed to fill the hole. 32440843Smsmith** If n < 0, roll top-of-stack to nth entry, pushing others 32540843Smsmith** upward as needed to fill the hole. 32640843Smsmith*******************************************************************/ 32740843Smsmith 32840843Smsmithvoid stackRoll(FICL_STACK *pStack, int n) 32940843Smsmith{ 33040843Smsmith CELL c; 33140843Smsmith CELL *pCell; 33240843Smsmith 33340843Smsmith if (n == 0) 33440843Smsmith return; 33540843Smsmith else if (n > 0) 33640843Smsmith { 33740843Smsmith pCell = pStack->sp - n - 1; 33840843Smsmith c = *pCell; 33940843Smsmith 34040843Smsmith for (;n > 0; --n, pCell++) 34140843Smsmith { 34240843Smsmith *pCell = pCell[1]; 34340843Smsmith } 34440843Smsmith 34540843Smsmith *pCell = c; 34640843Smsmith } 34740843Smsmith else 34840843Smsmith { 34940843Smsmith pCell = pStack->sp - 1; 35040843Smsmith c = *pCell; 35140843Smsmith 35240843Smsmith for (; n < 0; ++n, pCell--) 35340843Smsmith { 35440843Smsmith *pCell = pCell[-1]; 35540843Smsmith } 35640843Smsmith 35740843Smsmith *pCell = c; 35840843Smsmith } 35940843Smsmith return; 36040843Smsmith} 36140843Smsmith 36240843Smsmith 36340843Smsmith/******************************************************************* 36440843Smsmith s t a c k S e t T o p 36540843Smsmith** 36640843Smsmith*******************************************************************/ 36740843Smsmith 36840843Smsmithvoid stackSetTop(FICL_STACK *pStack, CELL c) 36940843Smsmith{ 37040843Smsmith pStack->sp[-1] = c; 37140843Smsmith return; 37240843Smsmith} 37340843Smsmith 37440843Smsmith 375