📄 symbol.c
字号:
/*********************************************************/
/* DecrementIntegerCount: Decrements the count value for */
/* an IntegerTable entry. Adds the integer to the */
/* EphemeralIntegerList if the count becomes zero. */
/*********************************************************/
globle void DecrementIntegerCount(
void *theEnv,
INTEGER_HN *theValue)
{
if (theValue->count <= 0)
{
SystemError(theEnv,"SYMBOL",6);
EnvExitRouter(theEnv,EXIT_FAILURE);
}
theValue->count--;
if (theValue->count != 0) return;
if (theValue->markedEphemeral == FALSE)
{
AddEphemeralHashNode(theEnv,(GENERIC_HN *) theValue,&SymbolData(theEnv)->EphemeralIntegerList,
sizeof(INTEGER_HN),0);
}
return;
}
/*****************************************************/
/* DecrementBitMapCount: Decrements the count value */
/* for a BitmapTable entry. Adds the bitmap to the */
/* EphemeralBitMapList if the count becomes zero. */
/*****************************************************/
globle void DecrementBitMapCount(
void *theEnv,
BITMAP_HN *theValue)
{
if (theValue->count < 0)
{
SystemError(theEnv,"SYMBOL",7);
EnvExitRouter(theEnv,EXIT_FAILURE);
}
if (theValue->count == 0)
{
SystemError(theEnv,"SYMBOL",8);
EnvExitRouter(theEnv,EXIT_FAILURE);
}
theValue->count--;
if (theValue->count != 0) return;
if (theValue->markedEphemeral == FALSE)
{
AddEphemeralHashNode(theEnv,(GENERIC_HN *) theValue,&SymbolData(theEnv)->EphemeralBitMapList,
sizeof(BITMAP_HN),sizeof(long));
}
return;
}
/*************************************************************/
/* RemoveHashNode: Removes a hash node from the SymbolTable, */
/* FloatTable, IntegerTable, or BitMapTable. */
/*************************************************************/
static void RemoveHashNode(
void *theEnv,
GENERIC_HN *theValue,
GENERIC_HN **theTable,
int size,
int type)
{
GENERIC_HN *previousNode, *currentNode;
/*=============================================*/
/* Find the entry in the specified hash table. */
/*=============================================*/
previousNode = NULL;
currentNode = theTable[theValue->bucket];
while (currentNode != theValue)
{
previousNode = currentNode;
currentNode = currentNode->next;
if (currentNode == NULL)
{
SystemError(theEnv,"SYMBOL",9);
EnvExitRouter(theEnv,EXIT_FAILURE);
}
}
/*===========================================*/
/* Remove the entry from the list of entries */
/* stored in the hash table bucket. */
/*===========================================*/
if (previousNode == NULL)
{ theTable[theValue->bucket] = theValue->next; }
else
{ previousNode->next = currentNode->next; }
/*=================================================*/
/* Symbol and bit map nodes have additional memory */
/* use to store the character or bitmap string. */
/*=================================================*/
if (type == SYMBOL)
{
rm(theEnv,((SYMBOL_HN *) theValue)->contents,
strlen(((SYMBOL_HN *) theValue)->contents) + 1);
}
else if (type == BITMAPARRAY)
{
rm(theEnv,((BITMAP_HN *) theValue)->contents,
((BITMAP_HN *) theValue)->size);
}
/*===========================*/
/* Return the table entry to */
/* the pool of free memory. */
/*===========================*/
rtn_sized_struct(theEnv,size,theValue);
}
/***********************************************************/
/* AddEphemeralHashNode: Adds a symbol, integer, float, or */
/* bit map table entry to the list of ephemeral atomic */
/* values. These entries have a zero count indicating */
/* that no structure is using the data value. */
/***********************************************************/
static void AddEphemeralHashNode(
void *theEnv,
GENERIC_HN *theHashNode,
struct ephemeron **theEphemeralList,
int hashNodeSize,
int averageContentsSize)
{
struct ephemeron *temp;
/*===========================================*/
/* If the count isn't zero then this routine */
/* should never have been called. */
/*===========================================*/
if (theHashNode->count != 0)
{
SystemError(theEnv,"SYMBOL",10);
EnvExitRouter(theEnv,EXIT_FAILURE);
}
/*=====================================*/
/* Mark the atomic value as ephemeral. */
/*=====================================*/
theHashNode->markedEphemeral = TRUE;
/*=============================*/
/* Add the atomic value to the */
/* list of ephemeral values. */
/*=============================*/
temp = get_struct(theEnv,ephemeron);
temp->associatedValue = theHashNode;
temp->next = *theEphemeralList;
*theEphemeralList = temp;
/*=========================================================*/
/* Increment the ephemeral count and size variables. These */
/* variables are used by the garbage collection routines */
/* to determine when garbage collection should occur. */
/*=========================================================*/
UtilityData(theEnv)->EphemeralItemCount++;
UtilityData(theEnv)->EphemeralItemSize += sizeof(struct ephemeron) + hashNodeSize +
averageContentsSize;
}
/***************************************************/
/* RemoveEphemeralAtoms: Causes the removal of all */
/* ephemeral symbols, integers, floats, and bit */
/* maps that still have a count value of zero, */
/* from their respective storage tables. */
/***************************************************/
globle void RemoveEphemeralAtoms(
void *theEnv)
{
RemoveEphemeralHashNodes(theEnv,&SymbolData(theEnv)->EphemeralSymbolList,(GENERIC_HN **) SymbolData(theEnv)->SymbolTable,
sizeof(SYMBOL_HN),SYMBOL,AVERAGE_STRING_SIZE);
RemoveEphemeralHashNodes(theEnv,&SymbolData(theEnv)->EphemeralFloatList,(GENERIC_HN **) SymbolData(theEnv)->FloatTable,
sizeof(FLOAT_HN),FLOAT,0);
RemoveEphemeralHashNodes(theEnv,&SymbolData(theEnv)->EphemeralIntegerList,(GENERIC_HN **) SymbolData(theEnv)->IntegerTable,
sizeof(INTEGER_HN),INTEGER,0);
RemoveEphemeralHashNodes(theEnv,&SymbolData(theEnv)->EphemeralBitMapList,(GENERIC_HN **) SymbolData(theEnv)->BitMapTable,
sizeof(BITMAP_HN),BITMAPARRAY,AVERAGE_BITMAP_SIZE);
}
/****************************************************************/
/* RemoveEphemeralHashNodes: Removes symbols from the ephemeral */
/* symbol list that have a count of zero and were placed on */
/* the list at a higher level than the current evaluation */
/* depth. Since symbols are ordered in the list in descending */
/* order, the removal process can end when a depth is reached */
/* less than the current evaluation depth. Because ephemeral */
/* symbols can be "pulled" up through an evaluation depth, */
/* this routine needs to check through both the previous and */
/* current evaluation depth. */
/****************************************************************/
static void RemoveEphemeralHashNodes(
void *theEnv,
struct ephemeron **theEphemeralList,
GENERIC_HN **theTable,
int hashNodeSize,
int hashNodeType,
int averageContentsSize)
{
struct ephemeron *edPtr, *lastPtr = NULL, *nextPtr;
edPtr = *theEphemeralList;
while (edPtr != NULL)
{
/*======================================================*/
/* Check through previous and current evaluation depth */
/* because these symbols can be interspersed, otherwise */
/* symbols are stored in descending evaluation depth. */
/*======================================================*/
nextPtr = edPtr->next;
/*==================================================*/
/* Remove any symbols that have a count of zero and */
/* were added to the ephemeral list at a higher */
/* evaluation depth. */
/*==================================================*/
if ((edPtr->associatedValue->count == 0) &&
(edPtr->associatedValue->depth > EvaluationData(theEnv)->CurrentEvaluationDepth))
{
RemoveHashNode(theEnv,edPtr->associatedValue,theTable,hashNodeSize,hashNodeType);
rtn_struct(theEnv,ephemeron,edPtr);
if (lastPtr == NULL) *theEphemeralList = nextPtr;
else lastPtr->next = nextPtr;
UtilityData(theEnv)->EphemeralItemCount--;
UtilityData(theEnv)->EphemeralItemSize -= sizeof(struct ephemeron) + hashNodeSize +
averageContentsSize;
}
/*=======================================*/
/* Remove ephemeral status of any symbol */
/* with a count greater than zero. */
/*=======================================*/
else if (edPtr->associatedValue->count > 0)
{
edPtr->associatedValue->markedEphemeral = FALSE;
rtn_struct(theEnv,ephemeron,edPtr);
if (lastPtr == NULL) *theEphemeralList = nextPtr;
else lastPtr->next = nextPtr;
UtilityData(theEnv)->EphemeralItemCount--;
UtilityData(theEnv)->EphemeralItemSize -= sizeof(struct ephemeron) + hashNodeSize +
averageContentsSize;
}
/*==================================================*/
/* Otherwise keep the symbol in the ephemeral list. */
/*==================================================*/
else
{ lastPtr = edPtr; }
edPtr = nextPtr;
}
}
/*********************************************************/
/* GetSymbolTable: Returns a pointer to the SymbolTable. */
/*********************************************************/
globle SYMBOL_HN **GetSymbolTable(
void *theEnv)
{
return(SymbolData(theEnv)->SymbolTable);
}
/******************************************************/
/* SetSymbolTable: Sets the value of the SymbolTable. */
/******************************************************/
globle void SetSymbolTable(
void *theEnv,
SYMBOL_HN **value)
{
SymbolData(theEnv)->SymbolTable = value;
}
/*******************************************************/
/* GetFloatTable: Returns a pointer to the FloatTable. */
/*******************************************************/
globle FLOAT_HN **GetFloatTable(
void *theEnv)
{
return(SymbolData(theEnv)->FloatTable);
}
/****************************************************/
/* SetFloatTable: Sets the value of the FloatTable. */
/****************************************************/
globle void SetFloatTable(
void *theEnv,
FLOAT_HN **value)
{
SymbolData(theEnv)->FloatTable = value;
}
/***********************************************************/
/* GetIntegerTable: Returns a pointer to the IntegerTable. */
/***********************************************************/
globle INTEGER_HN **GetIntegerTable(
void *theEnv)
{
return(SymbolData(theEnv)->IntegerTable);
}
/********************************************************/
/* SetIntegerTable: Sets the value of the IntegerTable. */
/********************************************************/
globle void SetIntegerTable(
void *theEnv,
INTEGER_HN **value)
{
SymbolData(theEnv)->IntegerTable = value;
}
/*********************************************************/
/* GetBitMapTable: Returns a pointer to the BitMapTable. */
/*********************************************************/
globle BITMAP_HN **GetBitMapTable(
void *theEnv)
{
return(SymbolData(theEnv)->BitMapTable);
}
/******************************************************/
/* SetBitMapTable: Sets the value of the BitMapTable. */
/******************************************************/
globle void SetBitMapTable(
void *theEnv,
BITMAP_HN **value)
{
SymbolData(theEnv)->BitMapTable = value;
}
/******************************************************/
/* RefreshSpecialSymbols: Resets the values of the */
/* TrueSymbol, FalseSymbol, Zero, PositiveInfinity, */
/* and NegativeInfinity symbols. */
/******************************************************/
globle void RefreshSpecialSymbols(
void *theEnv)
{
SymbolData(theEnv)->TrueSymbolHN = (void *) FindSymbolHN(theEnv,TRUE_STRING);
SymbolData(theEnv)->FalseSymbolHN = (void *) FindSymbolHN(theEnv,FALSE_STRING);
SymbolData(theEnv)->PositiveInfinity = (void *) FindSymbolHN(theEnv,POSITIVE_INFINITY_STRING);
SymbolData(theEnv)->NegativeInfinity = (void *) FindSymbolHN(theEnv,NEGATIVE_INFINITY_STRING);
SymbolData(theEnv)->Zero = (void *) FindLongHN(theEnv,0L);
}
/***********************************************************/
/* FindSymbolMatches: Finds all symbols in the SymbolTable */
/* which begin with a specified symbol. This function is */
/* used to implement the command completion feature */
/* found in some of the machine specific interfaces. */
/***********************************************************/
globle struct symbolMatch *FindSymbolMatches(
void *theEnv,
char *searchString,
unsigned *numberOfMatches,
unsigned *commonPrefixLength)
{
struct symbolMatch *reply = NULL, *temp;
struct symbolHashNode *hashPtr = NULL;
unsigned searchLength;
searchLength = strlen(searchString);
*numberOfMatches = 0;
while ((hashPtr = GetNextSymbolMatch(theEnv,searchString,searchLength,hashPtr,
FALSE,commonPrefixLength)) != NULL)
{
*numberOfMatches = *numberOfMatches + 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -