/*
* d i c t . c
* Forth Inspired Command Language - dictionary methods
* Author: John Sadler (john_sadler@alum.mit.edu)
* Created: 19 July 1997
* $Id: dictionary.c,v 1.2 2010/09/12 15:14:52 asau Exp $
*/
/*
* This file implements the dictionary -- Ficl's model of
* memory management. All Ficl words are stored in the
* dictionary. A word is a named chunk of data with its
* associated code. Ficl treats all words the same, even
* precompiled ones, so your words become first-class
* extensions of the language. You can even define new
* control structures.
*
* 29 jun 1998 (sadler) added variable sized hash table support
*/
/*
* Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
* All rights reserved.
*
* Get the latest Ficl release at http://ficl.sourceforge.net
*
* I am interested in hearing from anyone who uses Ficl. If you have
* a problem, a success story, a defect, an enhancement request, or
* if you would like to contribute to the Ficl release, please
* contact me by email at the address above.
*
* L I C E N S E and D I S C L A I M E R
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "ficl.h"
/*
* d i c t A b o r t D e f i n i t i o n
* Abort a definition in process: reclaim its memory and unlink it
* from the dictionary list. Assumes that there is a smudged
* definition in process...otherwise does nothing.
* NOTE: this function is not smart enough to unlink a word that
* has been successfully defined (ie linked into a hash). It
* only works for defs in process. If the def has been unsmudged,
* nothing happens.
*/
void
{
}
/*
* d i c t A l i g n
* Align the dictionary's free space pointer
*/
void
{
}
/*
* d i c t A l l o t
* Allocate or remove n chars of dictionary space, with
* checks for underrun and overrun
*/
void
{
here += n;
}
/*
* d i c t A l l o t C e l l s
* Reserve space for the requested number of ficlCells in the
* dictionary. If nficlCells < 0 , removes space from the dictionary.
*/
void
{
}
/*
* d i c t A p p e n d C e l l
* Append the specified ficlCell to the dictionary
*/
void
{
*dictionary->here++ = c;
}
/*
* d i c t A p p e n d C h a r
* Append the specified char to the dictionary
*/
void
{
*here++ = c;
}
/*
* d i c t A p p e n d U N S
* Append the specified ficlUnsigned to the dictionary
*/
void
{
ficlCell c;
c.u = u;
}
void *
{
if (length == 0) {
return ((char *)dictionary->here);
}
while (length) {
length--;
}
*here++ = '\0';
return (oldHere);
}
/*
* d i c t C o p y N a m e
* Copy up to FICL_NAME_LENGTH characters of the name specified by s into
* the dictionary starting at "here", then NULL-terminate the name,
* point "here" to the next available byte, and return the address of
* the beginning of the name. Used by dictAppendWord.
* N O T E S :
* 1. "here" is guaranteed to be aligned after this operation.
* 2. If the string has zero length, align and return "here"
*/
char *
{
if (length > FICL_NAME_LENGTH)
}
ficlWord *
{
return (word);
}
ficlWord *
{
}
return (word);
}
ficlWord *
{
ficlString s;
return (ficlDictionaryAppendConstantInstruction(dictionary, s,
}
ficlWord *
{
ficlString s;
return (ficlDictionaryAppend2ConstantInstruction(dictionary, s,
}
ficlWord *
{
ficlCell c;
} else {
c.i = value;
}
return (word);
}
ficlWord *
{
ficlString s;
return (ficlDictionarySetConstantInstruction(dictionary, s,
}
ficlWord *
{
/*
* only reuse the existing word if we're sure it has space for a
* 2constant
*/
#if FICL_WANT_FLOAT
#else
#endif /* FICL_WANT_FLOAT */
{
} else {
instruction, value);
}
return (word);
}
ficlWord *
{
ficlString s;
return (ficlDictionarySet2ConstantInstruction(dictionary, s,
}
ficlWord *
char *value)
{
ficlString s;
return (ficlDictionarySet2ConstantInstruction(dictionary, s,
}
/*
* 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 *
{
char *nameCopy;
/*
* NOTE: ficlDictionaryAppendString advances "here" as a side-effect.
* It must execute before word is initialized.
*/
/*
* Point "here" to first ficlCell of new word's param area...
*/
if (!(flags & FICL_WORD_SMUDGED))
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
* name, code, and flags. Name must be NULL-terminated.
*/
ficlWord *
{
ficlString s;
}
ficlWord *
{
ficlString s;
} else {
}
return (word);
}
ficlWord *
{
}
ficlWord *
{
}
/*
* d i c t C e l l s A v a i l
* Returns the number of empty ficlCells left in the dictionary
*/
int
{
}
/*
* d i c t C e l l s U s e d
* Returns the number of ficlCells consumed in the dicionary
*/
int
{
}
/*
* d i c t C r e a t e
* Create and initialize a dictionary with the specified number
* of ficlCells capacity, and no hashing (hash size == 1).
*/
{
}
unsigned bucketCount)
{
return (dictionary);
}
/*
* d i c t C r e a t e W o r d l i s t
* Create and initialize an anonymous wordlist
*/
ficlHash *
{
return (hash);
}
/*
* d i c t D e l e t e
* Free all memory allocated for the given dictionary
*/
void
{
}
/*
* d i c t E m p t y
* Empty the dictionary, reset its hash table, and reset its search order.
* Clears and (re-)creates the hash table with the size specified by nHash.
*/
void
{
}
/*
* i s A F i c l W o r d
* Vet a candidate pointer carefully to make sure
* it's not some chunk o' inline data...
* It has to have a name, and it has to look
* like it's in the dictionary address range.
* NOTE: this excludes :noname words!
*/
int
{
return (1);
return (0);
return (0);
return (0);
return (0);
return (0);
return (1);
}
/*
* f i n d E n c l o s i n g W o r d
* Given a pointer to something, check to make sure it's an address in the
* dictionary. If so, search backwards until we find something that looks
* like a dictionary header. If successful, return the address of the
* ficlWord found. Otherwise return NULL. nSEARCH_CELLS sets the maximum
* neighborhood this func will search before giving up
*/
ficlWord *
{
int i;
return (NULL);
for (i = nSEARCH_CELLS; i > 0; --i, --cell) {
return (word);
}
return (NULL);
}
/*
* d i c t I n c l u d e s
* Returns FICL_TRUE iff the given pointer is within the address range of
* the dictionary.
*/
int
{
return ((p >= (void *) &dictionary->base) &&
}
/*
* 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 *
{
int i;
}
return (word);
}
/*
* s e e
* TOOLS ( "<spaces>name" -- )
* Display a human-readable representation of the named word's definition.
* The source of the representation (object-code decompilation, source
* block, etc.) and the particular form of the display is implementation
* defined.
*/
/*
* ficlSeeColon (for proctologists only)
* Walks a colon definition, decompiling
* on the fly. Knows about primitive control structures.
*/
char *ficlDictionaryInstructionNames[] =
{
#include "ficltokens.h"
};
void
{
char *trace;
*trace++ = '>';
else
*trace++ = ' ';
switch (kind) {
ficlDictionaryInstructionNames[(long)word],
(long)word);
break;
c = *++cell;
"argument %ld (%#lx)",
ficlDictionaryInstructionNames[(long)word],
(long)word, (long)c.i, (unsigned long)c.u);
break;
"%s :: executes %s (instruction word %ld)",
break;
case FICL_WORDKIND_LITERAL:
c = *++cell;
if (ficlDictionaryIsAWord(dictionary, c.p) &&
(c.i >= ficlInstructionLast)) {
(unsigned long)c.u);
} else
"literal %ld (%#lx)", (long)c.i,
(unsigned long)c.u);
break;
case FICL_WORDKIND_2LITERAL:
c = *++cell;
(unsigned long)c.u);
break;
#if FICL_WANT_FLOAT
case FICL_WORDKIND_FLITERAL:
c = *++cell;
(double)c.f, (unsigned long)c.u);
break;
#endif /* FICL_WANT_FLOAT */
case FICL_WORDKIND_STRING_LITERAL: {
}
break;
case FICL_WORDKIND_CSTRING_LITERAL: {
}
break;
case FICL_WORDKIND_BRANCH0:
c = *++cell;
break;
case FICL_WORDKIND_BRANCH:
c = *++cell;
break;
case FICL_WORDKIND_QDO:
c = *++cell;
break;
case FICL_WORDKIND_DO:
c = *++cell;
break;
case FICL_WORDKIND_LOOP:
c = *++cell;
break;
case FICL_WORDKIND_OF:
c = *++cell;
break;
case FICL_WORDKIND_PLOOP:
c = *++cell;
break;
default:
break;
}
} else {
/* probably not a word - punt and print value */
(unsigned long)cell->u);
}
}
}
/*
* d i c t R e s e t S e a r c h O r d e r
* Initialize the dictionary search order list to sane state
*/
void
{
}
/*
* d i c t S e t F l a g s
* Changes the flags field of the most recently defined word:
* Set all bits that are ones in the set parameter.
*/
void
{
}
/*
* d i c t C l e a r F l a g s
* Changes the flags field of the most recently defined word:
* Clear all bits that are ones in the clear parameter.
*/
void
{
}
/*
* d i c t S e t I m m e d i a t e
* Set the most recently defined word as IMMEDIATE
*/
void
{
}
/*
* d i c t U n s m u d g e
* Completes the definition of a word by linking it
* into the main list
*/
void
{
/*
* :noname words never get linked into the list...
*/
}
/*
* d i c t W h e r e
* Returns the value of the HERE pointer -- the address
* of the next free ficlCell in the dictionary
*/
ficlCell *
{
return (dictionary->here);
}