📄 symbol.c
字号:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.05 04/09/97 */ /* */ /* 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: *//* *//*************************************************************/#define _SYMBOL_SOURCE_#include <stdio.h>#define _CLIPS_STDIO_#include <string.h>#include "setup.h"#include "constant.h"#include "clipsmem.h"#include "router.h"#include "utility.h"#include "argacces.h"#include "symbol.h"/**********************************************************//* EPHEMERON STRUCTURE: Data structure used to keep track *//* of ephemeral symbols, floats, and integers. *//* *//* associatedValue: Contains a pointer to the storage *//* structure for the symbol, float, or integer which is *//* ephemeral. *//* *//* next: Contains a pointer to the next ephemeral item *//* in a list of ephemeral items. *//**********************************************************/struct ephemeron { GENERIC_HN *associatedValue; struct ephemeron *next; };/***************//* 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 *//***************************************/#if ANSI_COMPILER static VOID RemoveHashNode(GENERIC_HN *,GENERIC_HN **,int,int); static VOID AddEphemeralHashNode(GENERIC_HN *,struct ephemeron **, int,int); static VOID RemoveEphemeralHashNodes(struct ephemeron **, GENERIC_HN **, int,int,int); static char *StringWithinString(char *,char *); static int CommonPrefixLength(char *,char *);#else static VOID RemoveHashNode(); static VOID AddEphemeralHashNode(); static VOID RemoveEphemeralHashNodes(); static char *StringWithinString(); static int CommonPrefixLength();#endif/****************************************//* GLOBAL INTERNAL VARIABLE DEFINITIONS *//****************************************/ globle VOID *CLIPSTrueSymbol; globle VOID *CLIPSFalseSymbol; globle VOID *PositiveInfinity; globle VOID *NegativeInfinity; globle VOID *Zero;/***************************************//* LOCAL INTERNAL VARIABLE DEFINITIONS *//***************************************/ static SYMBOL_HN **SymbolTable; static FLOAT_HN **FloatTable; static INTEGER_HN **IntegerTable; static BITMAP_HN **BitMapTable; static struct ephemeron *EphemeralSymbolList = NULL; static struct ephemeron *EphemeralFloatList = NULL; static struct ephemeron *EphemeralIntegerList = NULL; static struct ephemeron *EphemeralBitMapList = NULL;/********************************************************************//* AddSymbol: 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 *AddSymbol(str) char *str; { int tally, length; SYMBOL_HN *past = NULL, *peek; /*====================================*/ /* Get the hash value for the string. */ /*====================================*/ if (str == NULL) { CLIPSSystemError("SYMBOL",1); ExitCLIPS(5); } tally = HashSymbol(str,SYMBOL_HASH_SIZE); peek = 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(symbolHashNode); if (past == NULL) SymbolTable[tally] = peek; else past->next = peek; length = strlen(str) + 1; peek->contents = (char *) gm2(length); peek->next = NULL; peek->bucket = tally; peek->count = 0; strcpy(peek->contents,str); /*================================================*/ /* Add the string to the list of ephemeral items. */ /*================================================*/ AddEphemeralHashNode((GENERIC_HN *) peek,&EphemeralSymbolList, sizeof(SYMBOL_HN),AVERAGE_STRING_SIZE); peek->depth = CurrentEvaluationDepth; /*===================================*/ /* Return the address of the symbol. */ /*===================================*/ return((VOID *) peek); }/***************************************************************//* FindSymbol: Searches for the string in the symbol table and *//* returns a pointer to it if found, otherwise returns NULL. *//***************************************************************/globle SYMBOL_HN *FindSymbol(str) char *str; { int tally; SYMBOL_HN *peek; tally = HashSymbol(str,SYMBOL_HASH_SIZE); for (peek = SymbolTable[tally]; peek != NULL; peek = peek->next) { if (strcmp(str,peek->contents) == 0) return(peek); } return(NULL); }/******************************************************************//* AddDouble: Searches for the double in the hash table. If the *//* double is already in the hash table, then the address of the *//* double is returned. Otherwise, the double is hashed into the *//* table and the address of the double is also returned. *//******************************************************************/globle VOID *AddDouble(number) double number; { int tally; FLOAT_HN *past = NULL, *peek; /*====================================*/ /* Get the hash value for the double. */ /*====================================*/ tally = HashFloat(number,FLOAT_HASH_SIZE); peek = FloatTable[tally]; /*==================================================*/ /* Search for the double in the list of entries for */ /* this hash location. If the double is found, */ /* then return the address of the double. */ /*==================================================*/ while (peek != NULL) { if (number == peek->contents) { return((VOID *) peek); } past = peek; peek = peek->next; } /*=================================================*/ /* Add the float at the end of the list of entries */ /* for this hash location. */ /*=================================================*/ peek = get_struct(floatHashNode); if (past == NULL) FloatTable[tally] = peek; else past->next = peek; peek->contents = number; peek->next = NULL; peek->bucket = tally; peek->count = 0; /*===============================================*/ /* Add the float to the list of ephemeral items. */ /*===============================================*/ AddEphemeralHashNode((GENERIC_HN *) peek,&EphemeralFloatList, sizeof(FLOAT_HN),0); peek->depth = CurrentEvaluationDepth; /*==================================*/ /* Return the address of the float. */ /*==================================*/ return((VOID *) peek); }/****************************************************************//* AddLong: Searches for the long in the hash table. If the *//* long is already in the hash table, then the address of the *//* long is returned. Otherwise, the long is hashed into the *//* table and the address of the long is also returned. *//****************************************************************/globle VOID *AddLong(number) long int number; { int tally; INTEGER_HN *past = NULL, *peek; /*==================================*/ /* Get the hash value for the long. */ /*==================================*/ tally = HashInteger(number,INTEGER_HASH_SIZE); peek = IntegerTable[tally]; /*================================================*/ /* Search for the long in the list of entries for */ /* this hash location. If the long is found, then */ /* return the address of the long. */ /*================================================*/ while (peek != NULL) { if (number == peek->contents) { return((VOID *) peek); } past = peek; peek = peek->next; } /*================================================*/ /* Add the long at the end of the list of entries */ /* for this hash location. */ /*================================================*/ peek = get_struct(integerHashNode); if (past == NULL) IntegerTable[tally] = peek; else past->next = peek; peek->contents = number; peek->next = NULL; peek->bucket = tally; peek->count = 0; /*=================================================*/ /* Add the integer to the list of ephemeral items. */ /*=================================================*/ AddEphemeralHashNode((GENERIC_HN *) peek,&EphemeralIntegerList, sizeof(INTEGER_HN),0); peek->depth = CurrentEvaluationDepth; /*====================================*/ /* Return the address of the integer. */ /*====================================*/ return((VOID *) peek); } /***************************************************************//* FindLong: Searches for the integer in the integer table and *//* returns a pointer to it if found, otherwise returns NULL. *//***************************************************************/globle INTEGER_HN *FindLong(theLong) long int theLong; { int tally; INTEGER_HN *peek; tally = HashInteger(theLong,INTEGER_HASH_SIZE); for (peek = IntegerTable[tally]; peek != NULL; peek = peek->next) { if (peek->contents == theLong) return(peek); } return(NULL); }/******************************************************************//* AddBitMap: Searches for the bitmap in the hash table. If the *//* bitmap is already in the hash table, then the address of the *//* bitmap is returned. Otherwise, the bitmap is hashed into the *//* table and the address of the bitmap is also returned. *//******************************************************************/globle VOID *AddBitMap(vTheBitMap,size) VOID *vTheBitMap; int size;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -