ficlWord *ficlSystemLookupLocal(ficlSystem *system, ficlString name) { ficlWord *word = NULL; ficlDictionary *dictionary = system->dictionary; ficlHash *hash = ficlSystemGetLocals(system)->forthWordlist; int i; ficlUnsigned16 hashCode = ficlHashCode(name); FICL_SYSTEM_ASSERT(system, hash); FICL_SYSTEM_ASSERT(system, dictionary); ficlDictionaryLock(dictionary, FICL_TRUE); /* ** check the locals dictionary first... */ word = ficlHashLookup(hash, name, hashCode); /* ** If no joy, (!word) ------------------------------v ** iterate over the search list in the main dictionary */ for (i = (int)dictionary->wordlistCount - 1; (i >= 0) && (!word); --i) { hash = dictionary->wordlists[i]; word = ficlHashLookup(hash, name, hashCode); } ficlDictionaryLock(dictionary, FICL_FALSE); return word; }
/* * d i c t A p p e n d W o r d * Create a new word in the dictionary with the specified * ficlString, code, and flags. Does not require a NULL-terminated * name. */ ficlWord * ficlDictionaryAppendWord(ficlDictionary *dictionary, ficlString name, ficlPrimitive code, ficlUnsigned8 flags) { ficlUnsigned8 length = (ficlUnsigned8)FICL_STRING_GET_LENGTH(name); char *nameCopy; ficlWord *word; ficlDictionaryLock(dictionary, FICL_TRUE); /* * NOTE: ficlDictionaryAppendString advances "here" as a side-effect. * It must execute before word is initialized. */ nameCopy = ficlDictionaryAppendString(dictionary, name); word = (ficlWord *)dictionary->here; dictionary->smudge = word; word->hash = ficlHashCode(name); word->code = code; word->semiParen = ficlInstructionSemiParen; word->flags = (ficlUnsigned8)(flags | FICL_WORD_SMUDGED); word->length = length; word->name = nameCopy; /* * Point "here" to first ficlCell of new word's param area... */ dictionary->here = word->param; if (!(flags & FICL_WORD_SMUDGED)) ficlDictionaryUnsmudge(dictionary); ficlDictionaryLock(dictionary, FICL_FALSE); return (word); }
/* * d i c t L o o k u p * Find the ficlWord that matches the given name and length. * If found, returns the word's address. Otherwise returns NULL. * Uses the search order list to search multiple wordlists. */ ficlWord * ficlDictionaryLookup(ficlDictionary *dictionary, ficlString name) { ficlWord *word = NULL; ficlHash *hash; int i; ficlUnsigned16 hashCode = ficlHashCode(name); FICL_DICTIONARY_ASSERT(dictionary, dictionary != NULL); ficlDictionaryLock(dictionary, FICL_TRUE); for (i = (int)dictionary->wordlistCount - 1; (i >= 0) && (!word); --i) { hash = dictionary->wordlists[i]; word = ficlHashLookup(hash, name, hashCode); } ficlDictionaryLock(dictionary, FICL_FALSE); return (word); }
/* * s e a r c h - w o r d l i s t * SEARCH ( c-addr u wid -- 0 | xt 1 | xt -1 ) * Find the definition identified by the string c-addr u in the word list * identified by wid. If the definition is not found, return zero. If the * definition is found, return its execution token xt and one (1) if the * definition is immediate, minus-one (-1) otherwise. */ static void ficlPrimitiveSearchWordlist(ficlVm *vm) { ficlString name; ficlUnsigned16 hashCode; ficlWord *word; ficlHash *hash = ficlStackPopPointer(vm->dataStack); name.length = (ficlUnsigned8)ficlStackPopUnsigned(vm->dataStack); name.text = ficlStackPopPointer(vm->dataStack); hashCode = ficlHashCode(name); ficlDictionaryLock(ficlVmGetDictionary(vm), FICL_TRUE); word = ficlHashLookup(hash, name, hashCode); ficlDictionaryLock(ficlVmGetDictionary(vm), FICL_FALSE); if (word) { ficlStackPushPointer(vm->dataStack, word); ficlStackPushInteger(vm->dataStack, (ficlWordIsImmediate(word) ? 1 : -1)); } else { ficlStackPushUnsigned(vm->dataStack, 0); } }
FICL_PLATFORM_EXTERN ficlUnsigned16 hashHashCode (ficlString string) { return ficlHashCode(string); }