📄 expressn.c
字号:
destination[i].value = original->value;
if (original->argList == NULL)
{ destination[i].argList = NULL; }
else
{
destination[i].argList =
(struct expr *) &destination[(long) count];
count = ListToPacked(original->argList,destination,count);
}
if (original->nextArg == NULL)
{ destination[i].nextArg = NULL; }
else
{
destination[i].nextArg =
(struct expr *) &destination[(long) count];
}
original = original->nextArg;
}
return(count);
}
/***************************************************************/
/* ReturnPackedExpression: Returns a packed expression created */
/* using PackExpression to the memory manager. */
/***************************************************************/
globle void ReturnPackedExpression(
void *theEnv,
struct expr *packPtr)
{
if (packPtr != NULL)
{
rm3(theEnv,(void *) packPtr,(long) sizeof (struct expr) *
ExpressionSize(packPtr));
}
}
#endif /* (! RUN_TIME) */
/***********************************************/
/* ReturnExpression: Returns a multiply linked */
/* list of expr data structures. */
/***********************************************/
globle void ReturnExpression(
void *theEnv,
struct expr *waste)
{
register struct expr *tmp;
while (waste != NULL)
{
if (waste->argList != NULL) ReturnExpression(theEnv,waste->argList);
tmp = waste;
waste = waste->nextArg;
rtn_struct(theEnv,expr,tmp);
}
}
#if (! RUN_TIME)
/***************************************************
NAME : FindHashedExpression
DESCRIPTION : Determines if a given expression
is in the expression hash table
INPUTS : 1) The expression
2) A buffer to hold the hash
value
3) A buffer to hold the previous
node in the hash chain
RETURNS : The expression hash table entry
(NULL if not found)
SIDE EFFECTS : None
NOTES : None
***************************************************/
static EXPRESSION_HN *FindHashedExpression(
void *theEnv,
EXPRESSION *theExp,
unsigned *hashval,
EXPRESSION_HN **prv)
{
EXPRESSION_HN *exphash;
if (theExp == NULL)
return(NULL);
*hashval = HashExpression(theExp);
*prv = NULL;
exphash = ExpressionData(theEnv)->ExpressionHashTable[*hashval];
while (exphash != NULL)
{
if (IdenticalExpression(exphash->exp,theExp))
return(exphash);
*prv = exphash;
exphash = exphash->next;
}
return(NULL);
}
/***************************************************
NAME : HashExpression
DESCRIPTION : Assigns a deterministic number to
an expression
INPUTS : The expression
RETURNS : The "value" of the expression
SIDE EFFECTS : None
NOTES : None
***************************************************/
static unsigned HashExpression(
EXPRESSION *theExp)
{
unsigned long tally = PRIME_THREE;
if (theExp->argList != NULL)
tally += HashExpression(theExp->argList) * PRIME_ONE;
while (theExp != NULL)
{
tally += (unsigned long) (theExp->type * PRIME_TWO);
tally += (unsigned long) theExp->value;
theExp = theExp->nextArg;
}
return((unsigned) (tally % EXPRESSION_HASH_SIZE));
}
/***************************************************
NAME : RemoveHashedExpression
DESCRIPTION : Removes a hashed expression from
the hash table
INPUTS : The expression
RETURNS : Nothing useful
SIDE EFFECTS : Hash node removed (or use count
decremented). If the hash node
is removed, the expression is
deinstalled and deleted
NOTES : If the expression is in use by
others, then the use count is
merely decremented
***************************************************/
globle void RemoveHashedExpression(
void *theEnv,
EXPRESSION *theExp)
{
EXPRESSION_HN *exphash,*prv;
unsigned hashval;
exphash = FindHashedExpression(theEnv,theExp,&hashval,&prv);
if (exphash == NULL)
return;
if (--exphash->count != 0)
return;
if (prv == NULL)
ExpressionData(theEnv)->ExpressionHashTable[hashval] = exphash->next;
else
prv->next = exphash->next;
ExpressionDeinstall(theEnv,exphash->exp);
ReturnPackedExpression(theEnv,exphash->exp);
rtn_struct(theEnv,exprHashNode,exphash);
}
#endif /* (! RUN_TIME) */
#if (! BLOAD_ONLY) && (! RUN_TIME)
/*****************************************************
NAME : AddHashedExpression
DESCRIPTION : Adds a new expression to the
expression hash table (or increments
the use count if it is already there)
INPUTS : The (new) expression
RETURNS : A pointer to the (new) hash node
SIDE EFFECTS : Adds the new hash node or increments
the count of an existing one
NOTES : It is the caller's responsibility to
delete the passed expression. This
routine copies, packs and installs
the given expression
*****************************************************/
globle EXPRESSION *AddHashedExpression(
void *theEnv,
EXPRESSION *theExp)
{
EXPRESSION_HN *prv,*exphash;
unsigned hashval;
if (theExp == NULL) return(NULL);
exphash = FindHashedExpression(theEnv,theExp,&hashval,&prv);
if (exphash != NULL)
{
exphash->count++;
return(exphash->exp);
}
exphash = get_struct(theEnv,exprHashNode);
exphash->hashval = hashval;
exphash->count = 1;
exphash->exp = PackExpression(theEnv,theExp);
ExpressionInstall(theEnv,exphash->exp);
exphash->next = ExpressionData(theEnv)->ExpressionHashTable[exphash->hashval];
ExpressionData(theEnv)->ExpressionHashTable[exphash->hashval] = exphash;
exphash->bsaveID = 0L;
return(exphash->exp);
}
#endif /* (! BLOAD_ONLY) && (! RUN_TIME) */
#if (BLOAD_AND_BSAVE || BLOAD_ONLY || BLOAD || CONSTRUCT_COMPILER) && (! RUN_TIME)
/***************************************************
NAME : HashedExpressionIndex
DESCRIPTION : Finds the expression bload array
index for a hashed expression
INPUTS : The expression
RETURNS : The bload index
SIDE EFFECTS : None
NOTES : None
***************************************************/
globle long HashedExpressionIndex(
void *theEnv,
EXPRESSION *theExp)
{
EXPRESSION_HN *exphash,*prv;
unsigned hashval;
if (theExp == NULL)
return(-1L);
exphash = FindHashedExpression(theEnv,theExp,&hashval,&prv);
return((exphash != NULL) ? exphash->bsaveID : -1L);
}
#endif /* (BLOAD_AND_BSAVE || BLOAD_ONLY || BLOAD || CONSTRUCT_COMPILER) && (! RUN_TIME) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -