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); }
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)); }
/************************************************************** NAME : ParseSuperclasses DESCRIPTION : Parses the (is-a <superclass>+) portion of the (defclass ...) construct and returns a list of direct superclasses. The class "standard-class" is the precedence list for classes with no direct superclasses. The final precedence list (not calculated here) will have the class in question first followed by the merged precedence lists of its direct superclasses. INPUTS : 1) The logical name of the input source 2) The symbolic name of the new class RETURNS : The address of the superclass list or NULL if there was an error SIDE EFFECTS : None NOTES : Assumes "(defclass <name> [<comment>] (" has already been scanned. All superclasses must be defined before their subclasses. Duplicates in the (is-a ...) list are are not allowed (a class may only inherits from a superclass once). This routine also checks the class-precedence lists of each of the direct superclasses for an occurrence of the new class - i.e. cycles! This can only happen when a class is redefined (a new class cannot have an unspecified superclass). This routine allocates the space for the list ***************************************************************/ globle PACKED_CLASS_LINKS *ParseSuperclasses( void *theEnv, char *readSource, SYMBOL_HN *newClassName) { CLASS_LINK *clink = NULL,*cbot = NULL,*ctmp; DEFCLASS *sclass; PACKED_CLASS_LINKS *plinks; if (GetType(DefclassData(theEnv)->ObjectParseToken) != LPAREN) { SyntaxErrorMessage(theEnv,(char*)"defclass inheritance"); return(NULL); } GetToken(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken); if ((GetType(DefclassData(theEnv)->ObjectParseToken) != SYMBOL) ? TRUE : (DefclassData(theEnv)->ObjectParseToken.value != (void *) DefclassData(theEnv)->ISA_SYMBOL)) { SyntaxErrorMessage(theEnv,(char*)"defclass inheritance"); return(NULL); } SavePPBuffer(theEnv,(char*)" "); GetToken(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken); while (GetType(DefclassData(theEnv)->ObjectParseToken) != RPAREN) { if (GetType(DefclassData(theEnv)->ObjectParseToken) != SYMBOL) { SyntaxErrorMessage(theEnv,(char*)"defclass"); goto SuperclassParseError; } if (FindModuleSeparator(ValueToString(newClassName))) { IllegalModuleSpecifierMessage(theEnv); goto SuperclassParseError; } if (GetValue(DefclassData(theEnv)->ObjectParseToken) == (void *) newClassName) { PrintErrorID(theEnv,(char*)"INHERPSR",1,FALSE); EnvPrintRouter(theEnv,WERROR,(char*)"A class may not have itself as a superclass.\n"); goto SuperclassParseError; } for (ctmp = clink ; ctmp != NULL ; ctmp = ctmp->nxt) { if (GetValue(DefclassData(theEnv)->ObjectParseToken) == (void *) ctmp->cls->header.name) { PrintErrorID(theEnv,(char*)"INHERPSR",2,FALSE); EnvPrintRouter(theEnv,WERROR,(char*)"A class may inherit from a superclass only once.\n"); goto SuperclassParseError; } } sclass = LookupDefclassInScope(theEnv,ValueToString(GetValue(DefclassData(theEnv)->ObjectParseToken))); if (sclass == NULL) { PrintErrorID(theEnv,(char*)"INHERPSR",3,FALSE); EnvPrintRouter(theEnv,WERROR,(char*)"A class must be defined after all its superclasses.\n"); goto SuperclassParseError; } if ((sclass == DefclassData(theEnv)->PrimitiveClassMap[INSTANCE_NAME]) || (sclass == DefclassData(theEnv)->PrimitiveClassMap[INSTANCE_ADDRESS]) || (sclass == DefclassData(theEnv)->PrimitiveClassMap[INSTANCE_NAME]->directSuperclasses.classArray[0])) { PrintErrorID(theEnv,(char*)"INHERPSR",6,FALSE); EnvPrintRouter(theEnv,WERROR,(char*)"A user-defined class cannot be a subclass of "); EnvPrintRouter(theEnv,WERROR,EnvGetDefclassName(theEnv,(void *) sclass)); EnvPrintRouter(theEnv,WERROR,(char*)".\n"); goto SuperclassParseError; } ctmp = get_struct(theEnv,classLink); ctmp->cls = sclass; if (clink == NULL) clink = ctmp; else cbot->nxt = ctmp; ctmp->nxt = NULL; cbot = ctmp; SavePPBuffer(theEnv,(char*)" "); GetToken(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken); } if (clink == NULL) { PrintErrorID(theEnv,(char*)"INHERPSR",4,FALSE); EnvPrintRouter(theEnv,WERROR,(char*)"Must have at least one superclass.\n"); return(NULL); } PPBackup(theEnv); PPBackup(theEnv); SavePPBuffer(theEnv,(char*)")"); plinks = get_struct(theEnv,packedClassLinks); PackClassLinks(theEnv,plinks,clink); return(plinks); SuperclassParseError: DeleteClassLinks(theEnv,clink); return(NULL); }
globle struct expr *Function2Parse( void *theEnv, char *logicalName, char *name) { struct FunctionDefinition *theFunction; struct expr *top; #if DEFGENERIC_CONSTRUCT void *gfunc; #endif #if DEFFUNCTION_CONSTRUCT void *dptr; #endif /*=========================================================*/ /* Module specification cannot be used in a function call. */ /*=========================================================*/ if (FindModuleSeparator(name)) { IllegalModuleSpecifierMessage(theEnv); return(NULL); } /*================================*/ /* Has the function been defined? */ /*================================*/ theFunction = FindFunction(theEnv,name); #if DEFGENERIC_CONSTRUCT gfunc = (void *) LookupDefgenericInScope(theEnv,name); #endif #if DEFFUNCTION_CONSTRUCT if ((theFunction == NULL) #if DEFGENERIC_CONSTRUCT && (gfunc == NULL) #endif ) dptr = (void *) LookupDeffunctionInScope(theEnv,name); else dptr = NULL; #endif /*=============================*/ /* Define top level structure. */ /*=============================*/ #if DEFFUNCTION_CONSTRUCT if (dptr != NULL) top = GenConstant(theEnv,PCALL,dptr); else #endif #if DEFGENERIC_CONSTRUCT if (gfunc != NULL) top = GenConstant(theEnv,GCALL,gfunc); else #endif if (theFunction != NULL) top = GenConstant(theEnv,FCALL,theFunction); else { PrintErrorID(theEnv,"EXPRNPSR",3,TRUE); EnvPrintRouter(theEnv,WERROR,"Missing function declaration for "); EnvPrintRouter(theEnv,WERROR,name); EnvPrintRouter(theEnv,WERROR,".\n"); return(NULL); } /*=======================================================*/ /* Check to see if function has its own parsing routine. */ /*=======================================================*/ PushRtnBrkContexts(theEnv); ExpressionData(theEnv)->ReturnContext = FALSE; ExpressionData(theEnv)->BreakContext = FALSE; #if DEFGENERIC_CONSTRUCT || DEFFUNCTION_CONSTRUCT if (top->type == FCALL) #endif { if (theFunction->parser != NULL) { top = (*theFunction->parser)(theEnv,top,logicalName); PopRtnBrkContexts(theEnv); if (top == NULL) return(NULL); if (ReplaceSequenceExpansionOps(theEnv,top->argList,top,FindFunction(theEnv,"(expansion-call)"), FindFunction(theEnv,"expand$"))) { ReturnExpression(theEnv,top); return(NULL); } return(top); } } /*========================================*/ /* Default parsing routine for functions. */ /*========================================*/ top = CollectArguments(theEnv,top,logicalName); PopRtnBrkContexts(theEnv); if (top == NULL) return(NULL); if (ReplaceSequenceExpansionOps(theEnv,top->argList,top,FindFunction(theEnv,"(expansion-call)"), FindFunction(theEnv,"expand$"))) { ReturnExpression(theEnv,top); return(NULL); } /*============================================================*/ /* If the function call uses the sequence expansion operator, */ /* its arguments cannot be checked until runtime. */ /*============================================================*/ if (top->value == (void *) FindFunction(theEnv,"(expansion-call)")) { return(top); } /*============================*/ /* Check for argument errors. */ /*============================*/ if ((top->type == FCALL) && EnvGetStaticConstraintChecking(theEnv)) { if (CheckExpressionAgainstRestrictions(theEnv,top,theFunction->restrictions,name)) { ReturnExpression(theEnv,top); return(NULL); } } #if DEFFUNCTION_CONSTRUCT else if (top->type == PCALL) { if (CheckDeffunctionCall(theEnv,top->value,CountArguments(top->argList)) == FALSE) { ReturnExpression(theEnv,top); return(NULL); } } #endif /*========================*/ /* Return the expression. */ /*========================*/ return(top); }
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); }