📄 symbol.c
字号:
if (strcmp(str,peek->contents) == 0) { return(peek); } } return(NULL); }/*******************************************************************//* EnvAddDouble: 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 *EnvAddDouble( void *theEnv, double number) { unsigned tally; FLOAT_HN *past = NULL, *peek; /*====================================*/ /* Get the hash value for the double. */ /*====================================*/ tally = HashFloat(number,FLOAT_HASH_SIZE); peek = SymbolData(theEnv)->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(theEnv,floatHashNode); if (past == NULL) SymbolData(theEnv)->FloatTable[tally] = peek; else past->next = peek; peek->contents = number; peek->next = NULL; peek->bucket = tally; peek->count = 0; peek->permanent = FALSE; /*===============================================*/ /* Add the float to the list of ephemeral items. */ /*===============================================*/ AddEphemeralHashNode(theEnv,(GENERIC_HN *) peek,&SymbolData(theEnv)->EphemeralFloatList, sizeof(FLOAT_HN),0); peek->depth = EvaluationData(theEnv)->CurrentEvaluationDepth; /*==================================*/ /* Return the address of the float. */ /*==================================*/ return((void *) peek); }/***************************************************************//* EnvAddLong: 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 *EnvAddLong( void *theEnv, long long number) { unsigned tally; INTEGER_HN *past = NULL, *peek; /*==================================*/ /* Get the hash value for the long. */ /*==================================*/ tally = HashInteger(number,INTEGER_HASH_SIZE); peek = SymbolData(theEnv)->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(theEnv,integerHashNode); if (past == NULL) SymbolData(theEnv)->IntegerTable[tally] = peek; else past->next = peek; peek->contents = number; peek->next = NULL; peek->bucket = tally; peek->count = 0; peek->permanent = FALSE; /*=================================================*/ /* Add the integer to the list of ephemeral items. */ /*=================================================*/ AddEphemeralHashNode(theEnv,(GENERIC_HN *) peek,&SymbolData(theEnv)->EphemeralIntegerList, sizeof(INTEGER_HN),0); peek->depth = EvaluationData(theEnv)->CurrentEvaluationDepth; /*====================================*/ /* Return the address of the integer. */ /*====================================*/ return((void *) peek); }/*****************************************************************//* FindLongHN: Searches for the integer in the integer table and *//* returns a pointer to it if found, otherwise returns NULL. *//*****************************************************************/globle INTEGER_HN *FindLongHN( void *theEnv, long long theLong) { unsigned tally; INTEGER_HN *peek; tally = HashInteger(theLong,INTEGER_HASH_SIZE); for (peek = SymbolData(theEnv)->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( void *theEnv, void *vTheBitMap, unsigned size) { char *theBitMap = (char *) vTheBitMap; unsigned tally; unsigned i; BITMAP_HN *past = NULL, *peek; /*====================================*/ /* Get the hash value for the bitmap. */ /*====================================*/ if (theBitMap == NULL) { SystemError(theEnv,"SYMBOL",2); EnvExitRouter(theEnv,EXIT_FAILURE); } tally = HashBitMap(theBitMap,BITMAP_HASH_SIZE,size); peek = SymbolData(theEnv)->BitMapTable[tally]; /*==================================================*/ /* Search for the bitmap in the list of entries for */ /* this hash table location. If the bitmap is */ /* found, then return the address of the bitmap. */ /*==================================================*/ while (peek != NULL) { if (peek->size == size) { for (i = 0; i < size ; i++) { if (peek->contents[i] != theBitMap[i]) break; } if (i == size) return((void *) peek); } past = peek; peek = peek->next; } /*==================================================*/ /* Add the bitmap at the end of the list of entries */ /* for this hash table location. Return the */ /*==================================================*/ peek = get_struct(theEnv,bitMapHashNode); if (past == NULL) SymbolData(theEnv)->BitMapTable[tally] = peek; else past->next = peek; peek->contents = (char *) gm2(theEnv,size); peek->next = NULL; peek->bucket = tally; peek->count = 0; peek->permanent = FALSE; peek->size = (unsigned short) size; for (i = 0; i < size ; i++) peek->contents[i] = theBitMap[i]; /*================================================*/ /* Add the bitmap to the list of ephemeral items. */ /*================================================*/ AddEphemeralHashNode(theEnv,(GENERIC_HN *) peek,&SymbolData(theEnv)->EphemeralBitMapList, sizeof(BITMAP_HN),sizeof(long)); peek->depth = EvaluationData(theEnv)->CurrentEvaluationDepth; /*===================================*/ /* Return the address of the bitmap. */ /*===================================*/ return((void *) peek); }/***************************************************//* HashSymbol: Computes a hash value for a symbol. *//***************************************************/globle unsigned long HashSymbol( char *word, long range) { register int i; unsigned long tally = 0; for (i = 0; word[i]; i++) { tally = tally * 127 + word[i]; } if (range == -1) { return tally; } return(tally % range); }/*************************************************//* HashFloat: Computes a hash value for a float. *//*************************************************/globle unsigned HashFloat( double number, unsigned range) { unsigned long tally = 0; char *word; unsigned i; word = (char *) &number; for (i = 0; i < sizeof(double); i++) { tally = tally * 127 + word[i]; } return(tally % range); }/******************************************************//* HashInteger: Computes a hash value for an integer. *//******************************************************/globle unsigned HashInteger( long long number, unsigned range) { unsigned tally;#if IBM_MSC if (number < 0) { number = - number; } tally = (((unsigned) number) % range);#else tally = (((unsigned) llabs(number)) % range);#endif return(tally); }/***************************************************//* HashBitMap: Computes a hash value for a bitmap. *//***************************************************/globle unsigned HashBitMap( char *word, unsigned range, unsigned length) { register unsigned k,j,i; unsigned tally; unsigned longLength; unsigned long count = 0L,tmpLong; char *tmpPtr; tmpPtr = (char *) &tmpLong; /*================================================================ */ /* Add up the first part of the word as unsigned long int values. */ /*================================================================ */ longLength = length / sizeof(unsigned long); for (i = 0 , j = 0 ; i < longLength; i++) { for (k = 0 ; k < sizeof(unsigned long) ; k++ , j++) tmpPtr[k] = word[j]; count += tmpLong; } /*============================================*/ /* Add the remaining characters to the count. */ /*============================================*/ for (; j < length; j++) count += (unsigned long) word[j]; /*========================*/ /* Return the hash value. */ /*========================*/ tally = (count % range); return(tally); }/*****************************************************//* DecrementSymbolCount: Decrements the count value *//* for a SymbolTable entry. Adds the symbol to the *//* EphemeralSymbolList if the count becomes zero. *//*****************************************************/globle void DecrementSymbolCount( void *theEnv, SYMBOL_HN *theValue) { if (theValue->count < 0) { SystemError(theEnv,"SYMBOL",3); EnvExitRouter(theEnv,EXIT_FAILURE); } if (theValue->count == 0) { SystemError(theEnv,"SYMBOL",4); EnvExitRouter(theEnv,EXIT_FAILURE); } theValue->count--; if (theValue->count != 0) return; if (theValue->markedEphemeral == FALSE) { AddEphemeralHashNode(theEnv,(GENERIC_HN *) theValue,&SymbolData(theEnv)->EphemeralSymbolList, sizeof(SYMBOL_HN),AVERAGE_STRING_SIZE); } return; }/***************************************************//* DecrementFloatCount: Decrements the count value *//* for a FloatTable entry. Adds the float to the *//* EphemeralFloatList if the count becomes zero. *//***************************************************/globle void DecrementFloatCount( void *theEnv, FLOAT_HN *theValue) { if (theValue->count <= 0) { SystemError(theEnv,"SYMBOL",5); EnvExitRouter(theEnv,EXIT_FAILURE); } theValue->count--; if (theValue->count != 0) return; if (theValue->markedEphemeral == FALSE) { AddEphemeralHashNode(theEnv,(GENERIC_HN *) theValue,&SymbolData(theEnv)->EphemeralFloatList, sizeof(FLOAT_HN),0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -