📄 generate.c
字号:
{ top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_EQ); }
top->argList = (*theField->patternType->genGetPNValueFunction)(theEnv,theField);
top->argList->nextArg = conversion;
return(top);
}
/******************************************************************/
/* GetvarReplace: Replaces occurences of variables in expressions */
/* with function calls that will extract the variable's value */
/* from a partial match (i.e. from information stored in the */
/* join network or the activation of the rule). */
/******************************************************************/
globle struct expr *GetvarReplace(
void *theEnv,
struct lhsParseNode *nodeList)
{
struct expr *newList;
/*====================================*/
/* Return NULL for a NULL pointer */
/* (i.e. nothing has to be replaced). */
/*====================================*/
if (nodeList == NULL) return(NULL);
/*=====================================================*/
/* Create an expression data structure and recursively */
/* replace variables in its argument list and next */
/* argument links. */
/*=====================================================*/
newList = get_struct(theEnv,expr);
newList->type = nodeList->type;
newList->value = nodeList->value;
newList->nextArg = GetvarReplace(theEnv,nodeList->right);
newList->argList = GetvarReplace(theEnv,nodeList->bottom);
/*=========================================================*/
/* If the present node being examined is either a local or */
/* global variable, then replace it with a function call */
/* that will return the variable's value. */
/*=========================================================*/
if ((nodeList->type == SF_VARIABLE) || (nodeList->type == MF_VARIABLE))
{
(*nodeList->referringNode->patternType->replaceGetJNValueFunction)
(theEnv,newList,nodeList->referringNode);
}
#if DEFGLOBAL_CONSTRUCT
else if (newList->type == GBL_VARIABLE)
{ ReplaceGlobalVariable(theEnv,newList); }
#endif
/*====================================================*/
/* Return the expression with its variables replaced. */
/*====================================================*/
return(newList);
}
/**********************************************************************/
/* GetfieldReplace: Replaces occurences of variables in expressions */
/* with function calls that will extract the variable's value */
/* given a pointer to the data entity that contains the value (i.e. */
/* from information stored in the pattern network). */
/**********************************************************************/
static struct expr *GetfieldReplace(
void *theEnv,
struct lhsParseNode *nodeList)
{
struct expr *newList;
/*====================================*/
/* Return NULL for a NULL pointer */
/* (i.e. nothing has to be replaced). */
/*====================================*/
if (nodeList == NULL) return(NULL);
/*=====================================================*/
/* Create an expression data structure and recursively */
/* replace variables in its argument list and next */
/* argument links. */
/*=====================================================*/
newList = get_struct(theEnv,expr);
newList->type = nodeList->type;
newList->value = nodeList->value;
newList->nextArg = GetfieldReplace(theEnv,nodeList->right);
newList->argList = GetfieldReplace(theEnv,nodeList->bottom);
/*=========================================================*/
/* If the present node being examined is either a local or */
/* global variable, then replace it with a function call */
/* that will return the variable's value. */
/*=========================================================*/
if ((nodeList->type == SF_VARIABLE) || (nodeList->type == MF_VARIABLE))
{
(*nodeList->referringNode->patternType->replaceGetPNValueFunction)
(theEnv,newList,nodeList->referringNode);
}
#if DEFGLOBAL_CONSTRUCT
else if (newList->type == GBL_VARIABLE)
{ ReplaceGlobalVariable(theEnv,newList); }
#endif
/*====================================================*/
/* Return the expression with its variables replaced. */
/*====================================================*/
return(newList);
}
/**************************************************************/
/* GenJNVariableComparison: Generates a join network test for */
/* comparing two variables found in different patterns. */
/**************************************************************/
static struct expr *GenJNVariableComparison(
void *theEnv,
struct lhsParseNode *selfNode,
struct lhsParseNode *referringNode)
{
struct expr *top;
/*========================================================*/
/* If either pattern is missing a function for generating */
/* the appropriate test, then no test is generated. */
/*========================================================*/
if ((selfNode->patternType->genCompareJNValuesFunction == NULL) ||
(referringNode->patternType->genCompareJNValuesFunction == NULL))
{ return(NULL); }
/*=====================================================*/
/* If both patterns are of the same type, then use the */
/* special function for generating the join test. */
/*=====================================================*/
if (selfNode->patternType->genCompareJNValuesFunction ==
referringNode->patternType->genCompareJNValuesFunction)
{
return (*selfNode->patternType->genCompareJNValuesFunction)(theEnv,selfNode,
referringNode);
}
/*===========================================================*/
/* If the patterns are of different types, then generate a */
/* join test by using the eq/neq function with its arguments */
/* being function calls to retrieve the appropriate values */
/* from the patterns. */
/*===========================================================*/
if (selfNode->negated) top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_NEQ);
else top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_EQ);
top->argList = (*selfNode->patternType->genGetJNValueFunction)(theEnv,selfNode);
top->argList->nextArg = (*referringNode->patternType->genGetJNValueFunction)(theEnv,referringNode);
return(top);
}
/*************************************************************/
/* GenPNVariableComparison: Generates a pattern network test */
/* for comparing two variables found in the same pattern. */
/*************************************************************/
static struct expr *GenPNVariableComparison(
void *theEnv,
struct lhsParseNode *selfNode,
struct lhsParseNode *referringNode)
{
if (selfNode->patternType->genComparePNValuesFunction != NULL)
{
return (*selfNode->patternType->genComparePNValuesFunction)(theEnv,selfNode,referringNode);
}
return(NULL);
}
/************************************************************/
/* AllVariablesInPattern: Determines if all of the variable */
/* references in a field constraint can be referenced */
/* within thepattern in which the field is contained. */
/************************************************************/
static int AllVariablesInPattern(
struct lhsParseNode *orField,
int pattern)
{
struct lhsParseNode *andField;
/*=========================================*/
/* Loop through each of the | constraints. */
/*=========================================*/
for (;
orField != NULL;
orField = orField->bottom)
{
/*=========================================*/
/* Loop through each of the & constraints. */
/*=========================================*/
for (andField = orField;
andField != NULL;
andField = andField->right)
{
/*========================================================*/
/* If a variable is found, make sure the pattern in which */
/* the variable was previously bound is the same as the */
/* pattern being checked. */
/*========================================================*/
if ((andField->type == SF_VARIABLE) || (andField->type == MF_VARIABLE))
{ if (andField->referringNode->pattern != pattern) return(FALSE); }
/*========================================================*/
/* Check predicate and return value constraints to see */
/* that all variables can be referenced from the pattern. */
/*========================================================*/
else if ((andField->type == PREDICATE_CONSTRAINT) ||
(andField->type == RETURN_VALUE_CONSTRAINT))
{
if (AllVariablesInExpression(andField->expression,pattern) == FALSE)
{ return(FALSE); }
}
}
}
/*=====================================*/
/* All variables in the field can be */
/* referenced from within the pattern. */
/*=====================================*/
return(TRUE);
}
/**************************************************************************/
/* AllVariablesInExpression: Determines if all of the variable references */
/* in an expression can be referenced within the pattern in which the */
/* expression is contained. */
/**************************************************************************/
static int AllVariablesInExpression(
struct lhsParseNode *theExpression,
int pattern)
{
/*==========================================*/
/* Check all expressions in the right link. */
/*==========================================*/
for (;
theExpression != NULL;
theExpression = theExpression->right)
{
/*========================================================*/
/* If a variable is found, make sure the pattern in which */
/* the variable is bound is the same as the pattern being */
/* checked. */
/*========================================================*/
if ((theExpression->type == SF_VARIABLE) ||
(theExpression->type == MF_VARIABLE))
{ if (theExpression->referringNode->pattern != pattern) return(FALSE); }
/*=======================================================*/
/* Recursively check all expressions in the bottom link. */
/*=======================================================*/
if (AllVariablesInExpression(theExpression->bottom,pattern) == FALSE)
{ return(FALSE); }
}
/*========================================*/
/* All variables in the expression can be */
/* referenced from within the pattern. */
/*========================================*/
return(TRUE);
}
#endif /* (! RUN_TIME) && (! BLOAD_ONLY) && DEFRULE_CONSTRUCT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -