コード例 #1
0
ファイル: objrtgen.c プロジェクト: DrItanium/electron
/***************************************************************
  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);
  }
コード例 #2
0
ファイル: objrtgen.c プロジェクト: ahmed-masud/FuzzyCLIPS
/***************************************************************
  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);
  }