📄 generate.c
字号:
/* all the variables it refers to are contained in the previous */
/* pattern CE). If one of the or'ed constraints in a field refers to */
/* a binding occurrence of a variable in another pattern, then the */
/* other constraints in the field must be tested in the join network */
/* (this is how some constant constraint tests must occasionally be */
/* performed in the join network). */
/************************************************************************/
static void ExtractFieldTest(
void *theEnv,
struct lhsParseNode *theField,
int testInPatternNetwork,
struct expr **patternNetTest,
struct expr **joinNetTest)
{
*patternNetTest = NULL;
*joinNetTest = NULL;
/*==========================================================*/
/* Generate a network expression for a constant constraint. */
/*==========================================================*/
if ((theField->type == STRING) || (theField->type == SYMBOL) ||
#if OBJECT_SYSTEM
(theField->type == INSTANCE_NAME) ||
#endif
(theField->type == FLOAT) || (theField->type == INTEGER))
{
if (testInPatternNetwork == TRUE)
{ *patternNetTest = GenPNConstant(theEnv,theField); }
else
{ *joinNetTest = GenJNConstant(theEnv,theField); }
}
/*===========================================================*/
/* Generate a network expression for a predicate constraint. */
/*===========================================================*/
else if (theField->type == PREDICATE_CONSTRAINT)
{
if ((testInPatternNetwork == TRUE) &&
(AllVariablesInExpression(theField->expression,theField->pattern) == TRUE))
{ *patternNetTest = GenPNColon(theEnv,theField); }
else
{ *joinNetTest = GenJNColon(theEnv,theField); }
}
/*==============================================================*/
/* Generate a network expression for a return value constraint. */
/*==============================================================*/
else if (theField->type == RETURN_VALUE_CONSTRAINT)
{
if ((testInPatternNetwork == TRUE) &&
(AllVariablesInExpression(theField->expression,theField->pattern) == TRUE))
{ *patternNetTest = GenPNEq(theEnv,theField); }
else
{ *joinNetTest = GenJNEq(theEnv,theField); }
}
/*=====================================================================*/
/* Generate a network expression for a variable comparison constraint. */
/*=====================================================================*/
else if ((theField->type == SF_VARIABLE) || (theField->type == MF_VARIABLE))
{
if ((testInPatternNetwork == TRUE) &&
((theField->referringNode != NULL) ?
(theField->referringNode->pattern == theField->pattern) :
FALSE))
{ *patternNetTest = GenPNVariableComparison(theEnv,theField,theField->referringNode); }
else
{ *joinNetTest = GenJNVariableComparison(theEnv,theField,theField->referringNode); }
}
}
/*********************************************************/
/* GenPNConstant: Generates an expression for use in the */
/* pattern network of a data entity (such as a fact or */
/* instance). The expression generated is for comparing */
/* a constant value against a specified slot/field in */
/* the data entity for equality or inequality. */
/*********************************************************/
static struct expr *GenPNConstant(
void *theEnv,
struct lhsParseNode *theField)
{
struct expr *top;
/*===============================================*/
/* If the pattern parser is capable of creating */
/* a specialized test, then call the function to */
/* generate the pattern network test and return */
/* the expression generated. */
/*===============================================*/
if (theField->patternType->genPNConstantFunction != NULL)
{ return (*theField->patternType->genPNConstantFunction)(theEnv,theField); }
/*===================================================*/
/* Otherwise, generate a test which uses the eq/neq */
/* function to compare the pattern field/slot to the */
/* constant and then return the expression. */
/*===================================================*/
if (theField->negated)
{ top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_NEQ); }
else
{ top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_EQ); }
top->argList = (*theField->patternType->genGetPNValueFunction)(theEnv,theField);
top->argList->nextArg = GenConstant(theEnv,theField->type,theField->value);
return(top);
}
/************************************************************/
/* GenJNConstant: Generates an expression for use in the */
/* join network. The expression generated is for comparing */
/* a constant value against a specified slot/field in the */
/* data entity for equality or inequality. */
/************************************************************/
static struct expr *GenJNConstant(
void *theEnv,
struct lhsParseNode *theField)
{
struct expr *top;
/*===============================================*/
/* If the pattern parser is capable of creating */
/* a specialized test, then call the function to */
/* generate the join network test and return the */
/* expression generated. */
/*===============================================*/
if (theField->patternType->genJNConstantFunction != NULL)
{ return (*theField->patternType->genJNConstantFunction)(theEnv,theField); }
/*===================================================*/
/* Otherwise, generate a test which uses the eq/neq */
/* function to compare the pattern field/slot to the */
/* constant and then return the expression. */
/*===================================================*/
if (theField->negated)
{ top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_NEQ); }
else
{ top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_EQ); }
top->argList = (*theField->patternType->genGetJNValueFunction)(theEnv,theField);
top->argList->nextArg = GenConstant(theEnv,theField->type,theField->value);
return(top);
}
/******************************************************/
/* GenJNColon: Generates an expression for use in the */
/* join network. The expression generated is for a */
/* predicate field constraint (the : constraint). */
/******************************************************/
static struct expr *GenJNColon(
void *theEnv,
struct lhsParseNode *theField)
{
struct expr *top, *conversion;
/*==================================================*/
/* Replace variables with function calls to extract */
/* the appropriate value from the data entity. */
/*==================================================*/
conversion = GetvarReplace(theEnv,theField->expression);
/*================================================*/
/* If the predicate constraint is negated by a ~, */
/* then wrap a "not" function call around the */
/* expression before returning it. Otherwise, */
/* just return the expression. */
/*================================================*/
if (theField->negated)
{
top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_NOT);
top->argList = conversion;
}
else
{ top = conversion; }
return(top);
}
/******************************************************/
/* GenPNColon: Generates an expression for use in the */
/* pattern network. The expression generated is for */
/* a predicate field constraint (the : constraint). */
/******************************************************/
static struct expr *GenPNColon(
void *theEnv,
struct lhsParseNode *theField)
{
struct expr *top, *conversion;
/*==================================================*/
/* Replace variables with function calls to extract */
/* the appropriate value from the data entity. */
/*==================================================*/
conversion = GetfieldReplace(theEnv,theField->expression);
/*================================================*/
/* If the predicate constraint is negated by a ~, */
/* then wrap a "not" function call around the */
/* expression before returning it. Otherwise, */
/* just return the expression. */
/*================================================*/
if (theField->negated)
{
top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_NOT);
top->argList = conversion;
}
else
{ top = conversion; }
return(top);
}
/******************************************************/
/* GenJNEq: Generates an expression for use in the */
/* join network. The expression generated is for a */
/* return value field constraint (the = constraint). */
/******************************************************/
static struct expr *GenJNEq(
void *theEnv,
struct lhsParseNode *theField)
{
struct expr *top, *conversion;
/*==================================================*/
/* Replace variables with function calls to extract */
/* the appropriate value from the data entity. */
/*==================================================*/
conversion = GetvarReplace(theEnv,theField->expression);
/*============================================================*/
/* If the return value constraint is negated by a ~, then use */
/* the neq function to compare the value of the field to the */
/* value returned by the function call. Otherwise, use eq to */
/* compare the two values. */
/*============================================================*/
if (theField->negated)
{ top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_NEQ); }
else
{ top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_EQ); }
top->argList = (*theField->patternType->genGetJNValueFunction)(theEnv,theField);
top->argList->nextArg = conversion;
return(top);
}
/*******************************************************/
/* GenPNEq: Generates an expression for use in the */
/* pattern network. The expression generated is for a */
/* return value field constraint (the = constraint). */
/*******************************************************/
static struct expr *GenPNEq(
void *theEnv,
struct lhsParseNode *theField)
{
struct expr *top, *conversion;
/*==================================================*/
/* Replace variables with function calls to extract */
/* the appropriate value from the data entity. */
/*==================================================*/
conversion = GetfieldReplace(theEnv,theField->expression);
/*============================================================*/
/* If the return value constraint is negated by a ~, then use */
/* the neq function to compare the value of the field to the */
/* value returned by the function call. Otherwise, use eq to */
/* compare the two values. */
/*============================================================*/
if (theField->negated)
{ top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_NEQ); }
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -