/************************************************************************** h a s h L o o k u p ** Find a name in the hash table given the hashcode and text of the name. ** Returns the address of the corresponding ficlWord if found, ** otherwise NULL. ** Note: outer loop on link field supports inheritance in wordlists. ** It's not part of ANS Forth - Ficl only. hashReset creates wordlists ** with NULL link fields. **************************************************************************/ ficlWord *ficlHashLookup(ficlHash *hash, ficlString name, ficlUnsigned16 hashCode) { ficlUnsigned nCmp = name.length; ficlWord *word; ficlUnsigned16 hashIdx; if (nCmp > FICL_NAME_LENGTH) nCmp = FICL_NAME_LENGTH; for (; hash != NULL; hash = hash->link) { if (hash->size > 1) hashIdx = (ficlUnsigned16)(hashCode % hash->size); else /* avoid the modulo op for single threaded lists */ hashIdx = 0; for (word = hash->table[hashIdx]; word; word = word->link) { if ( (word->length == name.length) && (!ficlStrincmp(name.text, word->name, nCmp)) ) return word; #if FICL_ROBUST FICL_ASSERT_PHASH(hash, word != word->link); #endif } } return NULL; }
/************************************************************************** f i c l P a r s e P r e f i x ** This is the parse step for prefixes - it checks an incoming word ** to see if it starts with a prefix, and if so runs the corresponding ** code against the remainder of the word and returns true. **************************************************************************/ int ficlVmParsePrefix(ficlVm *vm, ficlString s) { int i; ficlHash *hash; ficlWord *word = ficlSystemLookup(vm->callback.system, list_name); /* ** Make sure we found the prefix dictionary - otherwise silently fail ** If forth-wordlist is not in the search order, we won't find the prefixes. */ if (!word) return FICL_FALSE; hash = (ficlHash *)(word->param[0].p); /* ** Walk the list looking for a match with the beginning of the incoming token */ for (i = 0; i < (int)hash->size; i++) { word = hash->table[i]; while (word != NULL) { int n; n = word->length; /* ** If we find a match, adjust the TIB to give back the non-prefix characters ** and execute the prefix word. */ if (!ficlStrincmp(FICL_STRING_GET_POINTER(s), word->name, (ficlUnsigned)n)) { /* (sadler) fixed off-by-one error when the token has no trailing space in the TIB */ ficlVmSetTibIndex(vm, s.text + n - vm->tib.text); ficlVmExecuteWord(vm, word); return FICL_TRUE; } word = word->link; } } return FICL_FALSE; }
FICL_PLATFORM_EXTERN int strincmp(char *cp1, char *cp2, ficlUnsigned count) { return ficlStrincmp(cp1, cp2, count); }