/*************************************************** 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); }
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); }
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; }
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); }
/*************************************************** 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); }
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)); }
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); }