/************************************************************************** d i c t C h e c k ** Checks the dictionary for corruption and throws appropriate ** errors. ** Input: +n number of ADDRESS UNITS (not Cells) proposed to allot ** -n number of ADDRESS UNITS proposed to de-allot ** 0 just do a consistency check **************************************************************************/ void dictCheck(FICL_DICT *pDict, FICL_VM *pVM, int n) { if ((n >= 0) && (dictCellsAvail(pDict) * (int)sizeof(CELL) < n)) { vmThrowErr(pVM, "Error: dictionary full"); } if ((n <= 0) && (dictCellsUsed(pDict) * (int)sizeof(CELL) < -n)) { vmThrowErr(pVM, "Error: dictionary underflow"); } if (pDict->nLists > FICL_DEFAULT_VOCS) { dictResetSearchOrder(pDict); vmThrowErr(pVM, "Error: search order overflow"); } else if (pDict->nLists < 0) { dictResetSearchOrder(pDict); vmThrowErr(pVM, "Error: search order underflow"); } return; }
/************************************************************************** d i c t A l l o t ** Allocate or remove n chars of dictionary space, with ** checks for underrun and overrun **************************************************************************/ int dictAllot(FICL_DICT *pDict, int n) { char *cp = (char *)pDict->here; #if FICL_ROBUST if (n > 0) { if ((unsigned)n <= dictCellsAvail(pDict) * sizeof (CELL)) cp += n; else return 1; /* dict is full */ } else { n = -n; if ((unsigned)n <= dictCellsUsed(pDict) * sizeof (CELL)) cp -= n; else /* prevent underflow */ cp -= dictCellsUsed(pDict) * sizeof (CELL); } #else cp += n; #endif pDict->here = PTRtoCELL cp; return 0; }
void dictCheckThreshold(FICL_DICT* dp) { if( dictCellsAvail(dp) < dictThreshold.u ) { dp->dict = ficlMalloc( dictIncrease.u * sizeof (CELL) ); assert(dp->dict); dp->here = dp->dict; dp->size = dictIncrease.u; dictAlign(dp); } }
/************************************************************************** f i c l B u i l d ** Builds a word into the dictionary. ** Preconditions: system must be initialized, and there must ** be enough space for the new word's header! Operation is ** controlled by ficlLockDictionary, so any initialization ** required by your version of the function (if you overrode ** it) must be complete at this point. ** Parameters: ** name -- duh, the name of the word ** code -- code to execute when the word is invoked - must take a single param ** pointer to a FICL_VM ** flags -- 0 or more of F_IMMEDIATE, F_COMPILE, use bitwise OR! ** **************************************************************************/ int ficlBuild(FICL_SYSTEM *pSys, char *name, FICL_CODE code, char flags) { #if FICL_MULTITHREAD int err = ficlLockDictionary(TRUE); if (err) return err; #endif /* FICL_MULTITHREAD */ assert(dictCellsAvail(pSys->dp) > sizeof (FICL_WORD) / sizeof (CELL)); dictAppendWord(pSys->dp, name, code, flags); ficlLockDictionary(FALSE); return 0; }
/************************************************************************** d i c t A l l o t C e l l s ** Reserve space for the requested number of cells in the ** dictionary. If nCells < 0 , removes space from the dictionary. **************************************************************************/ int dictAllotCells(FICL_DICT *pDict, int nCells) { #if FICL_ROBUST if (nCells > 0) { if (nCells <= dictCellsAvail(pDict)) pDict->here += nCells; else return 1; /* dict is full */ } else { nCells = -nCells; if (nCells <= dictCellsUsed(pDict)) pDict->here -= nCells; else /* prevent underflow */ pDict->here -= dictCellsUsed(pDict); } #else pDict->here += nCells; #endif return 0; }
static void freeHeap(FICL_VM *pVM) { stackPushINT(pVM->pStack, dictCellsAvail(ficlGetDict(pVM->pSys))); }