stack.c revision 40843
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 640843Smsmith** 740843Smsmith*******************************************************************/ 840843Smsmith#include <stdlib.h> 940843Smsmith 1040843Smsmith#include "ficl.h" 1140843Smsmith 1240843Smsmith#define STKDEPTH(s) ((s)->sp - (s)->base) 1340843Smsmith 1440843Smsmith/* 1540843Smsmith** N O T E: Stack convention: 1640843Smsmith** 1740843Smsmith** sp points to the first available cell 1840843Smsmith** push: store value at sp, increment sp 1940843Smsmith** pop: decrement sp, fetch value at sp 2040843Smsmith** Stack grows from low to high memory 2140843Smsmith*/ 2240843Smsmith 2340843Smsmith/******************************************************************* 2440843Smsmith v m C h e c k S t a c k 2540843Smsmith** Check the parameter stack for underflow or overflow. 2640843Smsmith** nCells controls the type of check: if nCells is zero, 2740843Smsmith** the function checks the stack state for underflow and overflow. 2840843Smsmith** If nCells > 0, checks to see that the stack has room to push 2940843Smsmith** that many cells. If less than zero, checks to see that the 3040843Smsmith** stack has room to pop that many cells. If any test fails, 3140843Smsmith** the function throws (via vmThrow) a VM_ERREXIT exception. 3240843Smsmith*******************************************************************/ 3340843Smsmithvoid vmCheckStack(FICL_VM *pVM, int popCells, int pushCells) 3440843Smsmith{ 3540843Smsmith FICL_STACK *pStack = pVM->pStack; 3640843Smsmith int nFree = pStack->base + pStack->nCells - pStack->sp; 3740843Smsmith 3840843Smsmith if (popCells > STKDEPTH(pStack)) 3940843Smsmith { 4040843Smsmith vmThrowErr(pVM, "Error: stack underflow"); 4140843Smsmith } 4240843Smsmith 4340843Smsmith if (nFree < pushCells - popCells) 4440843Smsmith { 4540843Smsmith vmThrowErr(pVM, "Error: stack overflow"); 4640843Smsmith } 4740843Smsmith 4840843Smsmith return; 4940843Smsmith} 5040843Smsmith 5140843Smsmith/******************************************************************* 5240843Smsmith s t a c k C r e a t e 5340843Smsmith** 5440843Smsmith*******************************************************************/ 5540843Smsmith 5640843SmsmithFICL_STACK *stackCreate(unsigned nCells) 5740843Smsmith{ 5840843Smsmith size_t size = sizeof (FICL_STACK) + nCells * sizeof (CELL); 5940843Smsmith FICL_STACK *pStack = ficlMalloc(size); 6040843Smsmith 6140843Smsmith#if FICL_ROBUST 6240843Smsmith assert (nCells != 0); 6340843Smsmith assert (pStack != NULL); 6440843Smsmith#endif 6540843Smsmith 6640843Smsmith pStack->nCells = nCells; 6740843Smsmith pStack->sp = pStack->base; 6840843Smsmith pStack->pFrame = NULL; 6940843Smsmith return pStack; 7040843Smsmith} 7140843Smsmith 7240843Smsmith 7340843Smsmith/******************************************************************* 7440843Smsmith s t a c k D e l e t e 7540843Smsmith** 7640843Smsmith*******************************************************************/ 7740843Smsmith 7840843Smsmithvoid stackDelete(FICL_STACK *pStack) 7940843Smsmith{ 8040843Smsmith if (pStack) 8140843Smsmith ficlFree(pStack); 8240843Smsmith return; 8340843Smsmith} 8440843Smsmith 8540843Smsmith 8640843Smsmith/******************************************************************* 8740843Smsmith s t a c k D e p t h 8840843Smsmith** 8940843Smsmith*******************************************************************/ 9040843Smsmith 9140843Smsmithint stackDepth(FICL_STACK *pStack) 9240843Smsmith{ 9340843Smsmith return STKDEPTH(pStack); 9440843Smsmith} 9540843Smsmith 9640843Smsmith/******************************************************************* 9740843Smsmith s t a c k D r o p 9840843Smsmith** 9940843Smsmith*******************************************************************/ 10040843Smsmith 10140843Smsmithvoid stackDrop(FICL_STACK *pStack, int n) 10240843Smsmith{ 10340843Smsmith#if FICL_ROBUST 10440843Smsmith assert(n > 0); 10540843Smsmith#endif 10640843Smsmith pStack->sp -= n; 10740843Smsmith return; 10840843Smsmith} 10940843Smsmith 11040843Smsmith 11140843Smsmith/******************************************************************* 11240843Smsmith s t a c k F e t c h 11340843Smsmith** 11440843Smsmith*******************************************************************/ 11540843Smsmith 11640843SmsmithCELL stackFetch(FICL_STACK *pStack, int n) 11740843Smsmith{ 11840843Smsmith return pStack->sp[-n-1]; 11940843Smsmith} 12040843Smsmith 12140843Smsmithvoid stackStore(FICL_STACK *pStack, int n, CELL c) 12240843Smsmith{ 12340843Smsmith pStack->sp[-n-1] = c; 12440843Smsmith return; 12540843Smsmith} 12640843Smsmith 12740843Smsmith 12840843Smsmith/******************************************************************* 12940843Smsmith s t a c k G e t T o p 13040843Smsmith** 13140843Smsmith*******************************************************************/ 13240843Smsmith 13340843SmsmithCELL stackGetTop(FICL_STACK *pStack) 13440843Smsmith{ 13540843Smsmith return pStack->sp[-1]; 13640843Smsmith} 13740843Smsmith 13840843Smsmith 13940843Smsmith/******************************************************************* 14040843Smsmith s t a c k L i n k 14140843Smsmith** Link a frame using the stack's frame pointer. Allot space for 14240843Smsmith** nCells cells in the frame 14340843Smsmith** 1) Push pFrame 14440843Smsmith** 2) pFrame = sp 14540843Smsmith** 3) sp += nCells 14640843Smsmith*******************************************************************/ 14740843Smsmith 14840843Smsmithvoid stackLink(FICL_STACK *pStack, int nCells) 14940843Smsmith{ 15040843Smsmith stackPushPtr(pStack, pStack->pFrame); 15140843Smsmith pStack->pFrame = pStack->sp; 15240843Smsmith pStack->sp += nCells; 15340843Smsmith return; 15440843Smsmith} 15540843Smsmith 15640843Smsmith 15740843Smsmith/******************************************************************* 15840843Smsmith s t a c k U n l i n k 15940843Smsmith** Unink a stack frame previously created by stackLink 16040843Smsmith** 1) sp = pFrame 16140843Smsmith** 2) pFrame = pop() 16240843Smsmith*******************************************************************/ 16340843Smsmith 16440843Smsmithvoid stackUnlink(FICL_STACK *pStack) 16540843Smsmith{ 16640843Smsmith pStack->sp = pStack->pFrame; 16740843Smsmith pStack->pFrame = stackPopPtr(pStack); 16840843Smsmith return; 16940843Smsmith} 17040843Smsmith 17140843Smsmith 17240843Smsmith/******************************************************************* 17340843Smsmith s t a c k P i c k 17440843Smsmith** 17540843Smsmith*******************************************************************/ 17640843Smsmith 17740843Smsmithvoid stackPick(FICL_STACK *pStack, int n) 17840843Smsmith{ 17940843Smsmith stackPush(pStack, stackFetch(pStack, n)); 18040843Smsmith return; 18140843Smsmith} 18240843Smsmith 18340843Smsmith 18440843Smsmith/******************************************************************* 18540843Smsmith s t a c k P o p 18640843Smsmith** 18740843Smsmith*******************************************************************/ 18840843Smsmith 18940843SmsmithCELL stackPop(FICL_STACK *pStack) 19040843Smsmith{ 19140843Smsmith return *--pStack->sp; 19240843Smsmith} 19340843Smsmith 19440843Smsmithvoid *stackPopPtr(FICL_STACK *pStack) 19540843Smsmith{ 19640843Smsmith return (*--pStack->sp).p; 19740843Smsmith} 19840843Smsmith 19940843SmsmithUNS32 stackPopUNS32(FICL_STACK *pStack) 20040843Smsmith{ 20140843Smsmith return (*--pStack->sp).u; 20240843Smsmith} 20340843Smsmith 20440843SmsmithINT32 stackPopINT32(FICL_STACK *pStack) 20540843Smsmith{ 20640843Smsmith return (*--pStack->sp).i; 20740843Smsmith} 20840843Smsmith 20940843Smsmith 21040843Smsmith/******************************************************************* 21140843Smsmith s t a c k P u s h 21240843Smsmith** 21340843Smsmith*******************************************************************/ 21440843Smsmith 21540843Smsmithvoid stackPush(FICL_STACK *pStack, CELL c) 21640843Smsmith{ 21740843Smsmith *pStack->sp++ = c; 21840843Smsmith} 21940843Smsmith 22040843Smsmithvoid stackPushPtr(FICL_STACK *pStack, void *ptr) 22140843Smsmith{ 22240843Smsmith *pStack->sp++ = LVALUEtoCELL(ptr); 22340843Smsmith} 22440843Smsmith 22540843Smsmithvoid stackPushUNS32(FICL_STACK *pStack, UNS32 u) 22640843Smsmith{ 22740843Smsmith *pStack->sp++ = LVALUEtoCELL(u); 22840843Smsmith} 22940843Smsmith 23040843Smsmithvoid stackPushINT32(FICL_STACK *pStack, INT32 i) 23140843Smsmith{ 23240843Smsmith *pStack->sp++ = LVALUEtoCELL(i); 23340843Smsmith} 23440843Smsmith 23540843Smsmith/******************************************************************* 23640843Smsmith s t a c k R e s e t 23740843Smsmith** 23840843Smsmith*******************************************************************/ 23940843Smsmith 24040843Smsmithvoid stackReset(FICL_STACK *pStack) 24140843Smsmith{ 24240843Smsmith pStack->sp = pStack->base; 24340843Smsmith return; 24440843Smsmith} 24540843Smsmith 24640843Smsmith 24740843Smsmith/******************************************************************* 24840843Smsmith s t a c k R o l l 24940843Smsmith** Roll nth stack entry to the top (counting from zero), if n is 25040843Smsmith** >= 0. Drop other entries as needed to fill the hole. 25140843Smsmith** If n < 0, roll top-of-stack to nth entry, pushing others 25240843Smsmith** upward as needed to fill the hole. 25340843Smsmith*******************************************************************/ 25440843Smsmith 25540843Smsmithvoid stackRoll(FICL_STACK *pStack, int n) 25640843Smsmith{ 25740843Smsmith CELL c; 25840843Smsmith CELL *pCell; 25940843Smsmith 26040843Smsmith if (n == 0) 26140843Smsmith return; 26240843Smsmith else if (n > 0) 26340843Smsmith { 26440843Smsmith pCell = pStack->sp - n - 1; 26540843Smsmith c = *pCell; 26640843Smsmith 26740843Smsmith for (;n > 0; --n, pCell++) 26840843Smsmith { 26940843Smsmith *pCell = pCell[1]; 27040843Smsmith } 27140843Smsmith 27240843Smsmith *pCell = c; 27340843Smsmith } 27440843Smsmith else 27540843Smsmith { 27640843Smsmith pCell = pStack->sp - 1; 27740843Smsmith c = *pCell; 27840843Smsmith 27940843Smsmith for (; n < 0; ++n, pCell--) 28040843Smsmith { 28140843Smsmith *pCell = pCell[-1]; 28240843Smsmith } 28340843Smsmith 28440843Smsmith *pCell = c; 28540843Smsmith } 28640843Smsmith return; 28740843Smsmith} 28840843Smsmith 28940843Smsmith 29040843Smsmith/******************************************************************* 29140843Smsmith s t a c k S e t T o p 29240843Smsmith** 29340843Smsmith*******************************************************************/ 29440843Smsmith 29540843Smsmithvoid stackSetTop(FICL_STACK *pStack, CELL c) 29640843Smsmith{ 29740843Smsmith pStack->sp[-1] = c; 29840843Smsmith return; 29940843Smsmith} 30040843Smsmith 30140843Smsmith 302