static struct factPatternNode *FindPatternNode(
  struct factPatternNode *listOfNodes,
  struct lhsParseNode *thePattern,
  struct factPatternNode **nodeBeforeMatch,
  unsigned endSlot)
  {
   *nodeBeforeMatch = NULL;

   /*==========================================================*/
   /* Loop through the nodes at the given level in the pattern */
   /* network looking for a node that can be reused (shared)?  */
   /*==========================================================*/

   while (listOfNodes != NULL)
     {
      /*==========================================================*/
      /* If the type of the pattern node and the expression being */
      /* tested by the pattern node are the same as the type and  */
      /* expression for the pattern field being added, then       */
      /* return the pattern node because it can be shared with    */
      /* the pattern field being added.                           */
      /*==========================================================*/

      if ((thePattern->type == SF_WILDCARD) || (thePattern->type == SF_VARIABLE))
        {
         if ((listOfNodes->header.singlefieldNode) &&
             (listOfNodes->header.endSlot == endSlot) &&
             (listOfNodes->whichField == thePattern->index) &&
             (listOfNodes->whichSlot == (thePattern->slotNumber - 1)) &&
             IdenticalExpression(listOfNodes->networkTest,thePattern->networkTest))
           { return(listOfNodes); }
        }
      else if ((thePattern->type == MF_WILDCARD) || (thePattern->type == MF_VARIABLE))
        {
         if ((listOfNodes->header.multifieldNode) &&
             (listOfNodes->header.endSlot == endSlot) &&
             (listOfNodes->leaveFields == thePattern->singleFieldsAfter) &&
             (listOfNodes->whichField == thePattern->index) &&
             (listOfNodes->whichSlot == (thePattern->slotNumber - 1)) &&
             IdenticalExpression(listOfNodes->networkTest,thePattern->networkTest))
           { return(listOfNodes); }
        }

      /*==================================*/
      /* Move on to the next node at this */
      /* level in the pattern network.    */
      /*==================================*/

      *nodeBeforeMatch = listOfNodes;
      listOfNodes = listOfNodes->rightNode;
     }

   /*==============================================*/
   /* A shareable pattern node could not be found. */
   /*==============================================*/

   return(NULL);
  }
Beispiel #2
0
globle BOOLEAN IdenticalExpression(
  struct expr *firstList,
  struct expr *secondList)
  {
   /*==============================================*/
   /* Compare each argument in both expressions by */
   /* following the nextArg list.                  */
   /*==============================================*/

   for (;
        (firstList != NULL) && (secondList != NULL);
        firstList = firstList->nextArg, secondList = secondList->nextArg)
     {
      /*=========================*/
      /* Compare type and value. */
      /*=========================*/

      if (firstList->type != secondList->type)
        { return(FALSE); }

      if (firstList->value != secondList->value)
        { return (FALSE); }

      /*==============================*/
      /* Compare the arguments lists. */
      /*==============================*/

      if (IdenticalExpression(firstList->argList,secondList->argList) == FALSE)
        { return(FALSE); }
     }

   /*=====================================================*/
   /* If firstList and secondList aren't both NULL, then  */
   /* one of the lists contains more expressions than the */
   /* other.                                              */
   /*=====================================================*/

   if (firstList != secondList) return(FALSE);

   /*============================*/
   /* Expressions are identical. */
   /*============================*/

   return(TRUE);
  }
Beispiel #3
0
/***************************************************
  NAME         : FindHashedExpression
  DESCRIPTION  : Determines if a given expression
                 is in the expression hash table
  INPUTS       : 1) The expression
                 2) A buffer to hold the hash
                    value
                 3) A buffer to hold the previous
                    node in the hash chain
  RETURNS      : The expression hash table entry
                 (NULL if not found)
  SIDE EFFECTS : None
  NOTES        : None
 ***************************************************/
static EXPRESSION_HN *FindHashedExpression(
  EXPRESSION *exp,
  unsigned *hashval,
  EXPRESSION_HN **prv)
  {
   EXPRESSION_HN *exphash;

   if (exp == NULL)
     return(NULL);
   *hashval = HashExpression(exp);
   *prv = NULL;
   exphash = ExpressionHashTable[*hashval];
   while (exphash != NULL)
     {
      if (IdenticalExpression(exphash->exp,exp))
        return(exphash);
      *prv = exphash;
      exphash = exphash->nxt;
     }
   return(NULL);
  }
Beispiel #4
0
static int TestJoinForReuse(
  struct joinNode *testJoin,
  unsigned firstJoin,
  unsigned negatedRHS,
  unsigned existsRHS,
  unsigned int isLogical,
  struct expr *joinTest,
  struct expr *secondaryJoinTest,
  struct expr *leftHash,
  struct expr *rightHash)
  {
   /*==================================================*/
   /* The first join of a rule may only be shared with */
   /* a join that has its firstJoin field set to TRUE. */
   /*==================================================*/

   if (testJoin->firstJoin != firstJoin) return(FALSE);

   /*========================================================*/
   /* A join connected to a not CE may only be shared with a */
   /* join that has its patternIsNegated field set to TRUE.  */
   /*========================================================*/

   if ((testJoin->patternIsNegated != negatedRHS) && (! existsRHS)) return(FALSE);

   /*==========================================================*/
   /* A join connected to an exists CE may only be shared with */
   /* a join that has its patternIsExists field set to TRUE.   */
   /*==========================================================*/

   if (testJoin->patternIsExists != existsRHS) return(FALSE);
   
   /*==========================================================*/
   /* If the join added is associated with a logical CE, then  */
   /* either the join to be shared must be associated with a   */
   /* logical CE or the beta memory must be empty (since       */
   /* joins associate an extra field with each partial match). */
   /*==========================================================*/

   if ((isLogical == TRUE) &&
       (testJoin->logicalJoin == FALSE) &&
       BetaMemoryNotEmpty(testJoin))
     { return(FALSE); }

   /*===============================================================*/
   /* The expression associated with the join must be identical to  */
   /* the networkTest expression stored with the join to be shared. */
   /*===============================================================*/

   if (IdenticalExpression(testJoin->networkTest,joinTest) != TRUE)
     { return(FALSE); }

   if (IdenticalExpression(testJoin->secondaryNetworkTest,secondaryJoinTest) != TRUE)
     { return(FALSE); }
     
   /*====================================================================*/
   /* The alpha memory hashing values associated with the join must be   */
   /* identical to the hashing values stored with the join to be shared. */
   /*====================================================================*/

   if (IdenticalExpression(testJoin->leftHash,leftHash) != TRUE)
     { return(FALSE); }

   if (IdenticalExpression(testJoin->rightHash,rightHash) != TRUE)
     { return(FALSE); }
     
   /*=============================================*/
   /* The join can be shared since all conditions */
   /* for sharing have been satisfied.            */
   /*=============================================*/

   return(TRUE);
  }
Beispiel #5
0
static struct expr *SwitchParse(
  void *theEnv,
  struct expr *top,
  char *infile)
  {
   struct token theToken;
   EXPRESSION *theExp,*chk;
   int default_count = 0;

   /*============================*/
   /* Process the switch value   */
   /*============================*/
   IncrementIndentDepth(theEnv,3);
   SavePPBuffer(theEnv," ");
   top->argList = theExp = ParseAtomOrExpression(theEnv,infile,NULL);
   if (theExp == NULL)
     goto SwitchParseError;

   /*========================*/
   /* Parse case statements. */
   /*========================*/
   GetToken(theEnv,infile,&theToken);
   while (theToken.type != RPAREN)
     {
      PPBackup(theEnv);
      PPCRAndIndent(theEnv);
      SavePPBuffer(theEnv,theToken.printForm);
      if (theToken.type != LPAREN)
        goto SwitchParseErrorAndMessage;
      GetToken(theEnv,infile,&theToken);
      SavePPBuffer(theEnv," ");
      if ((theToken.type == SYMBOL) &&
          (strcmp(ValueToString(theToken.value),"case") == 0))
        {
         if (default_count != 0)
           goto SwitchParseErrorAndMessage;
         theExp->nextArg = ParseAtomOrExpression(theEnv,infile,NULL);
         SavePPBuffer(theEnv," ");
         if (theExp->nextArg == NULL)
           goto SwitchParseError;
         for (chk = top->argList->nextArg ; chk != theExp->nextArg ; chk = chk->nextArg)
           {
            if ((chk->type == theExp->nextArg->type) &&
                (chk->value == theExp->nextArg->value) &&
                IdenticalExpression(chk->argList,theExp->nextArg->argList))
              {
               PrintErrorID(theEnv,"PRCDRPSR",3,TRUE);
               EnvPrintRouter(theEnv,WERROR,"Duplicate case found in switch function.\n");
               goto SwitchParseError;
              }
           }
         GetToken(theEnv,infile,&theToken);
         if ((theToken.type != SYMBOL) ? TRUE :
             (strcmp(ValueToString(theToken.value),"then") != 0))
           goto SwitchParseErrorAndMessage;
        }
      else if ((theToken.type == SYMBOL) &&
               (strcmp(ValueToString(theToken.value),"default") == 0))
        {
         if (default_count)
           goto SwitchParseErrorAndMessage;
         theExp->nextArg = GenConstant(theEnv,RVOID,NULL);
         default_count = 1;
        }
      else
        goto SwitchParseErrorAndMessage;
      theExp = theExp->nextArg;
      if (ExpressionData(theEnv)->svContexts->rtn == TRUE)
        ExpressionData(theEnv)->ReturnContext = TRUE;
      if (ExpressionData(theEnv)->svContexts->brk == TRUE)
        ExpressionData(theEnv)->BreakContext = TRUE;
      IncrementIndentDepth(theEnv,3);
      PPCRAndIndent(theEnv);
      theExp->nextArg = GroupActions(theEnv,infile,&theToken,TRUE,NULL,FALSE);
      DecrementIndentDepth(theEnv,3);
      ExpressionData(theEnv)->ReturnContext = FALSE;
      ExpressionData(theEnv)->BreakContext = FALSE;
      if (theExp->nextArg == NULL)
        goto SwitchParseError;
      theExp = theExp->nextArg;
      PPBackup(theEnv);
      PPBackup(theEnv);
      SavePPBuffer(theEnv,theToken.printForm);
      GetToken(theEnv,infile,&theToken);
     }
   DecrementIndentDepth(theEnv,3);
   return(top);

SwitchParseErrorAndMessage:
   SyntaxErrorMessage(theEnv,"switch function");
SwitchParseError:
   ReturnExpression(theEnv,top);
   DecrementIndentDepth(theEnv,3);
   return(NULL);
  }