Ejemplo n.º 1
0
globle BOOLEAN EvaluateJoinExpression(
  struct expr *joinExpr,
  struct partialMatch *lbinds,
  struct partialMatch *rbinds,
  struct joinNode *joinPtr)
  {
   DATA_OBJECT theResult;
   int andLogic, result = TRUE;
   struct partialMatch *oldLHSBinds;
   struct partialMatch *oldRHSBinds;
   struct joinNode *oldJoin;

   /*======================================*/
   /* A NULL expression evaluates to TRUE. */
   /*======================================*/

   if (joinExpr == NULL) return(TRUE);

   /*=========================================*/
   /* Initialize some of the global variables */
   /* used when evaluating expressions.       */
   /*=========================================*/

   oldLHSBinds = GlobalLHSBinds;
   oldRHSBinds = GlobalRHSBinds;
   oldJoin = GlobalJoin;
   GlobalLHSBinds = lbinds;
   GlobalRHSBinds = rbinds;
   GlobalJoin = joinPtr;

   /*=====================================================*/
   /* Partial matches stored in joins that are associated */
   /* with a not CE contain an additional slot shouldn't  */
   /* be considered when evaluating expressions. Since    */
   /* joins that have joins from the right don't have any */
   /* expression, we don't have to do this for partial    */
   /* matches contained in these joins.                   */
   /*=====================================================*/

   if (joinPtr->patternIsNegated) lbinds->bcount--;

   /*====================================================*/
   /* Initialize some variables which allow this routine */
   /* to avoid calling the "and" and "or" functions if   */
   /* they are the first part of the expression to be    */
   /* evaluated. Most of the join expressions do not use */
   /* deeply nested and/or functions so this technique   */
   /* speeds up evaluation.                              */
   /*====================================================*/

   if (joinExpr->value == PTR_AND)
     {
      andLogic = TRUE;
      joinExpr = joinExpr->argList;
     }
   else if (joinExpr->value == PTR_OR)
     {
      andLogic = FALSE;
      joinExpr = joinExpr->argList;
     }
   else
     { andLogic = TRUE; }

   /*=========================================*/
   /* Evaluate each of the expressions linked */
   /* together in the join expression.        */
   /*=========================================*/

   while (joinExpr != NULL)
     {
      /*================================*/
      /* Evaluate a primitive function. */
      /*================================*/

      if ((PrimitivesArray[joinExpr->type] == NULL) ?
          FALSE :
          PrimitivesArray[joinExpr->type]->evaluateFunction != NULL)
        {
         struct expr *oldArgument;

         oldArgument = CurrentExpression;
         CurrentExpression = joinExpr;
         result = (*PrimitivesArray[joinExpr->type]->evaluateFunction)(joinExpr->value,&theResult);
         CurrentExpression = oldArgument;
        }

      /*=============================*/
      /* Evaluate the "or" function. */
      /*=============================*/

      else if (joinExpr->value == PTR_OR)
        {
         result = FALSE;
         if (EvaluateJoinExpression(joinExpr,lbinds,rbinds,joinPtr) == TRUE)
           {
            if (EvaluationError)
              {
               if (joinPtr->patternIsNegated) lbinds->bcount++;
               GlobalLHSBinds = oldLHSBinds;
               GlobalRHSBinds = oldRHSBinds;
               GlobalJoin = oldJoin;
               return(FALSE);
              }
            result = TRUE;
           }
         else if (EvaluationError)
           {
            if (joinPtr->patternIsNegated) lbinds->bcount++;
            GlobalLHSBinds = oldLHSBinds;
            GlobalRHSBinds = oldRHSBinds;
            GlobalJoin = oldJoin;
            return(FALSE);
           }
        }

      /*==============================*/
      /* Evaluate the "and" function. */
      /*==============================*/

      else if (joinExpr->value == PTR_AND)
        {
         result = TRUE;
         if (EvaluateJoinExpression(joinExpr,lbinds,rbinds,joinPtr) == FALSE)
           {
            if (EvaluationError)
              {
               if (joinPtr->patternIsNegated) lbinds->bcount++;
               GlobalLHSBinds = oldLHSBinds;
               GlobalRHSBinds = oldRHSBinds;
               GlobalJoin = oldJoin;
               return(FALSE);
              }
            result = FALSE;
           }
         else if (EvaluationError)
           {
            if (joinPtr->patternIsNegated) lbinds->bcount++;
            GlobalLHSBinds = oldLHSBinds;
            GlobalRHSBinds = oldRHSBinds;
            GlobalJoin = oldJoin;
            return(FALSE);
           }
        }

      /*==========================================================*/
      /* Evaluate all other expressions using EvaluateExpression. */
      /*==========================================================*/

      else
        {
         EvaluateExpression(joinExpr,&theResult);

         if (EvaluationError)
           {
            JoinNetErrorMessage(joinPtr);
            if (joinPtr->patternIsNegated) lbinds->bcount++;
            GlobalLHSBinds = oldLHSBinds;
            GlobalRHSBinds = oldRHSBinds;
            GlobalJoin = oldJoin;
            return(FALSE);
           }

         if ((theResult.value == FalseSymbol) && (theResult.type == SYMBOL))
           { result = FALSE; }
         else
           { result = TRUE; }
        }

      /*====================================*/
      /* Handle the short cut evaluation of */
      /* the "and" and "or" functions.      */
      /*====================================*/

      if ((andLogic == TRUE) && (result == FALSE))
        {
         if (joinPtr->patternIsNegated) lbinds->bcount++;
         GlobalLHSBinds = oldLHSBinds;
         GlobalRHSBinds = oldRHSBinds;
         GlobalJoin = oldJoin;
         return(FALSE);
        }
      else if ((andLogic == FALSE) && (result == TRUE))
        {
         if (joinPtr->patternIsNegated) lbinds->bcount++;
         GlobalLHSBinds = oldLHSBinds;
         GlobalRHSBinds = oldRHSBinds;
         GlobalJoin = oldJoin;
         return(TRUE);
        }

      /*==============================================*/
      /* Move to the next expression to be evaluated. */
      /*==============================================*/

      joinExpr = joinExpr->nextArg;
     }

   /*=======================================*/
   /* Restore some of the global variables. */
   /*=======================================*/

   GlobalLHSBinds = oldLHSBinds;
   GlobalRHSBinds = oldRHSBinds;
   GlobalJoin = oldJoin;

   /*=====================================*/
   /* Restore the count value for the LHS */
   /* binds if it had to be modified.     */
   /*=====================================*/

   if (joinPtr->patternIsNegated) lbinds->bcount++;

   /*=================================================*/
   /* Return the result of evaluating the expression. */
   /*=================================================*/

   return(result);
  }
Ejemplo n.º 2
0
globle intBool EvaluateJoinExpression(
  void *theEnv,
  struct expr *joinExpr,
  struct joinNode *joinPtr)
  {
   DATA_OBJECT theResult;
   int andLogic, result = TRUE;

   /*======================================*/
   /* A NULL expression evaluates to TRUE. */
   /*======================================*/

   if (joinExpr == NULL) return(TRUE);

   /*====================================================*/
   /* Initialize some variables which allow this routine */
   /* to avoid calling the "and" and "or" functions if   */
   /* they are the first part of the expression to be    */
   /* evaluated. Most of the join expressions do not use */
   /* deeply nested and/or functions so this technique   */
   /* speeds up evaluation.                              */
   /*====================================================*/

   if (joinExpr->value == ExpressionData(theEnv)->PTR_AND)
     {
      andLogic = TRUE;
      joinExpr = joinExpr->argList;
     }
   else if (joinExpr->value == ExpressionData(theEnv)->PTR_OR)
     {
      andLogic = FALSE;
      joinExpr = joinExpr->argList;
     }
   else
     { andLogic = TRUE; }

   /*=========================================*/
   /* Evaluate each of the expressions linked */
   /* together in the join expression.        */
   /*=========================================*/

   while (joinExpr != NULL)
     {
      /*================================*/
      /* Evaluate a primitive function. */
      /*================================*/

      if ((EvaluationData(theEnv)->PrimitivesArray[joinExpr->type] == NULL) ?
          FALSE :
          EvaluationData(theEnv)->PrimitivesArray[joinExpr->type]->evaluateFunction != NULL)
        {
         struct expr *oldArgument;

         oldArgument = EvaluationData(theEnv)->CurrentExpression;
         EvaluationData(theEnv)->CurrentExpression = joinExpr;
         result = (*EvaluationData(theEnv)->PrimitivesArray[joinExpr->type]->evaluateFunction)(theEnv,joinExpr->value,&theResult);
         EvaluationData(theEnv)->CurrentExpression = oldArgument;
        }

      /*=============================*/
      /* Evaluate the "or" function. */
      /*=============================*/

      else if (joinExpr->value == ExpressionData(theEnv)->PTR_OR)
        {
         result = FALSE;
         if (EvaluateJoinExpression(theEnv,joinExpr,joinPtr) == TRUE)
           {
            if (EvaluationData(theEnv)->EvaluationError)
              { return(FALSE); }
            result = TRUE;
           }
         else if (EvaluationData(theEnv)->EvaluationError)
           { return(FALSE); }
        }

      /*==============================*/
      /* Evaluate the "and" function. */
      /*==============================*/

      else if (joinExpr->value == ExpressionData(theEnv)->PTR_AND)
        {
         result = TRUE;
         if (EvaluateJoinExpression(theEnv,joinExpr,joinPtr) == FALSE)
           {
            if (EvaluationData(theEnv)->EvaluationError)
              { return(FALSE); }
            result = FALSE;
           }
         else if (EvaluationData(theEnv)->EvaluationError)
           { return(FALSE); }
        }

      /*==========================================================*/
      /* Evaluate all other expressions using EvaluateExpression. */
      /*==========================================================*/

      else
        {
         EvaluateExpression(theEnv,joinExpr,&theResult);

         if (EvaluationData(theEnv)->EvaluationError)
           {
            JoinNetErrorMessage(theEnv,joinPtr);
            return(FALSE);
           }

         if ((theResult.value == EnvFalseSymbol(theEnv)) && (theResult.type == SYMBOL))
           { result = FALSE; }
         else
           { result = TRUE; }
        }

      /*====================================*/
      /* Handle the short cut evaluation of */
      /* the "and" and "or" functions.      */
      /*====================================*/

      if ((andLogic == TRUE) && (result == FALSE))
        { return(FALSE); }
      else if ((andLogic == FALSE) && (result == TRUE))
        { return(TRUE); }

      /*==============================================*/
      /* Move to the next expression to be evaluated. */
      /*==============================================*/

      joinExpr = joinExpr->nextArg;
     }

   /*=================================================*/
   /* Return the result of evaluating the expression. */
   /*=================================================*/

   return(result);
  }