globle void ReplaceGetPNObjectValue( void *theEnv, EXPRESSION *theItem, struct lhsParseNode *theNode) { GenObjectGetVar(theEnv,FALSE,theItem,theNode,-1); }
/********************************************** Build functions used by AddPatternParser() to provide object access to the join nertwork **********************************************/ globle void ReplaceGetJNObjectValue( void *theEnv, EXPRESSION *theItem, struct lhsParseNode *theNode, int side) { GenObjectGetVar(theEnv,TRUE,theItem,theNode,side); }
/********************************************** Build functions used by AddPatternParser() to provide object access to the pattern network **********************************************/ globle EXPRESSION *GenObjectPNConstantCompare( void *theEnv, struct lhsParseNode *theNode) { struct ObjectCmpPNConstant hack; EXPRESSION *theExp; unsigned short tmpType; /* =============================================================== If the value of a single field slot (or relation name) is being compared against a constant, then use specialized routines for doing the comparison. If a constant comparison is being done within a multifield slot and the constant's position has no multifields to the left or no multifields to the right, then use the same routine used for the single field slot case, but include the offset from either the beginning or end of the slot. Otherwise, use a general eq/neq test. =============================================================== */ ClearBitString((void *) &hack,(int) sizeof(struct ObjectCmpPNConstant)); if (theNode->negated) hack.fail = 1; else hack.pass = 1; if (((theNode->withinMultifieldSlot == FALSE) || (theNode->multiFieldsAfter == 0) || (theNode->multiFieldsBefore == 0)) && (theNode->slotNumber != ISA_ID) && (theNode->slotNumber != NAME_ID)) { if (theNode->withinMultifieldSlot == FALSE) hack.fromBeginning = TRUE; else if (theNode->multiFieldsBefore == 0) { hack.fromBeginning = TRUE; hack.offset = theNode->singleFieldsBefore; } else hack.offset = theNode->singleFieldsAfter; theExp = GenConstant(theEnv,OBJ_PN_CONSTANT,EnvAddBitMap(theEnv,(void *) &hack, (int) sizeof(struct ObjectCmpPNConstant))); theExp->argList = GenConstant(theEnv,theNode->type,theNode->value); } else { hack.general = 1; theExp = GenConstant(theEnv,OBJ_PN_CONSTANT,EnvAddBitMap(theEnv,(void *) &hack, (int) sizeof(struct ObjectCmpPNConstant))); theExp->argList = GenConstant(theEnv,0,NULL); tmpType = theNode->type; theNode->type = SF_VARIABLE; GenObjectGetVar(theEnv,FALSE,theExp->argList,theNode,-1); theNode->type = tmpType; theExp->argList->nextArg = GenConstant(theEnv,theNode->type,theNode->value); } return(theExp); }
globle EXPRESSION *GenGetJNObjectValue( struct lhsParseNode *theNode) { EXPRESSION *theItem; theItem = GenConstant(0,NULL); GenObjectGetVar(TRUE,theItem,theNode); return(theItem); }
globle EXPRESSION *GenGetPNObjectValue( void *theEnv, struct lhsParseNode *theNode) { EXPRESSION *theItem; theItem = GenConstant(theEnv,0,NULL); GenObjectGetVar(theEnv,FALSE,theItem,theNode,-1); return(theItem); }
/*************************************************************** NAME : GenerateSlotComparisonTest DESCRIPTION : Generates pattern and join network expressions for comparing object pattern variables INPUTS : 1) A flag indicating if this is a pattern or join network test 2) For a join test, a flag indicating if it is a nand join 3) The intermediate parse node for the first variable 4) The intermediate parse node for the second variable RETURNS : An expression for comparing the variables SIDE EFFECTS : Expression and bitmaps generated NOTES : The following tests are generated for the following scenarios: SF slot w/ SF slot: PN_1 or JN_1 Example: (foo ?x) with (bar ?xy) SF slot w/ SF reference in MF slot: PN_2 or JN_2 Example: (foo ?x) (bar ? ?x ? ?) SF reference w/ SF reference: PN_3 or JN_3 Example: (foo ? ?x ?) and (bar ? ? ? ?x) All other cases: EQ/NEQ general test Example: (foo $? ?x $?) and (bar ?x) ***************************************************************/ static EXPRESSION *GenerateSlotComparisonTest( void *theEnv, int joinTest, int isNand, struct lhsParseNode *selfNode, struct lhsParseNode *referringNode) { EXPRESSION *theExp; struct ObjectCmpPNSingleSlotVars1 phack1; struct ObjectCmpPNSingleSlotVars2 phack2; struct ObjectCmpPNSingleSlotVars3 phack3; struct ObjectCmpJoinSingleSlotVars1 jhack1; struct ObjectCmpJoinSingleSlotVars2 jhack2; struct ObjectCmpJoinSingleSlotVars3 jhack3; struct lhsParseNode *firstNode; if (isNand) { firstNode = referringNode; } else { firstNode = selfNode; } /* ========================================================= If we are comparing two single-field slot variables that don't require multifield markers for lookup, use a quick comparison. Otherwise, use a general eq/neq with the pattern variable access routines ========================================================= */ if (IsSimpleSlotVariable(firstNode) && IsSimpleSlotVariable(referringNode)) { /* ============================== Compare two single-field slots ============================== */ if ((firstNode->withinMultifieldSlot == FALSE) && (referringNode->withinMultifieldSlot == FALSE)) { ClearBitString((void *) &phack1,(int) sizeof(struct ObjectCmpPNSingleSlotVars1)); ClearBitString((void *) &jhack1,(int) sizeof(struct ObjectCmpJoinSingleSlotVars1)); if (selfNode->negated) phack1.fail = jhack1.fail = 1; else phack1.pass = jhack1.pass = 1; phack1.firstSlot = jhack1.firstSlot = (unsigned short) firstNode->slotNumber; phack1.secondSlot = jhack1.secondSlot = (unsigned short) referringNode->slotNumber; if (joinTest) { if (isNand) { jhack1.firstPattern = (unsigned short) referringNode->joinDepth; } else { jhack1.firstPattern = 0; } jhack1.firstPatternRHS = TRUE; jhack1.secondPatternLHS = TRUE; jhack1.secondPattern = (unsigned short) referringNode->joinDepth; theExp = GenConstant(theEnv,OBJ_JN_CMP1,EnvAddBitMap(theEnv,(void *) &jhack1, (int) sizeof(struct ObjectCmpJoinSingleSlotVars1))); } else theExp = GenConstant(theEnv,OBJ_PN_CMP1,EnvAddBitMap(theEnv,(void *) &phack1, (int) sizeof(struct ObjectCmpPNSingleSlotVars1))); } /* ============================================ Compare a single-field slot with a single-field in a multifield slot (make sure the multifield slot reference is first ============================================ */ else if ((firstNode->withinMultifieldSlot == FALSE) || (referringNode->withinMultifieldSlot == FALSE)) { ClearBitString((void *) &phack2,(int) sizeof(struct ObjectCmpPNSingleSlotVars2)); ClearBitString((void *) &jhack2,(int) sizeof(struct ObjectCmpJoinSingleSlotVars2)); if (selfNode->negated) phack2.fail = jhack2.fail = 1; else phack2.pass = jhack2.pass = 1; if (firstNode->withinMultifieldSlot == TRUE) { phack2.firstSlot = jhack2.firstSlot = (unsigned short) firstNode->slotNumber; phack2.secondSlot = jhack2.secondSlot = (unsigned short) referringNode->slotNumber; if (joinTest) { if (isNand) { jhack2.firstPattern = (unsigned short) referringNode->joinDepth; } else { jhack2.firstPattern = 0; } jhack2.firstPatternRHS = TRUE; jhack2.secondPatternLHS = TRUE; jhack2.secondPattern = (unsigned short) referringNode->joinDepth; } if (firstNode->multiFieldsBefore == 0) { phack2.fromBeginning = jhack2.fromBeginning = 1; phack2.offset = jhack2.offset = firstNode->singleFieldsBefore; } else phack2.offset = jhack2.offset = firstNode->singleFieldsAfter; } else { phack2.firstSlot = jhack2.firstSlot = (unsigned short) referringNode->slotNumber; phack2.secondSlot = jhack2.secondSlot = (unsigned short) firstNode->slotNumber; if (joinTest) { if (isNand) { jhack2.secondPattern = (unsigned short) firstNode->joinDepth; } else { jhack2.secondPattern = 0; } jhack2.secondPatternRHS = TRUE; jhack2.firstPatternLHS = TRUE; jhack2.firstPattern = (unsigned short) referringNode->joinDepth; } if (referringNode->multiFieldsBefore == 0) { phack2.fromBeginning = jhack2.fromBeginning = 1; phack2.offset = jhack2.offset = referringNode->singleFieldsBefore; } else phack2.offset = jhack2.offset = referringNode->singleFieldsAfter; } if (joinTest) theExp = GenConstant(theEnv,OBJ_JN_CMP2,EnvAddBitMap(theEnv,(void *) &jhack2, (int) sizeof(struct ObjectCmpJoinSingleSlotVars2))); else theExp = GenConstant(theEnv,OBJ_PN_CMP2,EnvAddBitMap(theEnv,(void *) &phack2, (int) sizeof(struct ObjectCmpPNSingleSlotVars2))); } /* =================================== Compare two single-field references within multifield slots =================================== */ else { ClearBitString((void *) &phack3,(int) sizeof(struct ObjectCmpPNSingleSlotVars3)); ClearBitString((void *) &jhack3,(int) sizeof(struct ObjectCmpJoinSingleSlotVars3)); if (selfNode->negated) phack3.fail = jhack3.fail = 1; else phack3.pass = jhack3.pass = 1; phack3.firstSlot = jhack3.firstSlot = (unsigned short) firstNode->slotNumber; phack3.secondSlot = jhack3.secondSlot = (unsigned short) referringNode->slotNumber; if (firstNode->multiFieldsBefore == 0) { phack3.firstFromBeginning = jhack3.firstFromBeginning = 1; phack3.firstOffset = jhack3.firstOffset = firstNode->singleFieldsBefore; } else phack3.firstOffset = jhack3.firstOffset = firstNode->singleFieldsAfter; if (referringNode->multiFieldsBefore == 0) { phack3.secondFromBeginning = jhack3.secondFromBeginning = 1; phack3.secondOffset = jhack3.secondOffset = referringNode->singleFieldsBefore; } else phack3.secondOffset = jhack3.secondOffset = referringNode->singleFieldsAfter; if (joinTest) { if (isNand) { jhack3.firstPattern = (unsigned short) referringNode->joinDepth; } else { jhack3.firstPattern = 0; } jhack3.firstPatternRHS = TRUE; jhack3.secondPatternLHS = TRUE; jhack3.secondPattern = (unsigned short) referringNode->joinDepth; theExp = GenConstant(theEnv,OBJ_JN_CMP3,EnvAddBitMap(theEnv,(void *) &jhack3, (int) sizeof(struct ObjectCmpJoinSingleSlotVars3))); } else theExp = GenConstant(theEnv,OBJ_PN_CMP3,EnvAddBitMap(theEnv,(void *) &phack3, (int) sizeof(struct ObjectCmpPNSingleSlotVars3))); } } /* ================================================== General comparison for multifield slot references, references which require multifield markers, and object addresses ================================================== */ else { theExp = GenConstant(theEnv,FCALL,selfNode->negated ? ExpressionData(theEnv)->PTR_NEQ : ExpressionData(theEnv)->PTR_EQ); theExp->argList = GenConstant(theEnv,0,NULL); if (isNand) { GenObjectGetVar(theEnv,joinTest,theExp->argList,selfNode,NESTED_RHS); } else { GenObjectGetVar(theEnv,joinTest,theExp->argList,selfNode,RHS); } theExp->argList->nextArg = GenConstant(theEnv,0,NULL); GenObjectGetVar(theEnv,joinTest,theExp->argList->nextArg,referringNode,LHS); } return(theExp); }
/********************************************** Build functions used by AddPatternParser() to provide object access to the join nertwork **********************************************/ globle void ReplaceGetJNObjectValue( EXPRESSION *theItem, struct lhsParseNode *theNode) { GenObjectGetVar(TRUE,theItem,theNode); }
/*************************************************************** NAME : GenerateSlotComparisonTest DESCRIPTION : Generates pattern and join network expressions for comparing object pattern variables INPUTS : 1) A flag indicating if this is a pattern or join network test 2) The intermediate parse node for the first variable 3) The intermediate parse node for the second variable RETURNS : An expression for comparing the variables SIDE EFFECTS : Expression and bitmaps generated NOTES : The following tests are generated for the following scenarios: SF slot w/ SF slot: PN_1 or JN_1 Example: (foo ?x) with (bar ?xy) SF slot w/ SF reference in MF slot: PN_2 or JN_2 Example: (foo ?x) (bar ? ?x ? ?) SF reference w/ SF reference: PN_3 or JN_3 Example: (foo ? ?x ?) and (bar ? ? ? ?x) All other cases: EQ/NEQ general test Example: (foo $? ?x $?) and (bar ?x) ***************************************************************/ static EXPRESSION *GenerateSlotComparisonTest( int joinTest, struct lhsParseNode *selfNode, struct lhsParseNode *referringNode) { EXPRESSION *exp; struct ObjectCmpPNSingleSlotVars1 phack1; struct ObjectCmpPNSingleSlotVars2 phack2; struct ObjectCmpPNSingleSlotVars3 phack3; struct ObjectCmpJoinSingleSlotVars1 jhack1; struct ObjectCmpJoinSingleSlotVars2 jhack2; struct ObjectCmpJoinSingleSlotVars3 jhack3; /* ========================================================= If we are comparing two single-field slot variables that don't require multifield markers for lookup, use a quick comparison. Otherwise, use a general eq/neq with the pattern variable access routines ========================================================= */ if (IsSimpleSlotVariable(selfNode) && IsSimpleSlotVariable(referringNode)) { /* ============================== Compare two single-field slots ============================== */ if ((selfNode->withinMultifieldSlot == FALSE) && (referringNode->withinMultifieldSlot == FALSE)) { ClearBitString((void *) &phack1,(int) sizeof(struct ObjectCmpPNSingleSlotVars1)); ClearBitString((void *) &jhack1,(int) sizeof(struct ObjectCmpJoinSingleSlotVars1)); if (selfNode->negated) phack1.fail = jhack1.fail = 1; else phack1.pass = jhack1.pass = 1; phack1.firstSlot = jhack1.firstSlot = (unsigned) selfNode->slotNumber; phack1.secondSlot = jhack1.secondSlot = (unsigned) referringNode->slotNumber; if (joinTest) { jhack1.firstPattern = (unsigned) selfNode->pattern; jhack1.secondPattern = (unsigned) referringNode->pattern; exp = GenConstant(OBJ_JN_CMP1,AddBitMap((void *) &jhack1, (int) sizeof(struct ObjectCmpJoinSingleSlotVars1))); } else exp = GenConstant(OBJ_PN_CMP1,AddBitMap((void *) &phack1, (int) sizeof(struct ObjectCmpPNSingleSlotVars1))); } /* ============================================ Compare a single-field slot with a single-field in a multifield slot (make sure the multifield slot reference is first ============================================ */ else if ((selfNode->withinMultifieldSlot == FALSE) || (referringNode->withinMultifieldSlot == FALSE)) { ClearBitString((void *) &phack2,(int) sizeof(struct ObjectCmpPNSingleSlotVars2)); ClearBitString((void *) &jhack2,(int) sizeof(struct ObjectCmpJoinSingleSlotVars2)); if (selfNode->negated) phack2.fail = jhack2.fail = 1; else phack2.pass = jhack2.pass = 1; if (selfNode->withinMultifieldSlot == TRUE) { phack2.firstSlot = jhack2.firstSlot = (unsigned) selfNode->slotNumber; phack2.secondSlot = jhack2.secondSlot = (unsigned) referringNode->slotNumber; if (joinTest) { jhack2.firstPattern = (unsigned) selfNode->pattern; jhack2.secondPattern = (unsigned) referringNode->pattern; } if (selfNode->multiFieldsBefore == 0) { phack2.fromBeginning = jhack2.fromBeginning = 1; phack2.offset = jhack2.offset = selfNode->singleFieldsBefore; } else phack2.offset = jhack2.offset = selfNode->singleFieldsAfter; } else { phack2.firstSlot = jhack2.firstSlot = (unsigned) referringNode->slotNumber; phack2.secondSlot = jhack2.secondSlot = (unsigned) selfNode->slotNumber; if (joinTest) { jhack2.firstPattern = (unsigned) referringNode->pattern; jhack2.secondPattern = (unsigned) selfNode->pattern; } if (referringNode->multiFieldsBefore == 0) { phack2.fromBeginning = jhack2.fromBeginning = 1; phack2.offset = jhack2.offset = referringNode->singleFieldsBefore; } else phack2.offset = jhack2.offset = referringNode->singleFieldsAfter; } if (joinTest) exp = GenConstant(OBJ_JN_CMP2,AddBitMap((void *) &jhack2, (int) sizeof(struct ObjectCmpJoinSingleSlotVars2))); else exp = GenConstant(OBJ_PN_CMP2,AddBitMap((void *) &phack2, (int) sizeof(struct ObjectCmpPNSingleSlotVars2))); } /* =================================== Compare two single-field references within multifield slots =================================== */ else { ClearBitString((void *) &phack3,(int) sizeof(struct ObjectCmpPNSingleSlotVars3)); ClearBitString((void *) &jhack3,(int) sizeof(struct ObjectCmpJoinSingleSlotVars3)); if (selfNode->negated) phack3.fail = jhack3.fail = 1; else phack3.pass = jhack3.pass = 1; phack3.firstSlot = jhack3.firstSlot = (unsigned) selfNode->slotNumber; phack3.secondSlot = jhack3.secondSlot = (unsigned) referringNode->slotNumber; if (selfNode->multiFieldsBefore == 0) { phack3.firstFromBeginning = jhack3.firstFromBeginning = 1; phack3.firstOffset = jhack3.firstOffset = selfNode->singleFieldsBefore; } else phack3.firstOffset = jhack3.firstOffset = selfNode->singleFieldsAfter; if (referringNode->multiFieldsBefore == 0) { phack3.secondFromBeginning = jhack3.secondFromBeginning = 1; phack3.secondOffset = jhack3.secondOffset = referringNode->singleFieldsBefore; } else phack3.secondOffset = jhack3.secondOffset = referringNode->singleFieldsAfter; if (joinTest) { jhack3.firstPattern = (unsigned) selfNode->pattern; jhack3.secondPattern = (unsigned) referringNode->pattern; exp = GenConstant(OBJ_JN_CMP3,AddBitMap((void *) &jhack3, (int) sizeof(struct ObjectCmpJoinSingleSlotVars3))); } else exp = GenConstant(OBJ_PN_CMP3,AddBitMap((void *) &phack3, (int) sizeof(struct ObjectCmpPNSingleSlotVars3))); } } /* ================================================== General comparison for multifield slot references, references which require multifield markers, and object addresses ================================================== */ else { exp = GenConstant(FCALL,selfNode->negated ? PTR_NEQ : PTR_EQ); exp->argList = GenConstant(0,NULL); GenObjectGetVar(joinTest,exp->argList,selfNode); exp->argList->nextArg = GenConstant(0,NULL); GenObjectGetVar(joinTest,exp->argList->nextArg,referringNode); } return(exp); }