📄 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 int 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 int 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,
unsigned long range)
{
register int i;
unsigned long tally = 0;
for (i = 0; word[i]; i++)
{ tally = tally * 127 + word[i]; }
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 int number,
unsigned range)
{
unsigned tally;
tally = (labs(number) % range);
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);
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -