📄 symbol.c
字号:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.24 06/05/06 */ /* */ /* SYMBOL MODULE */ /*******************************************************//*************************************************************//* Purpose: Manages the atomic data value hash tables for *//* storing symbols, integers, floats, and bit maps. *//* Contains routines for adding entries, examining the *//* hash tables, and performing garbage collection to *//* remove entries no longer in use. *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* *//* Contributing Programmer(s): *//* Brian L. Donnell *//* *//* Revision History: *//* 6.23: Correction for FalseSymbol/TrueSymbol. DR0859 *//* *//* 6.24: CLIPS crashing on AMD64 processor in the *//* function used to generate a hash value for *//* integers. DR0871 *//* *//* Support for run-time programs directly passing *//* the hash tables for initialization. *//* *//* Corrected code generating compilation *//* warnings. *//* *//*************************************************************/#define _SYMBOL_SOURCE_ #include <stdio.h>#define _STDIO_INCLUDED_#include <stdlib.h>#include <string.h>#include "setup.h"#include "constant.h"#include "envrnmnt.h"#include "memalloc.h"#include "router.h"#include "utility.h"#include "argacces.h"#include "sysdep.h"#include "symbol.h"/***************//* DEFINITIONS *//***************/#define FALSE_STRING "FALSE"#define TRUE_STRING "TRUE"#define POSITIVE_INFINITY_STRING "+oo"#define NEGATIVE_INFINITY_STRING "-oo"#define AVERAGE_STRING_SIZE 10#define AVERAGE_BITMAP_SIZE sizeof(long)#define NUMBER_OF_LONGS_FOR_HASH 25/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/ static void RemoveHashNode(void *,GENERIC_HN *,GENERIC_HN **,int,int); static void AddEphemeralHashNode(void *,GENERIC_HN *,struct ephemeron **, int,int); static void RemoveEphemeralHashNodes(void *,struct ephemeron **, GENERIC_HN **, int,int,int); static char *StringWithinString(char *,char *); static size_t CommonPrefixLength(char *,char *); static void DeallocateSymbolData(void *);/*******************************************************//* InitializeAtomTables: Initializes the SymbolTable, *//* IntegerTable, and FloatTable. It also initializes *//* the TrueSymbol and FalseSymbol. *//*******************************************************/#if IBM_TBC && (! RUN_TIME)#pragma argsused#endifgloble void InitializeAtomTables( void *theEnv, struct symbolHashNode **symbolTable, struct floatHashNode **floatTable, struct integerHashNode **integerTable, struct bitMapHashNode **bitmapTable) {#if ! RUN_TIME#if MAC_MCW || IBM_MCW || MAC_XCD#pragma unused(symbolTable)#pragma unused(floatTable)#pragma unused(integerTable)#pragma unused(bitmapTable)#endif unsigned long i;#endif AllocateEnvironmentData(theEnv,SYMBOL_DATA,sizeof(struct symbolData),DeallocateSymbolData);#if ! RUN_TIME /*=========================*/ /* Create the hash tables. */ /*=========================*/ SymbolData(theEnv)->SymbolTable = (SYMBOL_HN **) gm3(theEnv,sizeof (SYMBOL_HN *) * SYMBOL_HASH_SIZE); SymbolData(theEnv)->FloatTable = (FLOAT_HN **) gm2(theEnv,(int) sizeof (FLOAT_HN *) * FLOAT_HASH_SIZE); SymbolData(theEnv)->IntegerTable = (INTEGER_HN **) gm2(theEnv,(int) sizeof (INTEGER_HN *) * INTEGER_HASH_SIZE); SymbolData(theEnv)->BitMapTable = (BITMAP_HN **) gm2(theEnv,(int) sizeof (BITMAP_HN *) * BITMAP_HASH_SIZE); /*===================================================*/ /* Initialize all of the hash table entries to NULL. */ /*===================================================*/ for (i = 0; i < SYMBOL_HASH_SIZE; i++) SymbolData(theEnv)->SymbolTable[i] = NULL; for (i = 0; i < FLOAT_HASH_SIZE; i++) SymbolData(theEnv)->FloatTable[i] = NULL; for (i = 0; i < INTEGER_HASH_SIZE; i++) SymbolData(theEnv)->IntegerTable[i] = NULL; for (i = 0; i < BITMAP_HASH_SIZE; i++) SymbolData(theEnv)->BitMapTable[i] = NULL; /*========================*/ /* Predefine some values. */ /*========================*/ SymbolData(theEnv)->TrueSymbolHN = EnvAddSymbol(theEnv,TRUE_STRING); IncrementSymbolCount(SymbolData(theEnv)->TrueSymbolHN); SymbolData(theEnv)->FalseSymbolHN = EnvAddSymbol(theEnv,FALSE_STRING); IncrementSymbolCount(SymbolData(theEnv)->FalseSymbolHN); SymbolData(theEnv)->PositiveInfinity = EnvAddSymbol(theEnv,POSITIVE_INFINITY_STRING); IncrementSymbolCount(SymbolData(theEnv)->PositiveInfinity); SymbolData(theEnv)->NegativeInfinity = EnvAddSymbol(theEnv,NEGATIVE_INFINITY_STRING); IncrementSymbolCount(SymbolData(theEnv)->NegativeInfinity); SymbolData(theEnv)->Zero = EnvAddLong(theEnv,0LL); IncrementIntegerCount(SymbolData(theEnv)->Zero);#else SetSymbolTable(theEnv,symbolTable); SetFloatTable(theEnv,floatTable); SetIntegerTable(theEnv,integerTable); SetBitMapTable(theEnv,bitmapTable);#endif }/*************************************************//* DeallocateSymbolData: Deallocates environment *//* data for symbols. *//*************************************************/static void DeallocateSymbolData( void *theEnv) { int i; SYMBOL_HN *shPtr, *nextSHPtr; INTEGER_HN *ihPtr, *nextIHPtr; FLOAT_HN *fhPtr, *nextFHPtr; BITMAP_HN *bmhPtr, *nextBMHPtr; struct ephemeron *edPtr, *nextEDPtr; if ((SymbolData(theEnv)->SymbolTable == NULL) || (SymbolData(theEnv)->FloatTable == NULL) || (SymbolData(theEnv)->IntegerTable == NULL) || (SymbolData(theEnv)->BitMapTable == NULL)) { return; } for (i = 0; i < SYMBOL_HASH_SIZE; i++) { shPtr = SymbolData(theEnv)->SymbolTable[i]; while (shPtr != NULL) { nextSHPtr = shPtr->next; if (! shPtr->permanent) { rm(theEnv,shPtr->contents,strlen(shPtr->contents)+1); rtn_struct(theEnv,symbolHashNode,shPtr); } shPtr = nextSHPtr; } } for (i = 0; i < FLOAT_HASH_SIZE; i++) { fhPtr = SymbolData(theEnv)->FloatTable[i]; while (fhPtr != NULL) { nextFHPtr = fhPtr->next; if (! fhPtr->permanent) { rtn_struct(theEnv,floatHashNode,fhPtr); } fhPtr = nextFHPtr; } } for (i = 0; i < INTEGER_HASH_SIZE; i++) { ihPtr = SymbolData(theEnv)->IntegerTable[i]; while (ihPtr != NULL) { nextIHPtr = ihPtr->next; if (! ihPtr->permanent) { rtn_struct(theEnv,integerHashNode,ihPtr); } ihPtr = nextIHPtr; } } for (i = 0; i < BITMAP_HASH_SIZE; i++) { bmhPtr = SymbolData(theEnv)->BitMapTable[i]; while (bmhPtr != NULL) { nextBMHPtr = bmhPtr->next; if (! bmhPtr->permanent) { rm(theEnv,bmhPtr->contents,bmhPtr->size); rtn_struct(theEnv,bitMapHashNode,bmhPtr); } bmhPtr = nextBMHPtr; } } /*=========================================*/ /* Remove the ephemeral symbol structures. */ /*=========================================*/ edPtr = SymbolData(theEnv)->EphemeralSymbolList; while (edPtr != NULL) { nextEDPtr = edPtr->next; rtn_struct(theEnv,ephemeron,edPtr); edPtr = nextEDPtr; } edPtr = SymbolData(theEnv)->EphemeralFloatList; while (edPtr != NULL) { nextEDPtr = edPtr->next; rtn_struct(theEnv,ephemeron,edPtr); edPtr = nextEDPtr; } edPtr = SymbolData(theEnv)->EphemeralIntegerList; while (edPtr != NULL) { nextEDPtr = edPtr->next; rtn_struct(theEnv,ephemeron,edPtr); edPtr = nextEDPtr; } edPtr = SymbolData(theEnv)->EphemeralBitMapList; while (edPtr != NULL) { nextEDPtr = edPtr->next; rtn_struct(theEnv,ephemeron,edPtr); edPtr = nextEDPtr; } /*================================*/ /* Remove the symbol hash tables. */ /*================================*/ #if ! RUN_TIME rm3(theEnv,SymbolData(theEnv)->SymbolTable,sizeof (SYMBOL_HN *) * SYMBOL_HASH_SIZE); genfree(theEnv,SymbolData(theEnv)->FloatTable,(int) sizeof (FLOAT_HN *) * FLOAT_HASH_SIZE); genfree(theEnv,SymbolData(theEnv)->IntegerTable,(int) sizeof (INTEGER_HN *) * INTEGER_HASH_SIZE); genfree(theEnv,SymbolData(theEnv)->BitMapTable,(int) sizeof (BITMAP_HN *) * BITMAP_HASH_SIZE);#endif /*==============================*/ /* Remove binary symbol tables. */ /*==============================*/ #if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE || BLOAD_INSTANCES || BSAVE_INSTANCES if (SymbolData(theEnv)->SymbolArray != NULL) rm3(theEnv,(void *) SymbolData(theEnv)->SymbolArray,(long) sizeof(SYMBOL_HN *) * SymbolData(theEnv)->NumberOfSymbols); if (SymbolData(theEnv)->FloatArray != NULL) rm3(theEnv,(void *) SymbolData(theEnv)->FloatArray,(long) sizeof(FLOAT_HN *) * SymbolData(theEnv)->NumberOfFloats); if (SymbolData(theEnv)->IntegerArray != NULL) rm3(theEnv,(void *) SymbolData(theEnv)->IntegerArray,(long) sizeof(INTEGER_HN *) * SymbolData(theEnv)->NumberOfIntegers); if (SymbolData(theEnv)->BitMapArray != NULL) rm3(theEnv,(void *) SymbolData(theEnv)->BitMapArray,(long) sizeof(BITMAP_HN *) * SymbolData(theEnv)->NumberOfBitMaps);#endif }/*********************************************************************//* EnvAddSymbol: Searches for the string in the symbol table. If the *//* string is already in the symbol table, then the address of the *//* string's location in the symbol table is returned. Otherwise, *//* the string is added to the symbol table and then the address *//* of the string's location in the symbol table is returned. *//*********************************************************************/globle void *EnvAddSymbol( void *theEnv, char *str) { unsigned long tally; size_t length; SYMBOL_HN *past = NULL, *peek; /*====================================*/ /* Get the hash value for the string. */ /*====================================*/ if (str == NULL) { SystemError(theEnv,"SYMBOL",1); EnvExitRouter(theEnv,EXIT_FAILURE); } tally = HashSymbol(str,SYMBOL_HASH_SIZE); peek = SymbolData(theEnv)->SymbolTable[tally]; /*==================================================*/ /* Search for the string in the list of entries for */ /* this symbol table location. If the string is */ /* found, then return the address of the string. */ /*==================================================*/ while (peek != NULL) { if (strcmp(str,peek->contents) == 0) { return((void *) peek); } past = peek; peek = peek->next; } /*==================================================*/ /* Add the string at the end of the list of entries */ /* for this symbol table location. */ /*==================================================*/ peek = get_struct(theEnv,symbolHashNode); if (past == NULL) SymbolData(theEnv)->SymbolTable[tally] = peek; else past->next = peek; length = strlen(str) + 1; peek->contents = (char *) gm2(theEnv,length); peek->next = NULL; peek->bucket = tally; peek->count = 0; peek->permanent = FALSE; genstrcpy(peek->contents,str); /*================================================*/ /* Add the string to the list of ephemeral items. */ /*================================================*/ AddEphemeralHashNode(theEnv,(GENERIC_HN *) peek,&SymbolData(theEnv)->EphemeralSymbolList, sizeof(SYMBOL_HN),AVERAGE_STRING_SIZE); peek->depth = EvaluationData(theEnv)->CurrentEvaluationDepth; /*===================================*/ /* Return the address of the symbol. */ /*===================================*/ return((void *) peek); }/*****************************************************************//* FindSymbolHN: Searches for the string in the symbol table and *//* returns a pointer to it if found, otherwise returns NULL. *//*****************************************************************/globle SYMBOL_HN *FindSymbolHN( void *theEnv, char *str) { unsigned long tally; SYMBOL_HN *peek; tally = HashSymbol(str,SYMBOL_HASH_SIZE); for (peek = SymbolData(theEnv)->SymbolTable[tally]; peek != NULL; peek = peek->next) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -