1*a1bf3f78SToomas Soome /* 2*a1bf3f78SToomas Soome * d i c t . c 3*a1bf3f78SToomas Soome * Forth Inspired Command Language - dictionary methods 4*a1bf3f78SToomas Soome * Author: John Sadler (john_sadler@alum.mit.edu) 5*a1bf3f78SToomas Soome * Created: 19 July 1997 6*a1bf3f78SToomas Soome * $Id: dictionary.c,v 1.2 2010/09/12 15:14:52 asau Exp $ 7*a1bf3f78SToomas Soome */ 8*a1bf3f78SToomas Soome /* 9*a1bf3f78SToomas Soome * This file implements the dictionary -- Ficl's model of 10*a1bf3f78SToomas Soome * memory management. All Ficl words are stored in the 11*a1bf3f78SToomas Soome * dictionary. A word is a named chunk of data with its 12*a1bf3f78SToomas Soome * associated code. Ficl treats all words the same, even 13*a1bf3f78SToomas Soome * precompiled ones, so your words become first-class 14*a1bf3f78SToomas Soome * extensions of the language. You can even define new 15*a1bf3f78SToomas Soome * control structures. 16*a1bf3f78SToomas Soome * 17*a1bf3f78SToomas Soome * 29 jun 1998 (sadler) added variable sized hash table support 18*a1bf3f78SToomas Soome */ 19*a1bf3f78SToomas Soome /* 20*a1bf3f78SToomas Soome * Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu) 21*a1bf3f78SToomas Soome * All rights reserved. 22*a1bf3f78SToomas Soome * 23*a1bf3f78SToomas Soome * Get the latest Ficl release at http://ficl.sourceforge.net 24*a1bf3f78SToomas Soome * 25*a1bf3f78SToomas Soome * I am interested in hearing from anyone who uses Ficl. If you have 26*a1bf3f78SToomas Soome * a problem, a success story, a defect, an enhancement request, or 27*a1bf3f78SToomas Soome * if you would like to contribute to the Ficl release, please 28*a1bf3f78SToomas Soome * contact me by email at the address above. 29*a1bf3f78SToomas Soome * 30*a1bf3f78SToomas Soome * L I C E N S E and D I S C L A I M E R 31*a1bf3f78SToomas Soome * 32*a1bf3f78SToomas Soome * Redistribution and use in source and binary forms, with or without 33*a1bf3f78SToomas Soome * modification, are permitted provided that the following conditions 34*a1bf3f78SToomas Soome * are met: 35*a1bf3f78SToomas Soome * 1. Redistributions of source code must retain the above copyright 36*a1bf3f78SToomas Soome * notice, this list of conditions and the following disclaimer. 37*a1bf3f78SToomas Soome * 2. Redistributions in binary form must reproduce the above copyright 38*a1bf3f78SToomas Soome * notice, this list of conditions and the following disclaimer in the 39*a1bf3f78SToomas Soome * documentation and/or other materials provided with the distribution. 40*a1bf3f78SToomas Soome * 41*a1bf3f78SToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 42*a1bf3f78SToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43*a1bf3f78SToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44*a1bf3f78SToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45*a1bf3f78SToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46*a1bf3f78SToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47*a1bf3f78SToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48*a1bf3f78SToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49*a1bf3f78SToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50*a1bf3f78SToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51*a1bf3f78SToomas Soome * SUCH DAMAGE. 52*a1bf3f78SToomas Soome */ 53*a1bf3f78SToomas Soome 54*a1bf3f78SToomas Soome #include "ficl.h" 55*a1bf3f78SToomas Soome 56*a1bf3f78SToomas Soome #define FICL_SAFE_CALLBACK_FROM_SYSTEM(system) \ 57*a1bf3f78SToomas Soome (((system) != NULL) ? &((system)->callback) : NULL) 58*a1bf3f78SToomas Soome #define FICL_SAFE_SYSTEM_FROM_DICTIONARY(dictionary) \ 59*a1bf3f78SToomas Soome (((dictionary) != NULL) ? (dictionary)->system : NULL) 60*a1bf3f78SToomas Soome #define FICL_DICTIONARY_ASSERT(dictionary, expression) \ 61*a1bf3f78SToomas Soome FICL_SYSTEM_ASSERT(FICL_SAFE_SYSTEM_FROM_DICTIONARY(dictionary), \ 62*a1bf3f78SToomas Soome expression) 63*a1bf3f78SToomas Soome 64*a1bf3f78SToomas Soome /* 65*a1bf3f78SToomas Soome * d i c t A b o r t D e f i n i t i o n 66*a1bf3f78SToomas Soome * Abort a definition in process: reclaim its memory and unlink it 67*a1bf3f78SToomas Soome * from the dictionary list. Assumes that there is a smudged 68*a1bf3f78SToomas Soome * definition in process...otherwise does nothing. 69*a1bf3f78SToomas Soome * NOTE: this function is not smart enough to unlink a word that 70*a1bf3f78SToomas Soome * has been successfully defined (ie linked into a hash). It 71*a1bf3f78SToomas Soome * only works for defs in process. If the def has been unsmudged, 72*a1bf3f78SToomas Soome * nothing happens. 73*a1bf3f78SToomas Soome */ 74*a1bf3f78SToomas Soome void 75*a1bf3f78SToomas Soome ficlDictionaryAbortDefinition(ficlDictionary *dictionary) 76*a1bf3f78SToomas Soome { 77*a1bf3f78SToomas Soome ficlWord *word; 78*a1bf3f78SToomas Soome ficlDictionaryLock(dictionary, FICL_TRUE); 79*a1bf3f78SToomas Soome word = dictionary->smudge; 80*a1bf3f78SToomas Soome 81*a1bf3f78SToomas Soome if (word->flags & FICL_WORD_SMUDGED) 82*a1bf3f78SToomas Soome dictionary->here = (ficlCell *)word->name; 83*a1bf3f78SToomas Soome 84*a1bf3f78SToomas Soome ficlDictionaryLock(dictionary, FICL_FALSE); 85*a1bf3f78SToomas Soome } 86*a1bf3f78SToomas Soome 87*a1bf3f78SToomas Soome /* 88*a1bf3f78SToomas Soome * d i c t A l i g n 89*a1bf3f78SToomas Soome * Align the dictionary's free space pointer 90*a1bf3f78SToomas Soome */ 91*a1bf3f78SToomas Soome void 92*a1bf3f78SToomas Soome ficlDictionaryAlign(ficlDictionary *dictionary) 93*a1bf3f78SToomas Soome { 94*a1bf3f78SToomas Soome dictionary->here = ficlAlignPointer(dictionary->here); 95*a1bf3f78SToomas Soome } 96*a1bf3f78SToomas Soome 97*a1bf3f78SToomas Soome /* 98*a1bf3f78SToomas Soome * d i c t A l l o t 99*a1bf3f78SToomas Soome * Allocate or remove n chars of dictionary space, with 100*a1bf3f78SToomas Soome * checks for underrun and overrun 101*a1bf3f78SToomas Soome */ 102*a1bf3f78SToomas Soome void 103*a1bf3f78SToomas Soome ficlDictionaryAllot(ficlDictionary *dictionary, int n) 104*a1bf3f78SToomas Soome { 105*a1bf3f78SToomas Soome char *here = (char *)dictionary->here; 106*a1bf3f78SToomas Soome here += n; 107*a1bf3f78SToomas Soome dictionary->here = FICL_POINTER_TO_CELL(here); 108*a1bf3f78SToomas Soome } 109*a1bf3f78SToomas Soome 110*a1bf3f78SToomas Soome /* 111*a1bf3f78SToomas Soome * d i c t A l l o t C e l l s 112*a1bf3f78SToomas Soome * Reserve space for the requested number of ficlCells in the 113*a1bf3f78SToomas Soome * dictionary. If nficlCells < 0 , removes space from the dictionary. 114*a1bf3f78SToomas Soome */ 115*a1bf3f78SToomas Soome void 116*a1bf3f78SToomas Soome ficlDictionaryAllotCells(ficlDictionary *dictionary, int nficlCells) 117*a1bf3f78SToomas Soome { 118*a1bf3f78SToomas Soome dictionary->here += nficlCells; 119*a1bf3f78SToomas Soome } 120*a1bf3f78SToomas Soome 121*a1bf3f78SToomas Soome /* 122*a1bf3f78SToomas Soome * d i c t A p p e n d C e l l 123*a1bf3f78SToomas Soome * Append the specified ficlCell to the dictionary 124*a1bf3f78SToomas Soome */ 125*a1bf3f78SToomas Soome void 126*a1bf3f78SToomas Soome ficlDictionaryAppendCell(ficlDictionary *dictionary, ficlCell c) 127*a1bf3f78SToomas Soome { 128*a1bf3f78SToomas Soome *dictionary->here++ = c; 129*a1bf3f78SToomas Soome } 130*a1bf3f78SToomas Soome 131*a1bf3f78SToomas Soome /* 132*a1bf3f78SToomas Soome * d i c t A p p e n d C h a r 133*a1bf3f78SToomas Soome * Append the specified char to the dictionary 134*a1bf3f78SToomas Soome */ 135*a1bf3f78SToomas Soome void 136*a1bf3f78SToomas Soome ficlDictionaryAppendCharacter(ficlDictionary *dictionary, char c) 137*a1bf3f78SToomas Soome { 138*a1bf3f78SToomas Soome char *here = (char *)dictionary->here; 139*a1bf3f78SToomas Soome *here++ = c; 140*a1bf3f78SToomas Soome dictionary->here = FICL_POINTER_TO_CELL(here); 141*a1bf3f78SToomas Soome } 142*a1bf3f78SToomas Soome 143*a1bf3f78SToomas Soome /* 144*a1bf3f78SToomas Soome * d i c t A p p e n d U N S 145*a1bf3f78SToomas Soome * Append the specified ficlUnsigned to the dictionary 146*a1bf3f78SToomas Soome */ 147*a1bf3f78SToomas Soome void 148*a1bf3f78SToomas Soome ficlDictionaryAppendUnsigned(ficlDictionary *dictionary, ficlUnsigned u) 149*a1bf3f78SToomas Soome { 150*a1bf3f78SToomas Soome ficlCell c; 151*a1bf3f78SToomas Soome 152*a1bf3f78SToomas Soome c.u = u; 153*a1bf3f78SToomas Soome ficlDictionaryAppendCell(dictionary, c); 154*a1bf3f78SToomas Soome } 155*a1bf3f78SToomas Soome 156*a1bf3f78SToomas Soome void * 157*a1bf3f78SToomas Soome ficlDictionaryAppendData(ficlDictionary *dictionary, void *data, 158*a1bf3f78SToomas Soome ficlInteger length) 159*a1bf3f78SToomas Soome { 160*a1bf3f78SToomas Soome char *here = (char *)dictionary->here; 161*a1bf3f78SToomas Soome char *oldHere = here; 162*a1bf3f78SToomas Soome char *from = (char *)data; 163*a1bf3f78SToomas Soome 164*a1bf3f78SToomas Soome if (length == 0) { 165*a1bf3f78SToomas Soome ficlDictionaryAlign(dictionary); 166*a1bf3f78SToomas Soome return ((char *)dictionary->here); 167*a1bf3f78SToomas Soome } 168*a1bf3f78SToomas Soome 169*a1bf3f78SToomas Soome while (length) { 170*a1bf3f78SToomas Soome *here++ = *from++; 171*a1bf3f78SToomas Soome length--; 172*a1bf3f78SToomas Soome } 173*a1bf3f78SToomas Soome 174*a1bf3f78SToomas Soome *here++ = '\0'; 175*a1bf3f78SToomas Soome 176*a1bf3f78SToomas Soome dictionary->here = FICL_POINTER_TO_CELL(here); 177*a1bf3f78SToomas Soome ficlDictionaryAlign(dictionary); 178*a1bf3f78SToomas Soome return (oldHere); 179*a1bf3f78SToomas Soome } 180*a1bf3f78SToomas Soome 181*a1bf3f78SToomas Soome /* 182*a1bf3f78SToomas Soome * d i c t C o p y N a m e 183*a1bf3f78SToomas Soome * Copy up to FICL_NAME_LENGTH characters of the name specified by s into 184*a1bf3f78SToomas Soome * the dictionary starting at "here", then NULL-terminate the name, 185*a1bf3f78SToomas Soome * point "here" to the next available byte, and return the address of 186*a1bf3f78SToomas Soome * the beginning of the name. Used by dictAppendWord. 187*a1bf3f78SToomas Soome * N O T E S : 188*a1bf3f78SToomas Soome * 1. "here" is guaranteed to be aligned after this operation. 189*a1bf3f78SToomas Soome * 2. If the string has zero length, align and return "here" 190*a1bf3f78SToomas Soome */ 191*a1bf3f78SToomas Soome char * 192*a1bf3f78SToomas Soome ficlDictionaryAppendString(ficlDictionary *dictionary, ficlString s) 193*a1bf3f78SToomas Soome { 194*a1bf3f78SToomas Soome void *data = FICL_STRING_GET_POINTER(s); 195*a1bf3f78SToomas Soome ficlInteger length = FICL_STRING_GET_LENGTH(s); 196*a1bf3f78SToomas Soome 197*a1bf3f78SToomas Soome if (length > FICL_NAME_LENGTH) 198*a1bf3f78SToomas Soome length = FICL_NAME_LENGTH; 199*a1bf3f78SToomas Soome 200*a1bf3f78SToomas Soome return (ficlDictionaryAppendData(dictionary, data, length)); 201*a1bf3f78SToomas Soome } 202*a1bf3f78SToomas Soome 203*a1bf3f78SToomas Soome ficlWord * 204*a1bf3f78SToomas Soome ficlDictionaryAppendConstantInstruction(ficlDictionary *dictionary, 205*a1bf3f78SToomas Soome ficlString name, ficlInstruction instruction, ficlInteger value) 206*a1bf3f78SToomas Soome { 207*a1bf3f78SToomas Soome ficlWord *word = ficlDictionaryAppendWord(dictionary, name, 208*a1bf3f78SToomas Soome (ficlPrimitive)instruction, FICL_WORD_DEFAULT); 209*a1bf3f78SToomas Soome 210*a1bf3f78SToomas Soome if (word != NULL) 211*a1bf3f78SToomas Soome ficlDictionaryAppendUnsigned(dictionary, value); 212*a1bf3f78SToomas Soome return (word); 213*a1bf3f78SToomas Soome } 214*a1bf3f78SToomas Soome 215*a1bf3f78SToomas Soome ficlWord * 216*a1bf3f78SToomas Soome ficlDictionaryAppend2ConstantInstruction(ficlDictionary *dictionary, 217*a1bf3f78SToomas Soome ficlString name, ficlInstruction instruction, ficl2Integer value) 218*a1bf3f78SToomas Soome { 219*a1bf3f78SToomas Soome ficlWord *word = ficlDictionaryAppendWord(dictionary, name, 220*a1bf3f78SToomas Soome (ficlPrimitive)instruction, FICL_WORD_DEFAULT); 221*a1bf3f78SToomas Soome 222*a1bf3f78SToomas Soome if (word != NULL) { 223*a1bf3f78SToomas Soome ficlDictionaryAppendUnsigned(dictionary, 224*a1bf3f78SToomas Soome FICL_2UNSIGNED_GET_HIGH(value)); 225*a1bf3f78SToomas Soome ficlDictionaryAppendUnsigned(dictionary, 226*a1bf3f78SToomas Soome FICL_2UNSIGNED_GET_LOW(value)); 227*a1bf3f78SToomas Soome } 228*a1bf3f78SToomas Soome return (word); 229*a1bf3f78SToomas Soome } 230*a1bf3f78SToomas Soome 231*a1bf3f78SToomas Soome ficlWord * 232*a1bf3f78SToomas Soome ficlDictionaryAppendConstant(ficlDictionary *dictionary, char *name, 233*a1bf3f78SToomas Soome ficlInteger value) 234*a1bf3f78SToomas Soome { 235*a1bf3f78SToomas Soome ficlString s; 236*a1bf3f78SToomas Soome FICL_STRING_SET_FROM_CSTRING(s, name); 237*a1bf3f78SToomas Soome return (ficlDictionaryAppendConstantInstruction(dictionary, s, 238*a1bf3f78SToomas Soome ficlInstructionConstantParen, value)); 239*a1bf3f78SToomas Soome } 240*a1bf3f78SToomas Soome 241*a1bf3f78SToomas Soome ficlWord * 242*a1bf3f78SToomas Soome ficlDictionaryAppend2Constant(ficlDictionary *dictionary, char *name, 243*a1bf3f78SToomas Soome ficl2Integer value) 244*a1bf3f78SToomas Soome { 245*a1bf3f78SToomas Soome ficlString s; 246*a1bf3f78SToomas Soome FICL_STRING_SET_FROM_CSTRING(s, name); 247*a1bf3f78SToomas Soome return (ficlDictionaryAppend2ConstantInstruction(dictionary, s, 248*a1bf3f78SToomas Soome ficlInstruction2ConstantParen, value)); 249*a1bf3f78SToomas Soome } 250*a1bf3f78SToomas Soome 251*a1bf3f78SToomas Soome ficlWord * 252*a1bf3f78SToomas Soome ficlDictionarySetConstantInstruction(ficlDictionary *dictionary, 253*a1bf3f78SToomas Soome ficlString name, ficlInstruction instruction, ficlInteger value) 254*a1bf3f78SToomas Soome { 255*a1bf3f78SToomas Soome ficlWord *word = ficlDictionaryLookup(dictionary, name); 256*a1bf3f78SToomas Soome ficlCell c; 257*a1bf3f78SToomas Soome 258*a1bf3f78SToomas Soome if (word == NULL) { 259*a1bf3f78SToomas Soome word = ficlDictionaryAppendConstantInstruction(dictionary, 260*a1bf3f78SToomas Soome name, instruction, value); 261*a1bf3f78SToomas Soome } else { 262*a1bf3f78SToomas Soome word->code = (ficlPrimitive)instruction; 263*a1bf3f78SToomas Soome c.i = value; 264*a1bf3f78SToomas Soome word->param[0] = c; 265*a1bf3f78SToomas Soome } 266*a1bf3f78SToomas Soome return (word); 267*a1bf3f78SToomas Soome } 268*a1bf3f78SToomas Soome 269*a1bf3f78SToomas Soome ficlWord * 270*a1bf3f78SToomas Soome ficlDictionarySetConstant(ficlDictionary *dictionary, char *name, 271*a1bf3f78SToomas Soome ficlInteger value) 272*a1bf3f78SToomas Soome { 273*a1bf3f78SToomas Soome ficlString s; 274*a1bf3f78SToomas Soome FICL_STRING_SET_FROM_CSTRING(s, name); 275*a1bf3f78SToomas Soome return (ficlDictionarySetConstantInstruction(dictionary, s, 276*a1bf3f78SToomas Soome ficlInstructionConstantParen, value)); 277*a1bf3f78SToomas Soome } 278*a1bf3f78SToomas Soome 279*a1bf3f78SToomas Soome ficlWord * 280*a1bf3f78SToomas Soome ficlDictionarySet2ConstantInstruction(ficlDictionary *dictionary, ficlString s, 281*a1bf3f78SToomas Soome ficlInstruction instruction, ficl2Integer value) 282*a1bf3f78SToomas Soome { 283*a1bf3f78SToomas Soome ficlWord *word; 284*a1bf3f78SToomas Soome word = ficlDictionaryLookup(dictionary, s); 285*a1bf3f78SToomas Soome 286*a1bf3f78SToomas Soome /* 287*a1bf3f78SToomas Soome * only reuse the existing word if we're sure it has space for a 288*a1bf3f78SToomas Soome * 2constant 289*a1bf3f78SToomas Soome */ 290*a1bf3f78SToomas Soome #if FICL_WANT_FLOAT 291*a1bf3f78SToomas Soome if ((word != NULL) && 292*a1bf3f78SToomas Soome ((((ficlInstruction)word->code) == ficlInstruction2ConstantParen) || 293*a1bf3f78SToomas Soome (((ficlInstruction)word->code) == ficlInstructionF2ConstantParen))) 294*a1bf3f78SToomas Soome #else 295*a1bf3f78SToomas Soome if ((word != NULL) && 296*a1bf3f78SToomas Soome ((((ficlInstruction)word->code) == ficlInstruction2ConstantParen))) 297*a1bf3f78SToomas Soome #endif /* FICL_WANT_FLOAT */ 298*a1bf3f78SToomas Soome { 299*a1bf3f78SToomas Soome word->code = (ficlPrimitive)instruction; 300*a1bf3f78SToomas Soome word->param[0].u = FICL_2UNSIGNED_GET_HIGH(value); 301*a1bf3f78SToomas Soome word->param[1].u = FICL_2UNSIGNED_GET_LOW(value); 302*a1bf3f78SToomas Soome } else { 303*a1bf3f78SToomas Soome word = ficlDictionaryAppend2ConstantInstruction(dictionary, s, 304*a1bf3f78SToomas Soome instruction, value); 305*a1bf3f78SToomas Soome } 306*a1bf3f78SToomas Soome 307*a1bf3f78SToomas Soome return (word); 308*a1bf3f78SToomas Soome } 309*a1bf3f78SToomas Soome 310*a1bf3f78SToomas Soome ficlWord * 311*a1bf3f78SToomas Soome ficlDictionarySet2Constant(ficlDictionary *dictionary, char *name, 312*a1bf3f78SToomas Soome ficl2Integer value) 313*a1bf3f78SToomas Soome { 314*a1bf3f78SToomas Soome ficlString s; 315*a1bf3f78SToomas Soome FICL_STRING_SET_FROM_CSTRING(s, name); 316*a1bf3f78SToomas Soome 317*a1bf3f78SToomas Soome return (ficlDictionarySet2ConstantInstruction(dictionary, s, 318*a1bf3f78SToomas Soome ficlInstruction2ConstantParen, value)); 319*a1bf3f78SToomas Soome } 320*a1bf3f78SToomas Soome 321*a1bf3f78SToomas Soome ficlWord * 322*a1bf3f78SToomas Soome ficlDictionarySetConstantString(ficlDictionary *dictionary, char *name, 323*a1bf3f78SToomas Soome char *value) 324*a1bf3f78SToomas Soome { 325*a1bf3f78SToomas Soome ficlString s; 326*a1bf3f78SToomas Soome ficl2Integer valueAs2Integer; 327*a1bf3f78SToomas Soome FICL_2INTEGER_SET(strlen(value), (intptr_t)value, valueAs2Integer); 328*a1bf3f78SToomas Soome FICL_STRING_SET_FROM_CSTRING(s, name); 329*a1bf3f78SToomas Soome 330*a1bf3f78SToomas Soome return (ficlDictionarySet2ConstantInstruction(dictionary, s, 331*a1bf3f78SToomas Soome ficlInstruction2ConstantParen, valueAs2Integer)); 332*a1bf3f78SToomas Soome } 333*a1bf3f78SToomas Soome 334*a1bf3f78SToomas Soome /* 335*a1bf3f78SToomas Soome * d i c t A p p e n d W o r d 336*a1bf3f78SToomas Soome * Create a new word in the dictionary with the specified 337*a1bf3f78SToomas Soome * ficlString, code, and flags. Does not require a NULL-terminated 338*a1bf3f78SToomas Soome * name. 339*a1bf3f78SToomas Soome */ 340*a1bf3f78SToomas Soome ficlWord * 341*a1bf3f78SToomas Soome ficlDictionaryAppendWord(ficlDictionary *dictionary, ficlString name, 342*a1bf3f78SToomas Soome ficlPrimitive code, ficlUnsigned8 flags) 343*a1bf3f78SToomas Soome { 344*a1bf3f78SToomas Soome ficlUnsigned8 length = (ficlUnsigned8)FICL_STRING_GET_LENGTH(name); 345*a1bf3f78SToomas Soome char *nameCopy; 346*a1bf3f78SToomas Soome ficlWord *word; 347*a1bf3f78SToomas Soome 348*a1bf3f78SToomas Soome ficlDictionaryLock(dictionary, FICL_TRUE); 349*a1bf3f78SToomas Soome 350*a1bf3f78SToomas Soome /* 351*a1bf3f78SToomas Soome * NOTE: ficlDictionaryAppendString advances "here" as a side-effect. 352*a1bf3f78SToomas Soome * It must execute before word is initialized. 353*a1bf3f78SToomas Soome */ 354*a1bf3f78SToomas Soome nameCopy = ficlDictionaryAppendString(dictionary, name); 355*a1bf3f78SToomas Soome word = (ficlWord *)dictionary->here; 356*a1bf3f78SToomas Soome dictionary->smudge = word; 357*a1bf3f78SToomas Soome word->hash = ficlHashCode(name); 358*a1bf3f78SToomas Soome word->code = code; 359*a1bf3f78SToomas Soome word->semiParen = ficlInstructionSemiParen; 360*a1bf3f78SToomas Soome word->flags = (ficlUnsigned8)(flags | FICL_WORD_SMUDGED); 361*a1bf3f78SToomas Soome word->length = length; 362*a1bf3f78SToomas Soome word->name = nameCopy; 363*a1bf3f78SToomas Soome 364*a1bf3f78SToomas Soome /* 365*a1bf3f78SToomas Soome * Point "here" to first ficlCell of new word's param area... 366*a1bf3f78SToomas Soome */ 367*a1bf3f78SToomas Soome dictionary->here = word->param; 368*a1bf3f78SToomas Soome 369*a1bf3f78SToomas Soome if (!(flags & FICL_WORD_SMUDGED)) 370*a1bf3f78SToomas Soome ficlDictionaryUnsmudge(dictionary); 371*a1bf3f78SToomas Soome 372*a1bf3f78SToomas Soome ficlDictionaryLock(dictionary, FICL_FALSE); 373*a1bf3f78SToomas Soome return (word); 374*a1bf3f78SToomas Soome } 375*a1bf3f78SToomas Soome 376*a1bf3f78SToomas Soome /* 377*a1bf3f78SToomas Soome * d i c t A p p e n d W o r d 378*a1bf3f78SToomas Soome * Create a new word in the dictionary with the specified 379*a1bf3f78SToomas Soome * name, code, and flags. Name must be NULL-terminated. 380*a1bf3f78SToomas Soome */ 381*a1bf3f78SToomas Soome ficlWord * 382*a1bf3f78SToomas Soome ficlDictionaryAppendPrimitive(ficlDictionary *dictionary, char *name, 383*a1bf3f78SToomas Soome ficlPrimitive code, ficlUnsigned8 flags) 384*a1bf3f78SToomas Soome { 385*a1bf3f78SToomas Soome ficlString s; 386*a1bf3f78SToomas Soome FICL_STRING_SET_FROM_CSTRING(s, name); 387*a1bf3f78SToomas Soome 388*a1bf3f78SToomas Soome return (ficlDictionaryAppendWord(dictionary, s, code, flags)); 389*a1bf3f78SToomas Soome } 390*a1bf3f78SToomas Soome 391*a1bf3f78SToomas Soome ficlWord * 392*a1bf3f78SToomas Soome ficlDictionarySetPrimitive(ficlDictionary *dictionary, char *name, 393*a1bf3f78SToomas Soome ficlPrimitive code, ficlUnsigned8 flags) 394*a1bf3f78SToomas Soome { 395*a1bf3f78SToomas Soome ficlString s; 396*a1bf3f78SToomas Soome ficlWord *word; 397*a1bf3f78SToomas Soome 398*a1bf3f78SToomas Soome FICL_STRING_SET_FROM_CSTRING(s, name); 399*a1bf3f78SToomas Soome word = ficlDictionaryLookup(dictionary, s); 400*a1bf3f78SToomas Soome 401*a1bf3f78SToomas Soome if (word == NULL) { 402*a1bf3f78SToomas Soome word = ficlDictionaryAppendPrimitive(dictionary, name, 403*a1bf3f78SToomas Soome code, flags); 404*a1bf3f78SToomas Soome } else { 405*a1bf3f78SToomas Soome word->code = (ficlPrimitive)code; 406*a1bf3f78SToomas Soome word->flags = flags; 407*a1bf3f78SToomas Soome } 408*a1bf3f78SToomas Soome return (word); 409*a1bf3f78SToomas Soome } 410*a1bf3f78SToomas Soome 411*a1bf3f78SToomas Soome ficlWord * 412*a1bf3f78SToomas Soome ficlDictionaryAppendInstruction(ficlDictionary *dictionary, char *name, 413*a1bf3f78SToomas Soome ficlInstruction i, ficlUnsigned8 flags) 414*a1bf3f78SToomas Soome { 415*a1bf3f78SToomas Soome return (ficlDictionaryAppendPrimitive(dictionary, name, 416*a1bf3f78SToomas Soome (ficlPrimitive)i, (ficlUnsigned8)(FICL_WORD_INSTRUCTION | flags))); 417*a1bf3f78SToomas Soome } 418*a1bf3f78SToomas Soome 419*a1bf3f78SToomas Soome ficlWord * 420*a1bf3f78SToomas Soome ficlDictionarySetInstruction(ficlDictionary *dictionary, char *name, 421*a1bf3f78SToomas Soome ficlInstruction i, ficlUnsigned8 flags) 422*a1bf3f78SToomas Soome { 423*a1bf3f78SToomas Soome return (ficlDictionarySetPrimitive(dictionary, name, 424*a1bf3f78SToomas Soome (ficlPrimitive)i, (ficlUnsigned8)(FICL_WORD_INSTRUCTION | flags))); 425*a1bf3f78SToomas Soome } 426*a1bf3f78SToomas Soome 427*a1bf3f78SToomas Soome /* 428*a1bf3f78SToomas Soome * d i c t C e l l s A v a i l 429*a1bf3f78SToomas Soome * Returns the number of empty ficlCells left in the dictionary 430*a1bf3f78SToomas Soome */ 431*a1bf3f78SToomas Soome int 432*a1bf3f78SToomas Soome ficlDictionaryCellsAvailable(ficlDictionary *dictionary) 433*a1bf3f78SToomas Soome { 434*a1bf3f78SToomas Soome return (dictionary->size - ficlDictionaryCellsUsed(dictionary)); 435*a1bf3f78SToomas Soome } 436*a1bf3f78SToomas Soome 437*a1bf3f78SToomas Soome /* 438*a1bf3f78SToomas Soome * d i c t C e l l s U s e d 439*a1bf3f78SToomas Soome * Returns the number of ficlCells consumed in the dicionary 440*a1bf3f78SToomas Soome */ 441*a1bf3f78SToomas Soome int 442*a1bf3f78SToomas Soome ficlDictionaryCellsUsed(ficlDictionary *dictionary) 443*a1bf3f78SToomas Soome { 444*a1bf3f78SToomas Soome return (dictionary->here - dictionary->base); 445*a1bf3f78SToomas Soome } 446*a1bf3f78SToomas Soome 447*a1bf3f78SToomas Soome /* 448*a1bf3f78SToomas Soome * d i c t C r e a t e 449*a1bf3f78SToomas Soome * Create and initialize a dictionary with the specified number 450*a1bf3f78SToomas Soome * of ficlCells capacity, and no hashing (hash size == 1). 451*a1bf3f78SToomas Soome */ 452*a1bf3f78SToomas Soome ficlDictionary * 453*a1bf3f78SToomas Soome ficlDictionaryCreate(ficlSystem *system, unsigned size) 454*a1bf3f78SToomas Soome { 455*a1bf3f78SToomas Soome return (ficlDictionaryCreateHashed(system, size, 1)); 456*a1bf3f78SToomas Soome } 457*a1bf3f78SToomas Soome 458*a1bf3f78SToomas Soome ficlDictionary * 459*a1bf3f78SToomas Soome ficlDictionaryCreateHashed(ficlSystem *system, unsigned size, 460*a1bf3f78SToomas Soome unsigned bucketCount) 461*a1bf3f78SToomas Soome { 462*a1bf3f78SToomas Soome ficlDictionary *dictionary; 463*a1bf3f78SToomas Soome size_t nAlloc; 464*a1bf3f78SToomas Soome 465*a1bf3f78SToomas Soome nAlloc = sizeof (ficlDictionary) + (size * sizeof (ficlCell)) 466*a1bf3f78SToomas Soome + sizeof (ficlHash) + (bucketCount - 1) * sizeof (ficlWord *); 467*a1bf3f78SToomas Soome 468*a1bf3f78SToomas Soome dictionary = ficlMalloc(nAlloc); 469*a1bf3f78SToomas Soome FICL_SYSTEM_ASSERT(system, dictionary != NULL); 470*a1bf3f78SToomas Soome 471*a1bf3f78SToomas Soome dictionary->size = size; 472*a1bf3f78SToomas Soome dictionary->system = system; 473*a1bf3f78SToomas Soome 474*a1bf3f78SToomas Soome ficlDictionaryEmpty(dictionary, bucketCount); 475*a1bf3f78SToomas Soome return (dictionary); 476*a1bf3f78SToomas Soome } 477*a1bf3f78SToomas Soome 478*a1bf3f78SToomas Soome /* 479*a1bf3f78SToomas Soome * d i c t C r e a t e W o r d l i s t 480*a1bf3f78SToomas Soome * Create and initialize an anonymous wordlist 481*a1bf3f78SToomas Soome */ 482*a1bf3f78SToomas Soome ficlHash * 483*a1bf3f78SToomas Soome ficlDictionaryCreateWordlist(ficlDictionary *dictionary, int bucketCount) 484*a1bf3f78SToomas Soome { 485*a1bf3f78SToomas Soome ficlHash *hash; 486*a1bf3f78SToomas Soome 487*a1bf3f78SToomas Soome ficlDictionaryAlign(dictionary); 488*a1bf3f78SToomas Soome hash = (ficlHash *)dictionary->here; 489*a1bf3f78SToomas Soome ficlDictionaryAllot(dictionary, 490*a1bf3f78SToomas Soome sizeof (ficlHash) + (bucketCount - 1) * sizeof (ficlWord *)); 491*a1bf3f78SToomas Soome 492*a1bf3f78SToomas Soome hash->size = bucketCount; 493*a1bf3f78SToomas Soome ficlHashReset(hash); 494*a1bf3f78SToomas Soome return (hash); 495*a1bf3f78SToomas Soome } 496*a1bf3f78SToomas Soome 497*a1bf3f78SToomas Soome /* 498*a1bf3f78SToomas Soome * d i c t D e l e t e 499*a1bf3f78SToomas Soome * Free all memory allocated for the given dictionary 500*a1bf3f78SToomas Soome */ 501*a1bf3f78SToomas Soome void 502*a1bf3f78SToomas Soome ficlDictionaryDestroy(ficlDictionary *dictionary) 503*a1bf3f78SToomas Soome { 504*a1bf3f78SToomas Soome FICL_DICTIONARY_ASSERT(dictionary, dictionary != NULL); 505*a1bf3f78SToomas Soome ficlFree(dictionary); 506*a1bf3f78SToomas Soome } 507*a1bf3f78SToomas Soome 508*a1bf3f78SToomas Soome /* 509*a1bf3f78SToomas Soome * d i c t E m p t y 510*a1bf3f78SToomas Soome * Empty the dictionary, reset its hash table, and reset its search order. 511*a1bf3f78SToomas Soome * Clears and (re-)creates the hash table with the size specified by nHash. 512*a1bf3f78SToomas Soome */ 513*a1bf3f78SToomas Soome void 514*a1bf3f78SToomas Soome ficlDictionaryEmpty(ficlDictionary *dictionary, unsigned bucketCount) 515*a1bf3f78SToomas Soome { 516*a1bf3f78SToomas Soome ficlHash *hash; 517*a1bf3f78SToomas Soome 518*a1bf3f78SToomas Soome dictionary->here = dictionary->base; 519*a1bf3f78SToomas Soome 520*a1bf3f78SToomas Soome ficlDictionaryAlign(dictionary); 521*a1bf3f78SToomas Soome hash = (ficlHash *)dictionary->here; 522*a1bf3f78SToomas Soome ficlDictionaryAllot(dictionary, 523*a1bf3f78SToomas Soome sizeof (ficlHash) + (bucketCount - 1) * sizeof (ficlWord *)); 524*a1bf3f78SToomas Soome 525*a1bf3f78SToomas Soome hash->size = bucketCount; 526*a1bf3f78SToomas Soome ficlHashReset(hash); 527*a1bf3f78SToomas Soome 528*a1bf3f78SToomas Soome dictionary->forthWordlist = hash; 529*a1bf3f78SToomas Soome dictionary->smudge = NULL; 530*a1bf3f78SToomas Soome ficlDictionaryResetSearchOrder(dictionary); 531*a1bf3f78SToomas Soome } 532*a1bf3f78SToomas Soome 533*a1bf3f78SToomas Soome /* 534*a1bf3f78SToomas Soome * i s A F i c l W o r d 535*a1bf3f78SToomas Soome * Vet a candidate pointer carefully to make sure 536*a1bf3f78SToomas Soome * it's not some chunk o' inline data... 537*a1bf3f78SToomas Soome * It has to have a name, and it has to look 538*a1bf3f78SToomas Soome * like it's in the dictionary address range. 539*a1bf3f78SToomas Soome * NOTE: this excludes :noname words! 540*a1bf3f78SToomas Soome */ 541*a1bf3f78SToomas Soome int 542*a1bf3f78SToomas Soome ficlDictionaryIsAWord(ficlDictionary *dictionary, ficlWord *word) 543*a1bf3f78SToomas Soome { 544*a1bf3f78SToomas Soome if ((((ficlInstruction)word) > ficlInstructionInvalid) && 545*a1bf3f78SToomas Soome (((ficlInstruction)word) < ficlInstructionLast)) 546*a1bf3f78SToomas Soome return (1); 547*a1bf3f78SToomas Soome 548*a1bf3f78SToomas Soome if (!ficlDictionaryIncludes(dictionary, word)) 549*a1bf3f78SToomas Soome return (0); 550*a1bf3f78SToomas Soome 551*a1bf3f78SToomas Soome if (!ficlDictionaryIncludes(dictionary, word->name)) 552*a1bf3f78SToomas Soome return (0); 553*a1bf3f78SToomas Soome 554*a1bf3f78SToomas Soome if ((word->link != NULL) && 555*a1bf3f78SToomas Soome !ficlDictionaryIncludes(dictionary, word->link)) 556*a1bf3f78SToomas Soome return (0); 557*a1bf3f78SToomas Soome 558*a1bf3f78SToomas Soome if ((word->length <= 0) || (word->name[word->length] != '\0')) 559*a1bf3f78SToomas Soome return (0); 560*a1bf3f78SToomas Soome 561*a1bf3f78SToomas Soome if (strlen(word->name) != word->length) 562*a1bf3f78SToomas Soome return (0); 563*a1bf3f78SToomas Soome 564*a1bf3f78SToomas Soome return (1); 565*a1bf3f78SToomas Soome } 566*a1bf3f78SToomas Soome 567*a1bf3f78SToomas Soome /* 568*a1bf3f78SToomas Soome * f i n d E n c l o s i n g W o r d 569*a1bf3f78SToomas Soome * Given a pointer to something, check to make sure it's an address in the 570*a1bf3f78SToomas Soome * dictionary. If so, search backwards until we find something that looks 571*a1bf3f78SToomas Soome * like a dictionary header. If successful, return the address of the 572*a1bf3f78SToomas Soome * ficlWord found. Otherwise return NULL. nSEARCH_CELLS sets the maximum 573*a1bf3f78SToomas Soome * neighborhood this func will search before giving up 574*a1bf3f78SToomas Soome */ 575*a1bf3f78SToomas Soome #define nSEARCH_CELLS 100 576*a1bf3f78SToomas Soome 577*a1bf3f78SToomas Soome ficlWord * 578*a1bf3f78SToomas Soome ficlDictionaryFindEnclosingWord(ficlDictionary *dictionary, ficlCell *cell) 579*a1bf3f78SToomas Soome { 580*a1bf3f78SToomas Soome ficlWord *word; 581*a1bf3f78SToomas Soome int i; 582*a1bf3f78SToomas Soome 583*a1bf3f78SToomas Soome if (!ficlDictionaryIncludes(dictionary, (void *)cell)) 584*a1bf3f78SToomas Soome return (NULL); 585*a1bf3f78SToomas Soome 586*a1bf3f78SToomas Soome for (i = nSEARCH_CELLS; i > 0; --i, --cell) { 587*a1bf3f78SToomas Soome word = (ficlWord *) 588*a1bf3f78SToomas Soome (cell + 1 - (sizeof (ficlWord) / sizeof (ficlCell))); 589*a1bf3f78SToomas Soome if (ficlDictionaryIsAWord(dictionary, word)) 590*a1bf3f78SToomas Soome return (word); 591*a1bf3f78SToomas Soome } 592*a1bf3f78SToomas Soome 593*a1bf3f78SToomas Soome return (NULL); 594*a1bf3f78SToomas Soome } 595*a1bf3f78SToomas Soome 596*a1bf3f78SToomas Soome /* 597*a1bf3f78SToomas Soome * d i c t I n c l u d e s 598*a1bf3f78SToomas Soome * Returns FICL_TRUE iff the given pointer is within the address range of 599*a1bf3f78SToomas Soome * the dictionary. 600*a1bf3f78SToomas Soome */ 601*a1bf3f78SToomas Soome int 602*a1bf3f78SToomas Soome ficlDictionaryIncludes(ficlDictionary *dictionary, void *p) 603*a1bf3f78SToomas Soome { 604*a1bf3f78SToomas Soome return ((p >= (void *) &dictionary->base) && 605*a1bf3f78SToomas Soome (p < (void *)(&dictionary->base + dictionary->size))); 606*a1bf3f78SToomas Soome } 607*a1bf3f78SToomas Soome 608*a1bf3f78SToomas Soome /* 609*a1bf3f78SToomas Soome * d i c t L o o k u p 610*a1bf3f78SToomas Soome * Find the ficlWord that matches the given name and length. 611*a1bf3f78SToomas Soome * If found, returns the word's address. Otherwise returns NULL. 612*a1bf3f78SToomas Soome * Uses the search order list to search multiple wordlists. 613*a1bf3f78SToomas Soome */ 614*a1bf3f78SToomas Soome ficlWord * 615*a1bf3f78SToomas Soome ficlDictionaryLookup(ficlDictionary *dictionary, ficlString name) 616*a1bf3f78SToomas Soome { 617*a1bf3f78SToomas Soome ficlWord *word = NULL; 618*a1bf3f78SToomas Soome ficlHash *hash; 619*a1bf3f78SToomas Soome int i; 620*a1bf3f78SToomas Soome ficlUnsigned16 hashCode = ficlHashCode(name); 621*a1bf3f78SToomas Soome 622*a1bf3f78SToomas Soome FICL_DICTIONARY_ASSERT(dictionary, dictionary != NULL); 623*a1bf3f78SToomas Soome 624*a1bf3f78SToomas Soome ficlDictionaryLock(dictionary, FICL_TRUE); 625*a1bf3f78SToomas Soome 626*a1bf3f78SToomas Soome for (i = (int)dictionary->wordlistCount - 1; (i >= 0) && (!word); --i) { 627*a1bf3f78SToomas Soome hash = dictionary->wordlists[i]; 628*a1bf3f78SToomas Soome word = ficlHashLookup(hash, name, hashCode); 629*a1bf3f78SToomas Soome } 630*a1bf3f78SToomas Soome 631*a1bf3f78SToomas Soome ficlDictionaryLock(dictionary, FICL_FALSE); 632*a1bf3f78SToomas Soome return (word); 633*a1bf3f78SToomas Soome } 634*a1bf3f78SToomas Soome 635*a1bf3f78SToomas Soome /* 636*a1bf3f78SToomas Soome * s e e 637*a1bf3f78SToomas Soome * TOOLS ( "<spaces>name" -- ) 638*a1bf3f78SToomas Soome * Display a human-readable representation of the named word's definition. 639*a1bf3f78SToomas Soome * The source of the representation (object-code decompilation, source 640*a1bf3f78SToomas Soome * block, etc.) and the particular form of the display is implementation 641*a1bf3f78SToomas Soome * defined. 642*a1bf3f78SToomas Soome */ 643*a1bf3f78SToomas Soome /* 644*a1bf3f78SToomas Soome * ficlSeeColon (for proctologists only) 645*a1bf3f78SToomas Soome * Walks a colon definition, decompiling 646*a1bf3f78SToomas Soome * on the fly. Knows about primitive control structures. 647*a1bf3f78SToomas Soome */ 648*a1bf3f78SToomas Soome char *ficlDictionaryInstructionNames[] = 649*a1bf3f78SToomas Soome { 650*a1bf3f78SToomas Soome #define FICL_TOKEN(token, description) description, 651*a1bf3f78SToomas Soome #define FICL_INSTRUCTION_TOKEN(token, description, flags) description, 652*a1bf3f78SToomas Soome #include "ficltokens.h" 653*a1bf3f78SToomas Soome #undef FICL_TOKEN 654*a1bf3f78SToomas Soome #undef FICL_INSTRUCTION_TOKEN 655*a1bf3f78SToomas Soome }; 656*a1bf3f78SToomas Soome 657*a1bf3f78SToomas Soome void 658*a1bf3f78SToomas Soome ficlDictionarySee(ficlDictionary *dictionary, ficlWord *word, 659*a1bf3f78SToomas Soome ficlCallback *callback) 660*a1bf3f78SToomas Soome { 661*a1bf3f78SToomas Soome char *trace; 662*a1bf3f78SToomas Soome ficlCell *cell = word->param; 663*a1bf3f78SToomas Soome ficlCell *param0 = cell; 664*a1bf3f78SToomas Soome char buffer[128]; 665*a1bf3f78SToomas Soome 666*a1bf3f78SToomas Soome for (; cell->i != ficlInstructionSemiParen; cell++) { 667*a1bf3f78SToomas Soome ficlWord *word = (ficlWord *)(cell->p); 668*a1bf3f78SToomas Soome 669*a1bf3f78SToomas Soome trace = buffer; 670*a1bf3f78SToomas Soome if ((void *)cell == (void *)buffer) 671*a1bf3f78SToomas Soome *trace++ = '>'; 672*a1bf3f78SToomas Soome else 673*a1bf3f78SToomas Soome *trace++ = ' '; 674*a1bf3f78SToomas Soome trace += sprintf(trace, "%3ld ", (long)(cell - param0)); 675*a1bf3f78SToomas Soome 676*a1bf3f78SToomas Soome if (ficlDictionaryIsAWord(dictionary, word)) { 677*a1bf3f78SToomas Soome ficlWordKind kind = ficlWordClassify(word); 678*a1bf3f78SToomas Soome ficlCell c, c2; 679*a1bf3f78SToomas Soome 680*a1bf3f78SToomas Soome switch (kind) { 681*a1bf3f78SToomas Soome case FICL_WORDKIND_INSTRUCTION: 682*a1bf3f78SToomas Soome sprintf(trace, "%s (instruction %ld)", 683*a1bf3f78SToomas Soome ficlDictionaryInstructionNames[(long)word], 684*a1bf3f78SToomas Soome (long)word); 685*a1bf3f78SToomas Soome break; 686*a1bf3f78SToomas Soome case FICL_WORDKIND_INSTRUCTION_WITH_ARGUMENT: 687*a1bf3f78SToomas Soome c = *++cell; 688*a1bf3f78SToomas Soome sprintf(trace, "%s (instruction %ld), with " 689*a1bf3f78SToomas Soome "argument %ld (%#lx)", 690*a1bf3f78SToomas Soome ficlDictionaryInstructionNames[(long)word], 691*a1bf3f78SToomas Soome (long)word, (long)c.i, (unsigned long)c.u); 692*a1bf3f78SToomas Soome break; 693*a1bf3f78SToomas Soome case FICL_WORDKIND_INSTRUCTION_WORD: 694*a1bf3f78SToomas Soome sprintf(trace, 695*a1bf3f78SToomas Soome "%s :: executes %s (instruction word %ld)", 696*a1bf3f78SToomas Soome word->name, 697*a1bf3f78SToomas Soome ficlDictionaryInstructionNames[ 698*a1bf3f78SToomas Soome (long)word->code], (long)word->code); 699*a1bf3f78SToomas Soome break; 700*a1bf3f78SToomas Soome case FICL_WORDKIND_LITERAL: 701*a1bf3f78SToomas Soome c = *++cell; 702*a1bf3f78SToomas Soome if (ficlDictionaryIsAWord(dictionary, c.p) && 703*a1bf3f78SToomas Soome (c.i >= ficlInstructionLast)) { 704*a1bf3f78SToomas Soome ficlWord *word = (ficlWord *)c.p; 705*a1bf3f78SToomas Soome sprintf(trace, "%.*s ( %#lx literal )", 706*a1bf3f78SToomas Soome word->length, word->name, 707*a1bf3f78SToomas Soome (unsigned long)c.u); 708*a1bf3f78SToomas Soome } else 709*a1bf3f78SToomas Soome sprintf(trace, 710*a1bf3f78SToomas Soome "literal %ld (%#lx)", (long)c.i, 711*a1bf3f78SToomas Soome (unsigned long)c.u); 712*a1bf3f78SToomas Soome break; 713*a1bf3f78SToomas Soome case FICL_WORDKIND_2LITERAL: 714*a1bf3f78SToomas Soome c = *++cell; 715*a1bf3f78SToomas Soome c2 = *++cell; 716*a1bf3f78SToomas Soome sprintf(trace, "2literal %ld %ld (%#lx %#lx)", 717*a1bf3f78SToomas Soome (long)c2.i, (long)c.i, (unsigned long)c2.u, 718*a1bf3f78SToomas Soome (unsigned long)c.u); 719*a1bf3f78SToomas Soome break; 720*a1bf3f78SToomas Soome #if FICL_WANT_FLOAT 721*a1bf3f78SToomas Soome case FICL_WORDKIND_FLITERAL: 722*a1bf3f78SToomas Soome c = *++cell; 723*a1bf3f78SToomas Soome sprintf(trace, "fliteral %f (%#lx)", 724*a1bf3f78SToomas Soome (double)c.f, (unsigned long)c.u); 725*a1bf3f78SToomas Soome break; 726*a1bf3f78SToomas Soome #endif /* FICL_WANT_FLOAT */ 727*a1bf3f78SToomas Soome case FICL_WORDKIND_STRING_LITERAL: { 728*a1bf3f78SToomas Soome ficlCountedString *counted; 729*a1bf3f78SToomas Soome counted = (ficlCountedString *)(void *)++cell; 730*a1bf3f78SToomas Soome cell = (ficlCell *) 731*a1bf3f78SToomas Soome ficlAlignPointer(counted->text + 732*a1bf3f78SToomas Soome counted->length + 1) - 1; 733*a1bf3f78SToomas Soome sprintf(trace, "s\" %.*s\"", counted->length, 734*a1bf3f78SToomas Soome counted->text); 735*a1bf3f78SToomas Soome } 736*a1bf3f78SToomas Soome break; 737*a1bf3f78SToomas Soome case FICL_WORDKIND_CSTRING_LITERAL: { 738*a1bf3f78SToomas Soome ficlCountedString *counted; 739*a1bf3f78SToomas Soome counted = (ficlCountedString *)(void *)++cell; 740*a1bf3f78SToomas Soome cell = (ficlCell *) 741*a1bf3f78SToomas Soome ficlAlignPointer(counted->text + 742*a1bf3f78SToomas Soome counted->length + 1) - 1; 743*a1bf3f78SToomas Soome sprintf(trace, "c\" %.*s\"", counted->length, 744*a1bf3f78SToomas Soome counted->text); 745*a1bf3f78SToomas Soome } 746*a1bf3f78SToomas Soome break; 747*a1bf3f78SToomas Soome case FICL_WORDKIND_BRANCH0: 748*a1bf3f78SToomas Soome c = *++cell; 749*a1bf3f78SToomas Soome sprintf(trace, "branch0 %ld", 750*a1bf3f78SToomas Soome (long)(cell + c.i - param0)); 751*a1bf3f78SToomas Soome break; 752*a1bf3f78SToomas Soome case FICL_WORDKIND_BRANCH: 753*a1bf3f78SToomas Soome c = *++cell; 754*a1bf3f78SToomas Soome sprintf(trace, "branch %ld", 755*a1bf3f78SToomas Soome (long)(cell + c.i - param0)); 756*a1bf3f78SToomas Soome break; 757*a1bf3f78SToomas Soome 758*a1bf3f78SToomas Soome case FICL_WORDKIND_QDO: 759*a1bf3f78SToomas Soome c = *++cell; 760*a1bf3f78SToomas Soome sprintf(trace, "?do (leave %ld)", 761*a1bf3f78SToomas Soome (long)((ficlCell *)c.p - param0)); 762*a1bf3f78SToomas Soome break; 763*a1bf3f78SToomas Soome case FICL_WORDKIND_DO: 764*a1bf3f78SToomas Soome c = *++cell; 765*a1bf3f78SToomas Soome sprintf(trace, "do (leave %ld)", 766*a1bf3f78SToomas Soome (long)((ficlCell *)c.p - param0)); 767*a1bf3f78SToomas Soome break; 768*a1bf3f78SToomas Soome case FICL_WORDKIND_LOOP: 769*a1bf3f78SToomas Soome c = *++cell; 770*a1bf3f78SToomas Soome sprintf(trace, "loop (branch %ld)", 771*a1bf3f78SToomas Soome (long)(cell + c.i - param0)); 772*a1bf3f78SToomas Soome break; 773*a1bf3f78SToomas Soome case FICL_WORDKIND_OF: 774*a1bf3f78SToomas Soome c = *++cell; 775*a1bf3f78SToomas Soome sprintf(trace, "of (branch %ld)", 776*a1bf3f78SToomas Soome (long)(cell + c.i - param0)); 777*a1bf3f78SToomas Soome break; 778*a1bf3f78SToomas Soome case FICL_WORDKIND_PLOOP: 779*a1bf3f78SToomas Soome c = *++cell; 780*a1bf3f78SToomas Soome sprintf(trace, "+loop (branch %ld)", 781*a1bf3f78SToomas Soome (long)(cell + c.i - param0)); 782*a1bf3f78SToomas Soome break; 783*a1bf3f78SToomas Soome default: 784*a1bf3f78SToomas Soome sprintf(trace, "%.*s", word->length, 785*a1bf3f78SToomas Soome word->name); 786*a1bf3f78SToomas Soome break; 787*a1bf3f78SToomas Soome } 788*a1bf3f78SToomas Soome } else { 789*a1bf3f78SToomas Soome /* probably not a word - punt and print value */ 790*a1bf3f78SToomas Soome sprintf(trace, "%ld ( %#lx )", (long)cell->i, 791*a1bf3f78SToomas Soome (unsigned long)cell->u); 792*a1bf3f78SToomas Soome } 793*a1bf3f78SToomas Soome 794*a1bf3f78SToomas Soome ficlCallbackTextOut(callback, buffer); 795*a1bf3f78SToomas Soome ficlCallbackTextOut(callback, "\n"); 796*a1bf3f78SToomas Soome } 797*a1bf3f78SToomas Soome 798*a1bf3f78SToomas Soome ficlCallbackTextOut(callback, ";\n"); 799*a1bf3f78SToomas Soome } 800*a1bf3f78SToomas Soome 801*a1bf3f78SToomas Soome /* 802*a1bf3f78SToomas Soome * d i c t R e s e t S e a r c h O r d e r 803*a1bf3f78SToomas Soome * Initialize the dictionary search order list to sane state 804*a1bf3f78SToomas Soome */ 805*a1bf3f78SToomas Soome void 806*a1bf3f78SToomas Soome ficlDictionaryResetSearchOrder(ficlDictionary *dictionary) 807*a1bf3f78SToomas Soome { 808*a1bf3f78SToomas Soome FICL_DICTIONARY_ASSERT(dictionary, dictionary); 809*a1bf3f78SToomas Soome dictionary->compilationWordlist = dictionary->forthWordlist; 810*a1bf3f78SToomas Soome dictionary->wordlistCount = 1; 811*a1bf3f78SToomas Soome dictionary->wordlists[0] = dictionary->forthWordlist; 812*a1bf3f78SToomas Soome } 813*a1bf3f78SToomas Soome 814*a1bf3f78SToomas Soome /* 815*a1bf3f78SToomas Soome * d i c t S e t F l a g s 816*a1bf3f78SToomas Soome * Changes the flags field of the most recently defined word: 817*a1bf3f78SToomas Soome * Set all bits that are ones in the set parameter. 818*a1bf3f78SToomas Soome */ 819*a1bf3f78SToomas Soome void 820*a1bf3f78SToomas Soome ficlDictionarySetFlags(ficlDictionary *dictionary, ficlUnsigned8 set) 821*a1bf3f78SToomas Soome { 822*a1bf3f78SToomas Soome FICL_DICTIONARY_ASSERT(dictionary, dictionary->smudge); 823*a1bf3f78SToomas Soome dictionary->smudge->flags |= set; 824*a1bf3f78SToomas Soome } 825*a1bf3f78SToomas Soome 826*a1bf3f78SToomas Soome 827*a1bf3f78SToomas Soome /* 828*a1bf3f78SToomas Soome * d i c t C l e a r F l a g s 829*a1bf3f78SToomas Soome * Changes the flags field of the most recently defined word: 830*a1bf3f78SToomas Soome * Clear all bits that are ones in the clear parameter. 831*a1bf3f78SToomas Soome */ 832*a1bf3f78SToomas Soome void 833*a1bf3f78SToomas Soome ficlDictionaryClearFlags(ficlDictionary *dictionary, ficlUnsigned8 clear) 834*a1bf3f78SToomas Soome { 835*a1bf3f78SToomas Soome FICL_DICTIONARY_ASSERT(dictionary, dictionary->smudge); 836*a1bf3f78SToomas Soome dictionary->smudge->flags &= ~clear; 837*a1bf3f78SToomas Soome } 838*a1bf3f78SToomas Soome 839*a1bf3f78SToomas Soome /* 840*a1bf3f78SToomas Soome * d i c t S e t I m m e d i a t e 841*a1bf3f78SToomas Soome * Set the most recently defined word as IMMEDIATE 842*a1bf3f78SToomas Soome */ 843*a1bf3f78SToomas Soome void 844*a1bf3f78SToomas Soome ficlDictionarySetImmediate(ficlDictionary *dictionary) 845*a1bf3f78SToomas Soome { 846*a1bf3f78SToomas Soome FICL_DICTIONARY_ASSERT(dictionary, dictionary->smudge); 847*a1bf3f78SToomas Soome dictionary->smudge->flags |= FICL_WORD_IMMEDIATE; 848*a1bf3f78SToomas Soome } 849*a1bf3f78SToomas Soome 850*a1bf3f78SToomas Soome /* 851*a1bf3f78SToomas Soome * d i c t U n s m u d g e 852*a1bf3f78SToomas Soome * Completes the definition of a word by linking it 853*a1bf3f78SToomas Soome * into the main list 854*a1bf3f78SToomas Soome */ 855*a1bf3f78SToomas Soome void 856*a1bf3f78SToomas Soome ficlDictionaryUnsmudge(ficlDictionary *dictionary) 857*a1bf3f78SToomas Soome { 858*a1bf3f78SToomas Soome ficlWord *word = dictionary->smudge; 859*a1bf3f78SToomas Soome ficlHash *hash = dictionary->compilationWordlist; 860*a1bf3f78SToomas Soome 861*a1bf3f78SToomas Soome FICL_DICTIONARY_ASSERT(dictionary, hash); 862*a1bf3f78SToomas Soome FICL_DICTIONARY_ASSERT(dictionary, word); 863*a1bf3f78SToomas Soome 864*a1bf3f78SToomas Soome /* 865*a1bf3f78SToomas Soome * :noname words never get linked into the list... 866*a1bf3f78SToomas Soome */ 867*a1bf3f78SToomas Soome if (word->length > 0) 868*a1bf3f78SToomas Soome ficlHashInsertWord(hash, word); 869*a1bf3f78SToomas Soome word->flags &= ~(FICL_WORD_SMUDGED); 870*a1bf3f78SToomas Soome } 871*a1bf3f78SToomas Soome 872*a1bf3f78SToomas Soome /* 873*a1bf3f78SToomas Soome * d i c t W h e r e 874*a1bf3f78SToomas Soome * Returns the value of the HERE pointer -- the address 875*a1bf3f78SToomas Soome * of the next free ficlCell in the dictionary 876*a1bf3f78SToomas Soome */ 877*a1bf3f78SToomas Soome ficlCell * 878*a1bf3f78SToomas Soome ficlDictionaryWhere(ficlDictionary *dictionary) 879*a1bf3f78SToomas Soome { 880*a1bf3f78SToomas Soome return (dictionary->here); 881*a1bf3f78SToomas Soome } 882