Ejemplo n.º 1
0
/***************************************************
  NAME         : ReplaceTemplateNameWithReference
  DESCRIPTION  : In parsing an fact-set query,
                 this function replaces a constant
                 template name with an actual pointer
                 to the template
  INPUTS       : The expression
  RETURNS      : TRUE if all OK, FALSE
                 if template cannot be found
  SIDE EFFECTS : The expression type and value are
                 modified if template is found
  NOTES        : Searches current and imported
                 modules for reference
 ***************************************************/
static intBool ReplaceTemplateNameWithReference(
  void *theEnv,
  EXPRESSION *theExp)
  {
   const char *theTemplateName;
   void *theDeftemplate;
   int count;

   if (theExp->type == SYMBOL)
     {
      theTemplateName = ValueToString(theExp->value);
      
      theDeftemplate = (struct deftemplate *)
                       FindImportedConstruct(theEnv,"deftemplate",NULL,theTemplateName,
                                             &count,TRUE,NULL);

      if (theDeftemplate == NULL)
        {
         CantFindItemErrorMessage(theEnv,"deftemplate",theTemplateName);
         return(FALSE);
        }
        
      if (count > 1)
        {
         AmbiguousReferenceErrorMessage(theEnv,"deftemplate",theTemplateName);
         return(FALSE);
        }

      theExp->type = DEFTEMPLATE_PTR;
      theExp->value = theDeftemplate;
     }
   return(TRUE);
  }
Ejemplo n.º 2
0
static intBool GetDefglobalValue2(
  void *theEnv,
  void *theValue,
  DATA_OBJECT_PTR vPtr)
  {
   struct defglobal *theGlobal;
   int count;

   /*===========================================*/
   /* Search for the specified defglobal in the */
   /* modules visible to the current module.    */
   /*===========================================*/

   theGlobal = (struct defglobal *)
               FindImportedConstruct(theEnv,"defglobal",NULL,ValueToString(theValue),
               &count,TRUE,NULL);

   /*=============================================*/
   /* If it wasn't found, print an error message. */
   /*=============================================*/

   if (theGlobal == NULL)
     {
      PrintErrorID(theEnv,"GLOBLDEF",1,FALSE);
      EnvPrintRouter(theEnv,WERROR,"Global variable ?*");
      EnvPrintRouter(theEnv,WERROR,ValueToString(theValue));
      EnvPrintRouter(theEnv,WERROR,"* is unbound.\n");
      vPtr->type = SYMBOL;
      vPtr->value = EnvFalseSymbol(theEnv);
      SetEvaluationError(theEnv,TRUE);
      return(FALSE);
     }

   /*========================================================*/
   /* The current implementation of the defmodules shouldn't */
   /* allow a construct to be defined which would cause an   */
   /* ambiguous reference, but we'll check for it anyway.    */
   /*========================================================*/

   if (count > 1)
     {
      AmbiguousReferenceErrorMessage(theEnv,"defglobal",ValueToString(theValue));
      vPtr->type = SYMBOL;
      vPtr->value = EnvFalseSymbol(theEnv);
      SetEvaluationError(theEnv,TRUE);
      return(FALSE);
     }

   /*=================================*/
   /* Get the value of the defglobal. */
   /*=================================*/

   QGetDefglobalValue(theEnv,theGlobal,vPtr);

   return(TRUE);
  }
Ejemplo n.º 3
0
static bool EntityGetDefglobalValue(
  Environment *theEnv,
  void *theValue,
  UDFValue *vPtr)
  {
   Defglobal *theGlobal;
   unsigned int count;

   /*===========================================*/
   /* Search for the specified defglobal in the */
   /* modules visible to the current module.    */
   /*===========================================*/

   theGlobal = (Defglobal *)
               FindImportedConstruct(theEnv,"defglobal",NULL,((CLIPSLexeme *) theValue)->contents,
               &count,true,NULL);

   /*=============================================*/
   /* If it wasn't found, print an error message. */
   /*=============================================*/

   if (theGlobal == NULL)
     {
      PrintErrorID(theEnv,"GLOBLDEF",1,false);
      WriteString(theEnv,STDERR,"Global variable ?*");
      WriteString(theEnv,STDERR,((CLIPSLexeme *) theValue)->contents);
      WriteString(theEnv,STDERR,"* is unbound.\n");
      vPtr->value = FalseSymbol(theEnv);
      SetEvaluationError(theEnv,true);
      return false;
     }

   /*========================================================*/
   /* The current implementation of the defmodules shouldn't */
   /* allow a construct to be defined which would cause an   */
   /* ambiguous reference, but we'll check for it anyway.    */
   /*========================================================*/

   if (count > 1)
     {
      AmbiguousReferenceErrorMessage(theEnv,"defglobal",((CLIPSLexeme *) theValue)->contents);
      vPtr->value = FalseSymbol(theEnv);
      SetEvaluationError(theEnv,true);
      return false;
     }

   /*=================================*/
   /* Get the value of the defglobal. */
   /*=================================*/

   CLIPSToUDFValue(&theGlobal->current,vPtr);
     
   return true;
  }
Ejemplo n.º 4
0
globle intBool ReplaceGlobalVariable(
  void *theEnv,
  struct expr *ePtr)
  {
   struct defglobal *theGlobal;
   int count;

   /*=================================*/
   /* Search for the global variable. */
   /*=================================*/

   theGlobal = (struct defglobal *)
               FindImportedConstruct(theEnv,"defglobal",NULL,ValueToString(ePtr->value),
                                     &count,TRUE,NULL);

   /*=============================================*/
   /* If it wasn't found, print an error message. */
   /*=============================================*/

   if (theGlobal == NULL)
     {
      GlobalReferenceErrorMessage(theEnv,ValueToString(ePtr->value));
      return(FALSE);
     }

   /*========================================================*/
   /* The current implementation of the defmodules shouldn't */
   /* allow a construct to be defined which would cause an   */
   /* ambiguous reference, but we'll check for it anyway.    */
   /*========================================================*/

   if (count > 1)
     {
      AmbiguousReferenceErrorMessage(theEnv,"defglobal",ValueToString(ePtr->value));
      return(FALSE);
     }

   /*==============================================*/
   /* Replace the symbolic reference of the global */
   /* variable with a direct pointer reference.    */
   /*==============================================*/

   ePtr->type = DEFGLOBAL_PTR;
   ePtr->value = (void *) theGlobal;

   return(TRUE);
  }
Ejemplo n.º 5
0
/***************************************************
  NAME         : ReplaceTemplateNameWithReference
  DESCRIPTION  : In parsing an fact-set query,
                 this function replaces a constant
                 template name with an actual pointer
                 to the template
  INPUTS       : The expression
  RETURNS      : TRUE if all OK, FALSE
                 if template cannot be found
  SIDE EFFECTS : The expression type and value are
                 modified if template is found
  NOTES        : Searches current and imported
                 modules for reference
 ***************************************************/
static intBool ReplaceTemplateNameWithReference(
  void *theEnv,
  EXPRESSION *theExp)
  {
   const char *theTemplateName;
   void *theDeftemplate;
   int count;

   if (theExp->type == SYMBOL)
     {
      theTemplateName = ValueToString(theExp->value);
      
      theDeftemplate = (struct deftemplate *)
                       FindImportedConstruct(theEnv,"deftemplate",NULL,theTemplateName,
                                             &count,TRUE,NULL);

      if (theDeftemplate == NULL)
        {
         CantFindItemErrorMessage(theEnv,"deftemplate",theTemplateName);
         return(FALSE);
        }
        
      if (count > 1)
        {
         AmbiguousReferenceErrorMessage(theEnv,"deftemplate",theTemplateName);
         return(FALSE);
        }

      theExp->type = DEFTEMPLATE_PTR;
      theExp->value = theDeftemplate;
      
#if (! RUN_TIME) && (! BLOAD_ONLY)
      if (! ConstructData(theEnv)->ParsingConstruct)
        { ConstructData(theEnv)->DanglingConstructs++; }
#endif
     }

   return(TRUE);
  }
Ejemplo n.º 6
0
globle struct expr *GetRHSPattern(
  char *readSource,
  struct token *tempToken,
  int *error,
  int constantsOnly,
  int readFirstParen,
  int checkFirstParen,
  int endType)
  {
   struct expr *lastOne = NULL;
   struct expr *nextOne, *firstOne, *argHead = NULL;
   int printError, count;
   struct deftemplate *theDeftemplate;
   struct symbolHashNode *templateName;

   /*=================================================*/
   /* Get the opening parenthesis of the RHS pattern. */
   /*=================================================*/

   *error = FALSE;

   if (readFirstParen) GetToken(readSource,tempToken);

   if (checkFirstParen)
     {
      if (tempToken->type == endType) return(NULL);

      if (tempToken->type != LPAREN)
        {
         SyntaxErrorMessage("RHS patterns");
         *error = TRUE;
         return(NULL);
        }
     }

   /*======================================================*/
   /* The first field of an asserted fact must be a symbol */
   /* (but not = or : which have special significance).    */
   /*======================================================*/

   GetToken(readSource,tempToken);
   if (tempToken->type != SYMBOL)
     {
      SyntaxErrorMessage("first field of a RHS pattern");
      *error = TRUE;
      return(NULL);
     }
   else if ((strcmp(ValueToString(tempToken->value),"=") == 0) ||
            (strcmp(ValueToString(tempToken->value),":") == 0))
     {
      SyntaxErrorMessage("first field of a RHS pattern");
      *error = TRUE;
      return(NULL);
     }

   /*=========================================================*/
   /* Check to see if the relation name is a reserved symbol. */
   /*=========================================================*/

   templateName = (struct symbolHashNode *) tempToken->value;

   if (ReservedPatternSymbol(ValueToString(templateName),NULL))
     {
      ReservedPatternSymbolErrorMsg(ValueToString(templateName),"a relation name");
      *error = TRUE;
      return(NULL);
     }

   /*============================================================*/
   /* A module separator in the name is illegal in this context. */
   /*============================================================*/

   if (FindModuleSeparator(ValueToString(templateName)))
     {
      IllegalModuleSpecifierMessage();

      *error = TRUE;
      return(NULL);
     }

   /*=============================================================*/
   /* Determine if there is an associated deftemplate. If so, let */
   /* the deftemplate parsing functions parse the RHS pattern and */
   /* then return the fact pattern that was parsed.               */
   /*=============================================================*/

   theDeftemplate = (struct deftemplate *)
                    FindImportedConstruct("deftemplate",NULL,ValueToString(templateName),
                                          &count,TRUE,NULL);

   if (count > 1)
     {
      AmbiguousReferenceErrorMessage("deftemplate",ValueToString(templateName));
      *error = TRUE;
      return(NULL);
     }

   /*======================================================*/
   /* If no deftemplate exists with the specified relation */
   /* name, then create an implied deftemplate.            */
   /*======================================================*/

   if (theDeftemplate == NULL)
#if (! BLOAD_ONLY) && (! RUN_TIME)
     {
#if BLOAD || BLOAD_AND_BSAVE
      if ((Bloaded()) && (! CheckSyntaxMode))
        {
         NoSuchTemplateError(ValueToString(templateName));
         *error = TRUE;
         return(NULL);
        }
#endif
#if DEFMODULE_CONSTRUCT
      if (FindImportExportConflict("deftemplate",((struct defmodule *) GetCurrentModule()),ValueToString(templateName)))
        {
         ImportExportConflictMessage("implied deftemplate",ValueToString(templateName),NULL,NULL);
         *error = TRUE;
         return(NULL);
        }
#endif
      if (! CheckSyntaxMode)
        { theDeftemplate = CreateImpliedDeftemplate((SYMBOL_HN *) templateName,TRUE); }
     }
#else
    {
     NoSuchTemplateError(ValueToString(templateName));
     *error = TRUE;
     return(NULL);
    }
#endif

   /*=========================================*/
   /* If an explicit deftemplate exists, then */
   /* parse the fact as a deftemplate fact.   */
   /*=========================================*/

   if ((theDeftemplate != NULL) && (theDeftemplate->implied == FALSE))
     {
      firstOne = GenConstant(DEFTEMPLATE_PTR,theDeftemplate);
      firstOne->nextArg = ParseAssertTemplate(readSource,tempToken,
                                              error,endType,
                                              constantsOnly,theDeftemplate);
      if (*error)
        {
         ReturnExpression(firstOne);
         firstOne = NULL;
        }

      return(firstOne);
     }

   /*========================================*/
   /* Parse the fact as an ordered RHS fact. */
   /*========================================*/

   firstOne = GenConstant(DEFTEMPLATE_PTR,theDeftemplate);

#if (! RUN_TIME) && (! BLOAD_ONLY)
   SavePPBuffer(" ");
#endif

   while ((nextOne = GetAssertArgument(readSource,tempToken,
                                        error,endType,constantsOnly,&printError)) != NULL)
     {
      if (argHead == NULL) argHead = nextOne;
      else lastOne->nextArg = nextOne;
      lastOne = nextOne;
#if (! RUN_TIME) && (! BLOAD_ONLY)
      SavePPBuffer(" ");
#endif
     }

   /*===========================================================*/
   /* If an error occurred, set the error flag and return NULL. */
   /*===========================================================*/

   if (*error)
     {
      if (printError) SyntaxErrorMessage("RHS patterns");
      ReturnExpression(firstOne);
      ReturnExpression(argHead);
      return(NULL);
     }

   /*=====================================*/
   /* Fix the pretty print representation */
   /* of the RHS ordered fact.            */
   /*=====================================*/

#if (! RUN_TIME) && (! BLOAD_ONLY)
   PPBackup();
   PPBackup();
   SavePPBuffer(tempToken->printForm);
#endif

   /*==========================================================*/
   /* Ordered fact assertions are processed by stuffing all of */
   /* the fact's proposition (except the relation name) into a */
   /* single multifield slot.                                  */
   /*==========================================================*/

   firstOne->nextArg = GenConstant(FACT_STORE_MULTIFIELD,AddBitMap("\0",1));
   firstOne->nextArg->argList = argHead;

   /*==============================*/
   /* Return the RHS ordered fact. */
   /*==============================*/

   return(firstOne);
  }
Ejemplo n.º 7
0
globle struct lhsParseNode *FactPatternParse(
  void *theEnv,
  char *readSource,
  struct token *theToken)
  {
   struct deftemplate *theDeftemplate;
   int count;

   /*=========================================*/
   /* A module separator can not be included  */
   /* as part of the pattern's relation name. */
   /*=========================================*/

   if (FindModuleSeparator(ValueToString(theToken->value)))
     {
      IllegalModuleSpecifierMessage(theEnv);
      return(NULL);
     }

   /*=========================================================*/
   /* Find the deftemplate associated with the relation name. */
   /*=========================================================*/

   theDeftemplate = (struct deftemplate *)
                    FindImportedConstruct(theEnv,"deftemplate",NULL,ValueToString(theToken->value),
                                          &count,TRUE,NULL);

   if (count > 1)
     {
      AmbiguousReferenceErrorMessage(theEnv,"deftemplate",ValueToString(theToken->value));
      return(NULL);
     }

   /*======================================================*/
   /* If no deftemplate exists with the specified relation */
   /* name, then create an implied deftemplate.            */
   /*======================================================*/

   if (theDeftemplate == NULL)
     {
#if DEFMODULE_CONSTRUCT
      if (FindImportExportConflict(theEnv,"deftemplate",((struct defmodule *) EnvGetCurrentModule(theEnv)),ValueToString(theToken->value)))
        {
         ImportExportConflictMessage(theEnv,"implied deftemplate",ValueToString(theToken->value),NULL,NULL);
         return(NULL);
        }
#endif /* DEFMODULE_CONSTRUCT */

      if (! ConstructData(theEnv)->CheckSyntaxMode)
        { theDeftemplate = CreateImpliedDeftemplate(theEnv,(SYMBOL_HN *) theToken->value,TRUE); }
      else
        { theDeftemplate = NULL; }
     }

   /*===============================================*/
   /* If an explicit deftemplate exists, then parse */
   /* the pattern as a deftemplate pattern.         */
   /*===============================================*/

   if ((theDeftemplate != NULL) && (theDeftemplate->implied == FALSE))
     { return(DeftemplateLHSParse(theEnv,readSource,theDeftemplate)); }

   /*================================*/
   /* Parse an ordered fact pattern. */
   /*================================*/

   return(SequenceRestrictionParse(theEnv,readSource,theToken));
  }
Ejemplo n.º 8
0
globle struct expr *GetRHSPattern(
  char *readSource,
  struct token *tempToken,
  int *error,
  int constantsOnly,
  int readFirstParen,
  int checkFirstParen,
  int endType)
  {
   struct expr *lastOne = NULL;
   struct expr *nextOne, *firstOne, *argHead = NULL;
   int printError, count;
   struct deftemplate *theDeftemplate;
   struct symbolHashNode *templateName;

   /*=================================================*/
   /* Get the opening parenthesis of the RHS pattern. */
   /*=================================================*/

   *error = FALSE;

   if (readFirstParen) GetToken(readSource,tempToken);

   if (checkFirstParen)
     {
      if (tempToken->type == endType) return(NULL);

      if (tempToken->type != LPAREN)
        {
         SyntaxErrorMessage("RHS patterns");
         *error = TRUE;
         return(NULL);
        }
     }

   /*======================================================*/
   /* The first field of an asserted fact must be a symbol */
   /* (but not = or : which have special significance).    */
   /*======================================================*/

   GetToken(readSource,tempToken);
   if (tempToken->type != SYMBOL)
     {
      SyntaxErrorMessage("first field of a RHS pattern");
      *error = TRUE;
      return(NULL);
     }
   else if ((strcmp(ValueToString(tempToken->value),"=") == 0) ||
            (strcmp(ValueToString(tempToken->value),":") == 0))
     {
      SyntaxErrorMessage("first field of a RHS pattern");
      *error = TRUE;
      return(NULL);
     }

   /*=========================================================*/
   /* Check to see if the relation name is a reserved symbol. */
   /*=========================================================*/

   templateName = (struct symbolHashNode *) tempToken->value;

   if (ReservedPatternSymbol(ValueToString(templateName),NULL))
     {
      ReservedPatternSymbolErrorMsg(ValueToString(templateName),"a relation name");
      *error = TRUE;
      return(NULL);
     }

   /*============================================================*/
   /* A module separator in the name is illegal in this context. */
   /*============================================================*/

   if (FindModuleSeparator(ValueToString(templateName)))
     {
      IllegalModuleSpecifierMessage();

      *error = TRUE;
      return(NULL);
     }

   /*=============================================================*/
   /* Determine if there is an associated deftemplate. If so, let */
   /* the deftemplate parsing functions parse the RHS pattern and */
   /* then return the fact pattern that was parsed.               */
   /*=============================================================*/

   theDeftemplate = (struct deftemplate *)
                    FindImportedConstruct("deftemplate",NULL,ValueToString(templateName),
                                          &count,TRUE,NULL);

   if (count > 1)
     {
      AmbiguousReferenceErrorMessage("deftemplate",ValueToString(templateName));
      *error = TRUE;
      return(NULL);
     }

   /*======================================================*/
   /* If no deftemplate exists with the specified relation */
   /* name, then create an implied deftemplate.            */
   /*======================================================*/

   if (theDeftemplate == NULL)
#if (! BLOAD_ONLY) && (! RUN_TIME)
     {
#if BLOAD || BLOAD_AND_BSAVE
      if ((Bloaded()) && (! CheckSyntaxMode))
        {
         NoSuchTemplateError(ValueToString(templateName));
         *error = TRUE;
         return(NULL);
        }
#endif
#if DEFMODULE_CONSTRUCT
      if (FindImportExportConflict("deftemplate",((struct defmodule *) GetCurrentModule()),ValueToString(templateName)))
        {
         ImportExportConflictMessage("implied deftemplate",ValueToString(templateName),NULL,NULL);
         *error = TRUE;
         return(NULL);
        }
#endif
      if (! CheckSyntaxMode)
        { theDeftemplate = CreateImpliedDeftemplate((SYMBOL_HN *) templateName,TRUE); }
     }
#else
    {
     NoSuchTemplateError(ValueToString(templateName));
     *error = TRUE;
     return(NULL);
    }
#endif

   /*=========================================*/
   /* If an explicit deftemplate exists, then */
   /* parse the fact as a deftemplate fact.   */
   /*=========================================*/

   if ((theDeftemplate != NULL) && (theDeftemplate->implied == FALSE))
     {
      firstOne = GenConstant(DEFTEMPLATE_PTR,theDeftemplate);
#if FUZZY_DEFTEMPLATES 
      if (theDeftemplate->fuzzyTemplate != NULL)
         firstOne->nextArg = ParseAssertFuzzyFact(readSource,tempToken,
                                              error,endType,
                                              constantsOnly,theDeftemplate,
                                              TRUE);
      else
#endif

      firstOne->nextArg = ParseAssertTemplate(readSource,tempToken,
                                              error,endType,
                                              constantsOnly,theDeftemplate);
      if (*error)
        {
         ReturnExpression(firstOne);
         firstOne = NULL;
        }

#if CERTAINTY_FACTORS 
      else
        {
          /* if certaintly factors allowed then the next item after a fact
             specifier COULD be a certainty factor spec --- CF x.xxx
          */
          SavePPBuffer(" ");
          GetToken(readSource,tempToken);
          if ((tempToken->type == SYMBOL) &&
              ((strcmp(ValueToString(tempToken->value),"CF") == 0) ||
               (strcmp(ValueToString(tempToken->value),"cf") == 0))
             )
            {
              struct expr *CFexpr;
              /* expecting a certainty factor (float) expression */
              /* tokenToFloatExpression expect 1st token already read */
              SavePPBuffer(" ");
              GetToken(readSource,tempToken);
              CFexpr = tokenToFloatExpression(readSource,tempToken,error,constantsOnly);

              if (*error)
                {
                  ReturnExpression(firstOne);
                  return( NULL );
                }

              if (CFexpr->type == FLOAT) /* if constant -- check range */
                {
                  double cfval = ValueToDouble(CFexpr->value);
                  if (cfval > 1.0 || cfval < 0.0)
                    {
                      *error = TRUE;
                      ReturnExpression(CFexpr);
                      cfRangeError();
                      ReturnExpression(firstOne);
                      return( NULL );
                    }
                }

             /* store the CF expression in the argList of the DEFTEMPLATE_PTR expr */
             firstOne->argList = CFexpr;
            }
          else
            {
              /* Do an 'UnGetToken' function here to undo the lookahead for a CF.
                 Also need to PPBackup over the space added before reading the
                 potential CF expression -- UnGetToken does one PPBackup over the
                 token which was added to the PP Buffer
              */
              UnGetToken(tempToken);
              PPBackup();
            }
        }
#endif

      return(firstOne);
     }


   /*========================================*/
   /* Parse the fact as an ordered RHS fact. */
   /*========================================*/

   firstOne = GenConstant(DEFTEMPLATE_PTR,theDeftemplate);

#if FUZZY_DEFTEMPLATES
   /*=============================================*/
   /* Fuzzy facts parsed differently              */
   /*=============================================*/
   if (theDeftemplate->fuzzyTemplate != NULL)
     {
       firstOne->nextArg = ParseAssertFuzzyFact(readSource,tempToken,
                                                error,endType,
                                                constantsOnly,theDeftemplate,
                                                TRUE);
       if (*error)
         {
          ReturnExpression(firstOne);
          return(NULL);
         }
     }
   else
     { /*   --- matches } below with FUZZY_DEFTEMPLATES */

#endif   /* FUZZY_DEFTEMPLATES */


#if (! RUN_TIME) && (! BLOAD_ONLY)
   SavePPBuffer(" ");
#endif

   while ((nextOne = GetAssertArgument(readSource,tempToken,
                                        error,endType,constantsOnly,&printError)) != NULL)
     {
      if (argHead == NULL) argHead = nextOne;
      else lastOne->nextArg = nextOne;
      lastOne = nextOne;
#if (! RUN_TIME) && (! BLOAD_ONLY)
      SavePPBuffer(" ");
#endif
     }

   /*===========================================================*/
   /* If an error occurred, set the error flag and return NULL. */
   /*===========================================================*/

   if (*error)
     {
      if (printError) SyntaxErrorMessage("RHS patterns");
      ReturnExpression(firstOne);
      ReturnExpression(argHead);
      return(NULL);
     }

   /*=====================================*/
   /* Fix the pretty print representation */
   /* of the RHS ordered fact.            */
   /*=====================================*/

#if (! RUN_TIME) && (! BLOAD_ONLY)
   PPBackup();
   PPBackup();
   SavePPBuffer(tempToken->printForm);
#endif

   /*==========================================================*/
   /* Ordered fact assertions are processed by stuffing all of */
   /* the fact's proposition (except the relation name) into a */
   /* single multifield slot.                                  */
   /*==========================================================*/

   firstOne->nextArg = GenConstant(FACT_STORE_MULTIFIELD,AddBitMap("\0",1));
   firstOne->nextArg->argList = argHead;

#if FUZZY_DEFTEMPLATES 
     }  /*    --- matches else { above with FUZZY_DEFTEMPLATES */
#endif

#if CERTAINTY_FACTORS 
   /* if certaintly factors allowed then the next item after a fact
          specifier could be a certainty factor spec --- CF x.xxx
   */
#if (! RUN_TIME) && (! BLOAD_ONLY)
   SavePPBuffer(" ");
#endif
   GetToken(readSource,tempToken);
   if ((tempToken->type == SYMBOL) &&
           ((strcmp(ValueToString(tempToken->value),"CF") == 0) ||
                (strcmp(ValueToString(tempToken->value),"cf") == 0))
          )
         {
            struct expr *CFexpr;

                /* expecting a certainty factor (float) expression */
        /* tokenToFloatExpression expect 1st token already read */
#if (! RUN_TIME) && (! BLOAD_ONLY)
        SavePPBuffer(" ");
#endif
        GetToken(readSource,tempToken);
                CFexpr = tokenToFloatExpression(readSource,tempToken,error,constantsOnly);

            if (*error)
          {
            ReturnExpression(firstOne);
            return( NULL );
          }

            if (CFexpr->type == FLOAT) /* if constant -- check range */
                  {
                    double cfval = ValueToDouble(CFexpr->value);
                        if (cfval > 1.0 || cfval < 0.0)
                          {
                            *error = TRUE;
                ReturnExpression(CFexpr);
                            cfRangeError();
                ReturnExpression(firstOne);
                return( NULL );
                          }
                  }

                /* store the CF expression in the argList of the DEFTEMPLATE_PTR expr */
            firstOne->argList = CFexpr;
          }
        else
      {
            /* Do an 'UnGetToken' function here to undo the lookahead for a CF.
                   Also need to PPBackup over the space added before reading the
                   potential CF expression -- UnGetToken does one PPBackup over the
                   token which was added to the PP Buffer
                */
                UnGetToken(tempToken);
#if (! RUN_TIME) && (! BLOAD_ONLY)
        PPBackup();
#endif
      }

#endif   /* CERTAINTY_FACTORS */


   /*==============================*/
   /* Return the RHS ordered fact. */
   /*==============================*/

   return(firstOne);
  }