📄 generate.c
字号:
{ tempExpression = (*theField->patternType->genGetJNValueFunction)(theEnv,theField,LHS); thePattern->externalRightHash = AppendExpressions(tempExpression,thePattern->externalRightHash); } if (theField->referringNode->patternType->genGetJNValueFunction) { tempExpression = (*theField->referringNode->patternType->genGetJNValueFunction)(theEnv,theField->referringNode,LHS); thePattern->externalLeftHash = AppendExpressions(tempExpression,thePattern->externalLeftHash); } } else { headOfJNExpression = CombineExpressions(theEnv,tempExpression,headOfJNExpression); /*==========================*/ /* Generate the hash index. */ /*==========================*/ if (theField->patternType->genGetPNValueFunction != NULL) { tempExpression = (*theField->patternType->genGetPNValueFunction)(theEnv,theField); thePattern->rightHash = AppendExpressions(tempExpression,thePattern->rightHash); } if (theField->referringNode->patternType->genGetJNValueFunction) { tempExpression = (*theField->referringNode->patternType->genGetJNValueFunction)(theEnv,theField->referringNode,LHS); thePattern->leftHash = AppendExpressions(tempExpression,thePattern->leftHash); } } } } /*======================================================*/ /* Attach the pattern network expressions to the field. */ /*======================================================*/ theField->networkTest = headOfPNExpression; /*=====================================================*/ /* Attach the join network expressions to the pattern. */ /*=====================================================*/ thePattern->networkTest = CombineExpressions(theEnv,thePattern->networkTest,headOfJNExpression); /*==========================================================*/ /* Attach the nand join network expressions to the pattern. */ /*==========================================================*/ thePattern->externalNetworkTest = CombineExpressions(theEnv,thePattern->externalNetworkTest,headOfNandExpression); /* TBD */ }/****************************************************************************//* ExtractAnds: Loops through a single set of subfields bound together by *//* an & connective constraint in a field and generates expressions needed *//* for testing conditions in the pattern and join network. *//****************************************************************************/static void ExtractAnds( void *theEnv, struct lhsParseNode *andField, int testInPatternNetwork, struct expr **patternNetTest, struct expr **joinNetTest, struct expr **nandTest, struct expr **constantSelector, struct expr **constantValue, int nandField) { struct expr *newPNTest, *newJNTest, *newNandTest, *newConstantSelector, *newConstantValue; /*=================================================*/ /* Before starting, the subfield has no pattern or */ /* join network expressions associated with it. */ /*=================================================*/ *patternNetTest = NULL; *joinNetTest = NULL; *nandTest = NULL; *constantSelector = NULL; *constantValue = NULL; /*=========================================*/ /* Loop through each of the subfields tied */ /* together by the & constraint. */ /*=========================================*/ for (; andField != NULL; andField = andField->right) { /*======================================*/ /* Extract the pattern and join network */ /* expressions from the subfield. */ /*======================================*/ ExtractFieldTest(theEnv,andField,testInPatternNetwork,&newPNTest,&newJNTest,&newNandTest,&newConstantSelector,&newConstantValue,nandField); /*=================================================*/ /* Add the new expressions to the list of pattern */ /* and join network expressions being constructed. */ /*=================================================*/ *patternNetTest = CombineExpressions(theEnv,*patternNetTest,newPNTest); *joinNetTest = CombineExpressions(theEnv,*joinNetTest,newJNTest); *nandTest = CombineExpressions(theEnv,*nandTest,newNandTest); *constantSelector = CombineExpressions(theEnv,*constantSelector,newConstantSelector); *constantValue = CombineExpressions(theEnv,*constantValue,newConstantValue); } }/************************************************************************//* ExtractFieldTest: Generates the pattern or join network expression *//* associated with the basic field constraints: constants, predicate, *//* return value, and variable constraints. Based on the context in *//* which a constraint is used, some constraints may be tested in the *//* pattern network while other constraints must be tested in the join *//* network. Constraints which refer to variables in other patterns *//* must be tested in the join network. The predicate constraint *//* associated with a test CE is tested in the join network (even if *//* 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, struct expr **nandTest, struct expr **constantSelector, struct expr **constantValue, int nandField) { struct expr *rv; *patternNetTest = NULL; *joinNetTest = NULL; *nandTest = NULL; *constantSelector = NULL; *constantValue = 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); if (! theField->negated) { *constantSelector = (*theField->patternType->genGetPNValueFunction)(theEnv,theField); *constantValue = GenConstant(theEnv,theField->type,theField->value); } } else { rv = GenJNConstant(theEnv,theField,nandField); if (nandField) { *nandTest = rv; } else { *joinNetTest = rv; } } } /*===========================================================*/ /* 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 { rv = GenJNColon(theEnv,theField,nandField); if (nandField) { *nandTest = rv; } else { *joinNetTest = rv; } } } /*==============================================================*/ /* 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 { rv = GenJNEq(theEnv,theField,nandField); if (nandField) { *nandTest = rv; } else { *joinNetTest = rv; } } } /*=====================================================================*/ /* 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 { if (nandField) { *nandTest = GenJNVariableComparison(theEnv,theField,theField->referringNode,nandField); } else { *joinNetTest = GenJNVariableComparison(theEnv,theField,theField->referringNode,nandField); } } } }/*********************************************************//* 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, int isNand) { 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -