static intBool MultiplyDefinedLHSSlots( void *theEnv, struct lhsParseNode *theSlots, SYMBOL_HN *slotName) { for (; theSlots != NULL; theSlots = theSlots->right) { if (theSlots->slot == slotName) { AlreadyParsedErrorMessage(theEnv,(char*)"slot ",ValueToString(slotName)); return(TRUE); } } return(FALSE); }
globle intBool ParseStandardConstraint( void *theEnv, char *readSource, char *constraintName, CONSTRAINT_RECORD *constraints, CONSTRAINT_PARSE_RECORD *parsedConstraints, int multipleValuesAllowed) { int rv = FALSE; /*=====================================================*/ /* Determine if the attribute has already been parsed. */ /*=====================================================*/ if (GetAttributeParseValue(constraintName,parsedConstraints)) { AlreadyParsedErrorMessage(theEnv,constraintName," attribute"); return(FALSE); } /*==========================================*/ /* If specified, parse the range attribute. */ /*==========================================*/ if (strcmp(constraintName,"range") == 0) { rv = ParseRangeCardinalityAttribute(theEnv,readSource,constraints,parsedConstraints, constraintName,multipleValuesAllowed); } /*================================================*/ /* If specified, parse the cardinality attribute. */ /*================================================*/ else if (strcmp(constraintName,"cardinality") == 0) { rv = ParseRangeCardinalityAttribute(theEnv,readSource,constraints,parsedConstraints, constraintName,multipleValuesAllowed); } /*=========================================*/ /* If specified, parse the type attribute. */ /*=========================================*/ else if (strcmp(constraintName,"type") == 0) { rv = ParseTypeAttribute(theEnv,readSource,constraints); } /*================================================*/ /* If specified, parse the allowed-... attribute. */ /*================================================*/ else if ((strcmp(constraintName,"allowed-symbols") == 0) || (strcmp(constraintName,"allowed-strings") == 0) || (strcmp(constraintName,"allowed-lexemes") == 0) || (strcmp(constraintName,"allowed-integers") == 0) || (strcmp(constraintName,"allowed-floats") == 0) || (strcmp(constraintName,"allowed-numbers") == 0) || (strcmp(constraintName,"allowed-instance-names") == 0) || (strcmp(constraintName,"allowed-classes") == 0) || (strcmp(constraintName,"allowed-values") == 0)) { rv = ParseAllowedValuesAttribute(theEnv,readSource,constraintName, constraints,parsedConstraints); } /*=========================================*/ /* Remember which constraint attribute was */ /* parsed and return the error status. */ /*=========================================*/ SetParseFlag(parsedConstraints,constraintName); return(rv); }
static struct templateSlot *ParseSlot( void *theEnv, char *readSource, struct token *inputToken, struct templateSlot *slotList) { int parsingMultislot; SYMBOL_HN *slotName; struct templateSlot *newSlot; int rv; /*=====================================================*/ /* Slots must begin with keyword field or multifield. */ /*=====================================================*/ if ((strcmp(ValueToString(inputToken->value),"field") != 0) && (strcmp(ValueToString(inputToken->value),"multifield") != 0) && (strcmp(ValueToString(inputToken->value),"slot") != 0) && (strcmp(ValueToString(inputToken->value),"multislot") != 0)) { SyntaxErrorMessage(theEnv,"deftemplate"); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } /*===============================================*/ /* Determine if multifield slot is being parsed. */ /*===============================================*/ if ((strcmp(ValueToString(inputToken->value),"multifield") == 0) || (strcmp(ValueToString(inputToken->value),"multislot") == 0)) { parsingMultislot = TRUE; } else { parsingMultislot = FALSE; } /*========================================*/ /* The name of the slot must be a symbol. */ /*========================================*/ SavePPBuffer(theEnv," "); GetToken(theEnv,readSource,inputToken); if (inputToken->type != SYMBOL) { SyntaxErrorMessage(theEnv,"deftemplate"); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } slotName = (SYMBOL_HN *) inputToken->value; /*================================================*/ /* Determine if the slot has already been parsed. */ /*================================================*/ while (slotList != NULL) { if (slotList->slotName == slotName) { AlreadyParsedErrorMessage(theEnv,"slot ",ValueToString(slotList->slotName)); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } slotList = slotList->next; } /*===================================*/ /* Parse the attributes of the slot. */ /*===================================*/ newSlot = DefinedSlots(theEnv,readSource,slotName,parsingMultislot,inputToken); if (newSlot == NULL) { DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } /*=================================*/ /* Check for slot conflict errors. */ /*=================================*/ if (CheckConstraintParseConflicts(theEnv,newSlot->constraints) == FALSE) { ReturnSlots(theEnv,newSlot); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } if ((newSlot->defaultPresent) || (newSlot->defaultDynamic)) { rv = ConstraintCheckExpressionChain(theEnv,newSlot->defaultList,newSlot->constraints); } else { rv = NO_VIOLATION; } if ((rv != NO_VIOLATION) && EnvGetStaticConstraintChecking(theEnv)) { char *temp; if (newSlot->defaultDynamic) temp = "the default-dynamic attribute"; else temp = "the default attribute"; ConstraintViolationErrorMessage(theEnv,"An expression",temp,FALSE,0, newSlot->slotName,0,rv,newSlot->constraints,TRUE); ReturnSlots(theEnv,newSlot); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } /*==================*/ /* Return the slot. */ /*==================*/ return(newSlot); }
static struct templateSlot *DefinedSlots( void *theEnv, char *readSource, SYMBOL_HN *slotName, int multifieldSlot, struct token *inputToken) { struct templateSlot *newSlot; struct expr *defaultList; int defaultFound = FALSE; int noneSpecified, deriveSpecified; CONSTRAINT_PARSE_RECORD parsedConstraints; /*===========================*/ /* Build the slot container. */ /*===========================*/ newSlot = get_struct(theEnv,templateSlot); newSlot->slotName = slotName; newSlot->defaultList = NULL; newSlot->constraints = GetConstraintRecord(theEnv); if (multifieldSlot) { newSlot->constraints->multifieldsAllowed = TRUE; } newSlot->multislot = multifieldSlot; newSlot->noDefault = FALSE; newSlot->defaultPresent = FALSE; newSlot->defaultDynamic = FALSE; newSlot->next = NULL; /*========================================*/ /* Parse the primitive slot if it exists. */ /*========================================*/ InitializeConstraintParseRecord(&parsedConstraints); GetToken(theEnv,readSource,inputToken); while (inputToken->type != RPAREN) { PPBackup(theEnv); SavePPBuffer(theEnv," "); SavePPBuffer(theEnv,inputToken->printForm); /*================================================*/ /* Slot attributes begin with a left parenthesis. */ /*================================================*/ if (inputToken->type != LPAREN) { SyntaxErrorMessage(theEnv,"deftemplate"); ReturnSlots(theEnv,newSlot); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } /*=============================================*/ /* The name of the attribute must be a symbol. */ /*=============================================*/ GetToken(theEnv,readSource,inputToken); if (inputToken->type != SYMBOL) { SyntaxErrorMessage(theEnv,"deftemplate"); ReturnSlots(theEnv,newSlot); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } /*================================================================*/ /* Determine if the attribute is one of the standard constraints. */ /*================================================================*/ if (StandardConstraint(ValueToString(inputToken->value))) { if (ParseStandardConstraint(theEnv,readSource,(ValueToString(inputToken->value)), newSlot->constraints,&parsedConstraints, multifieldSlot) == FALSE) { DeftemplateData(theEnv)->DeftemplateError = TRUE; ReturnSlots(theEnv,newSlot); return(NULL); } } /*=================================================*/ /* else if the attribute is the default attribute, */ /* then get the default list for this slot. */ /*=================================================*/ else if ((strcmp(ValueToString(inputToken->value),"default") == 0) || (strcmp(ValueToString(inputToken->value),"default-dynamic") == 0)) { /*======================================================*/ /* Check to see if the default has already been parsed. */ /*======================================================*/ if (defaultFound) { AlreadyParsedErrorMessage(theEnv,"default attribute",NULL); DeftemplateData(theEnv)->DeftemplateError = TRUE; ReturnSlots(theEnv,newSlot); return(NULL); } newSlot->noDefault = FALSE; /*=====================================================*/ /* Determine whether the default is dynamic or static. */ /*=====================================================*/ if (strcmp(ValueToString(inputToken->value),"default") == 0) { newSlot->defaultPresent = TRUE; newSlot->defaultDynamic = FALSE; } else { newSlot->defaultPresent = FALSE; newSlot->defaultDynamic = TRUE; } /*===================================*/ /* Parse the list of default values. */ /*===================================*/ defaultList = ParseDefault(theEnv,readSource,multifieldSlot,(int) newSlot->defaultDynamic, TRUE,&noneSpecified,&deriveSpecified,&DeftemplateData(theEnv)->DeftemplateError); if (DeftemplateData(theEnv)->DeftemplateError == TRUE) { ReturnSlots(theEnv,newSlot); return(NULL); } /*==================================*/ /* Store the default with the slot. */ /*==================================*/ defaultFound = TRUE; if (deriveSpecified) newSlot->defaultPresent = FALSE; else if (noneSpecified) { newSlot->noDefault = TRUE; newSlot->defaultPresent = FALSE; } newSlot->defaultList = defaultList; } /*============================================*/ /* Otherwise the attribute is an invalid one. */ /*============================================*/ else { SyntaxErrorMessage(theEnv,"slot attributes"); ReturnSlots(theEnv,newSlot); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } /*===================================*/ /* Begin parsing the next attribute. */ /*===================================*/ GetToken(theEnv,readSource,inputToken); } /*============================*/ /* Return the attribute list. */ /*============================*/ return(newSlot); }
static intBool ParseFacetAttribute( void *theEnv, char *readSource, struct templateSlot *theSlot, intBool multifacet) { struct token inputToken; SYMBOL_HN *facetName; struct expr *facetPair, *tempFacet, *facetValue = NULL, *lastValue = NULL; /*==============================*/ /* Parse the name of the facet. */ /*==============================*/ SavePPBuffer(theEnv,(char*)(" ")); GetToken(theEnv,readSource,&inputToken); /*==================================*/ /* The facet name must be a symbol. */ /*==================================*/ if (inputToken.type != SYMBOL) { if (multifacet) SyntaxErrorMessage(theEnv,(char*)("multifacet attribute")); else SyntaxErrorMessage(theEnv,(char*)("facet attribute")); return(FALSE); } facetName = (SYMBOL_HN *) inputToken.value; /*===================================*/ /* Don't allow facets with the same */ /* name as a predefined CLIPS facet. */ /*===================================*/ /*====================================*/ /* Has the facet already been parsed? */ /*====================================*/ for (tempFacet = theSlot->facetList; tempFacet != NULL; tempFacet = tempFacet->nextArg) { if (tempFacet->value == facetName) { if (multifacet) AlreadyParsedErrorMessage(theEnv,(char*)("multifacet "),ValueToString(facetName)); else AlreadyParsedErrorMessage(theEnv,(char*)("facet "),ValueToString(facetName)); return(FALSE); } } /*===============================*/ /* Parse the value of the facet. */ /*===============================*/ SavePPBuffer(theEnv,(char*)(" ")); GetToken(theEnv,readSource,&inputToken); while (inputToken.type != RPAREN) { /*=====================================*/ /* The facet value must be a constant. */ /*=====================================*/ if (! ConstantType(inputToken.type)) { if (multifacet) SyntaxErrorMessage(theEnv, (char*)("multifacet attribute")); else SyntaxErrorMessage(theEnv, (char*)("facet attribute")); ReturnExpression(theEnv,facetValue); return(FALSE); } /*======================================*/ /* Add the value to the list of values. */ /*======================================*/ if (lastValue == NULL) { facetValue = GenConstant(theEnv,inputToken.type,inputToken.value); lastValue = facetValue; } else { lastValue->nextArg = GenConstant(theEnv,inputToken.type,inputToken.value); lastValue = lastValue->nextArg; } /*=====================*/ /* Get the next token. */ /*=====================*/ SavePPBuffer(theEnv,(char*)(" ")); GetToken(theEnv,readSource,&inputToken); /*===============================================*/ /* A facet can't contain more than one constant. */ /*===============================================*/ if ((! multifacet) && (inputToken.type != RPAREN)) { SyntaxErrorMessage(theEnv,(char*)("facet attribute")); ReturnExpression(theEnv,facetValue); return(FALSE); } } /*========================================================*/ /* Remove the space before the closing right parenthesis. */ /*========================================================*/ PPBackup(theEnv); PPBackup(theEnv); SavePPBuffer(theEnv,(char*)(")")); /*====================================*/ /* A facet must contain one constant. */ /*====================================*/ if ((! multifacet) && (facetValue == NULL)) { SyntaxErrorMessage(theEnv,(char*)("facet attribute")); return(FALSE); } /*=================================================*/ /* Add the facet to the list of the slot's facets. */ /*=================================================*/ facetPair = GenConstant(theEnv,SYMBOL,facetName); if (multifacet) { facetPair->argList = GenConstant(theEnv,FCALL, (void *) FindFunction(theEnv,(char*)("create$"))); facetPair->argList->argList = facetValue; } else { facetPair->argList = facetValue; } facetPair->nextArg = theSlot->facetList; theSlot->facetList = facetPair; /*===============================================*/ /* The facet/multifacet was successfully parsed. */ /*===============================================*/ return(TRUE); }
static struct expr *ModAndDupParse( void *theEnv, struct expr *top, char *logicalName, char *name) { int error = FALSE; struct token theToken; struct expr *nextOne, *tempSlot; struct expr *newField, *firstField, *lastField; int printError; short done; /*==================================================================*/ /* Parse the fact-address or index to the modify/duplicate command. */ /*==================================================================*/ SavePPBuffer(theEnv," "); GetToken(theEnv,logicalName,&theToken); if ((theToken.type == SF_VARIABLE) || (theToken.type == GBL_VARIABLE)) { nextOne = GenConstant(theEnv,theToken.type,theToken.value); } else if (theToken.type == INTEGER) { if (! TopLevelCommand(theEnv)) { PrintErrorID(theEnv,"TMPLTFUN",1,TRUE); EnvPrintRouter(theEnv,WERROR,"Fact-indexes can only be used by "); EnvPrintRouter(theEnv,WERROR,name); EnvPrintRouter(theEnv,WERROR," as a top level command.\n"); ReturnExpression(theEnv,top); return(NULL); } nextOne = GenConstant(theEnv,INTEGER,theToken.value); } else { ExpectedTypeError2(theEnv,name,1); ReturnExpression(theEnv,top); return(NULL); } nextOne->nextArg = NULL; nextOne->argList = NULL; top->argList = nextOne; nextOne = top->argList; /*=======================================================*/ /* Parse the remaining modify/duplicate slot specifiers. */ /*=======================================================*/ GetToken(theEnv,logicalName,&theToken); while (theToken.type != RPAREN) { PPBackup(theEnv); SavePPBuffer(theEnv," "); SavePPBuffer(theEnv,theToken.printForm); /*=================================================*/ /* Slot definition begins with a left parenthesis. */ /*=================================================*/ if (theToken.type != LPAREN) { SyntaxErrorMessage(theEnv,"duplicate/modify function"); ReturnExpression(theEnv,top); return(NULL); } /*=================================*/ /* The slot name must be a symbol. */ /*=================================*/ GetToken(theEnv,logicalName,&theToken); if (theToken.type != SYMBOL) { SyntaxErrorMessage(theEnv,"duplicate/modify function"); ReturnExpression(theEnv,top); return(NULL); } /*=================================*/ /* Check for duplicate slot names. */ /*=================================*/ for (tempSlot = top->argList->nextArg; tempSlot != NULL; tempSlot = tempSlot->nextArg) { if (tempSlot->value == theToken.value) { AlreadyParsedErrorMessage(theEnv,"slot ",ValueToString(theToken.value)); ReturnExpression(theEnv,top); return(NULL); } } /*=========================================*/ /* Add the slot name to the list of slots. */ /*=========================================*/ nextOne->nextArg = GenConstant(theEnv,SYMBOL,theToken.value); nextOne = nextOne->nextArg; /*====================================================*/ /* Get the values to be stored in the specified slot. */ /*====================================================*/ firstField = NULL; lastField = NULL; done = FALSE; while (! done) { SavePPBuffer(theEnv," "); newField = GetAssertArgument(theEnv,logicalName,&theToken,&error, RPAREN,FALSE,&printError); if (error) { if (printError) SyntaxErrorMessage(theEnv,"deftemplate pattern"); ReturnExpression(theEnv,top); return(NULL); } if (newField == NULL) { done = TRUE; } if (lastField == NULL) { firstField = newField; } else { lastField->nextArg = newField; } lastField = newField; } /*================================================*/ /* Slot definition ends with a right parenthesis. */ /*================================================*/ if (theToken.type != RPAREN) { SyntaxErrorMessage(theEnv,"duplicate/modify function"); ReturnExpression(theEnv,top); ReturnExpression(theEnv,firstField); return(NULL); } else { PPBackup(theEnv); PPBackup(theEnv); SavePPBuffer(theEnv,")"); } nextOne->argList = firstField; GetToken(theEnv,logicalName,&theToken); } /*================================================*/ /* Return the parsed modify/duplicate expression. */ /*================================================*/ return(top); }
globle struct expr *ParseAssertTemplate( char *readSource, struct token *theToken, int *error, int endType, int constantsOnly, struct deftemplate *theDeftemplate) { struct expr *firstSlot, *lastSlot, *nextSlot; struct expr *firstArg, *tempSlot; struct templateSlot *slotPtr; firstSlot = NULL; lastSlot = NULL; /*==============================================*/ /* Parse each of the slot fields in the assert. */ /*==============================================*/ while ((slotPtr = ParseSlotLabel(readSource,theToken,theDeftemplate,error,endType)) != NULL) { /*========================================================*/ /* Check to see that the slot hasn't already been parsed. */ /*========================================================*/ for (tempSlot = firstSlot; tempSlot != NULL; tempSlot = tempSlot->nextArg) { if (tempSlot->value == (void *) slotPtr->slotName) { AlreadyParsedErrorMessage("slot ",ValueToString(slotPtr->slotName)); *error = TRUE; ReturnExpression(firstSlot); return(NULL); } } #if FUZZY_DEFTEMPLATES /* If the slot was bloaded, there is now an optimisation:- it will only have a constraint record if it was saved with one. Therefore, the test below must first check for the record before checking fuzzy constraints. DPW 20/5/01 */ if ((slotPtr->constraints != NULL) && (slotPtr->constraints->fuzzyValuesAllowed)) { struct expr *newField; struct deftemplate *theFuzzyDeftemplate; /* Fuzzy Deftemplates don't store deftemplate ptr in restrictionList */ if (slotPtr->constraints->fuzzyValueRestriction) theFuzzyDeftemplate = (struct deftemplate *) slotPtr->constraints->restrictionList->value; else theFuzzyDeftemplate = theDeftemplate; newField = ParseAssertFuzzyFact(readSource,theToken, error,endType,constantsOnly, theFuzzyDeftemplate, TRUE); /* note: ParseAssertFuzzyFact will have read the ')' of the slot */ /*=========================================================*/ /* Build and return a structure describing the slot value. */ /*=========================================================*/ if (*error == FALSE) { nextSlot = GenConstant(SYMBOL,slotPtr->slotName); nextSlot->argList = newField; } } else nextSlot = ParseAssertSlotValues(readSource,theToken, slotPtr,error,constantsOnly); #else /*============================================*/ /* Parse the values to be stored in the slot. */ /*============================================*/ nextSlot = ParseAssertSlotValues(readSource,theToken, slotPtr,error,constantsOnly); #endif /* FUZZY_DEFTEMPLATES */ if (*error) { ReturnExpression(firstSlot); return(NULL); } /*============================================*/ /* Check to see if the values to be stored in */ /* the slot violate the slot's constraints. */ /*============================================*/ if (CheckRHSSlotTypes(nextSlot->argList,slotPtr,"assert") == 0) { *error = TRUE; ReturnExpression(firstSlot); ReturnExpression(nextSlot); return(NULL); } /*===================================================*/ /* Add the slot to the list of slots already parsed. */ /*===================================================*/ if (lastSlot == NULL) { firstSlot = nextSlot; } else { lastSlot->nextArg = nextSlot; } lastSlot = nextSlot; } /*=================================================*/ /* Return if an error occured parsing a slot name. */ /*=================================================*/ if (*error) { ReturnExpression(firstSlot); return(NULL); } /*=============================================================*/ /* Reorder the arguments to the order used by the deftemplate. */ /*=============================================================*/ firstArg = ReorderAssertSlotValues(theDeftemplate->slotList,firstSlot,error); ReturnExpression(firstSlot); /*==============================*/ /* Return the assert arguments. */ /*==============================*/ return(firstArg); }
static void DeclarationParse( void *theEnv, char *readSource, char *ruleName, int *error) { struct token theToken; struct expr *packPtr; int notDone = TRUE; int salienceParsed = FALSE, autoFocusParsed = FALSE; /*===========================*/ /* Next token must be a '('. */ /*===========================*/ SavePPBuffer(theEnv," "); GetToken(theEnv,readSource,&theToken); if (theToken.type != LPAREN) { SyntaxErrorMessage(theEnv,"declare statement"); *error = TRUE; return; } /*==========================================*/ /* Continue parsing until there are no more */ /* valid rule property declarations. */ /*==========================================*/ while (notDone) { /*=============================================*/ /* The name of a rule property must be symbol. */ /*=============================================*/ GetToken(theEnv,readSource,&theToken); if (theToken.type != SYMBOL) { SyntaxErrorMessage(theEnv,"declare statement"); *error = TRUE; } /*==============================================*/ /* Parse a salience declaration if encountered. */ /*==============================================*/ else if (strcmp(ValueToString(theToken.value),"salience") == 0) { if (salienceParsed) { AlreadyParsedErrorMessage(theEnv,"salience declaration",NULL); *error = TRUE; } else { ParseSalience(theEnv,readSource,ruleName,error); salienceParsed = TRUE; } } /*=================================================*/ /* Parse an auto-focus declaration if encountered. */ /* A global flag is used to indicate if the */ /* auto-focus feature for a rule was parsed. */ /*=================================================*/ else if (strcmp(ValueToString(theToken.value),"auto-focus") == 0) { if (autoFocusParsed) { AlreadyParsedErrorMessage(theEnv,"auto-focus declaration",NULL); *error = TRUE; } else { ParseAutoFocus(theEnv,readSource,error); autoFocusParsed = TRUE; } } /*==========================================*/ /* Otherwise the symbol does not correspond */ /* to a valid rule property. */ /*==========================================*/ else { SyntaxErrorMessage(theEnv,"declare statement"); *error = TRUE; } /*=====================================*/ /* Return if an error was encountered. */ /*=====================================*/ if (*error) { ReturnExpression(theEnv,PatternData(theEnv)->SalienceExpression); PatternData(theEnv)->SalienceExpression = NULL; return; } /*=======================================*/ /* Both the salience and auto-focus rule */ /* properties are closed with a ')'. */ /*=======================================*/ GetToken(theEnv,readSource,&theToken); if (theToken.type != RPAREN) { PPBackup(theEnv); SavePPBuffer(theEnv," "); SavePPBuffer(theEnv,theToken.printForm); ReturnExpression(theEnv,PatternData(theEnv)->SalienceExpression); PatternData(theEnv)->SalienceExpression = NULL; SyntaxErrorMessage(theEnv,"declare statement"); *error = TRUE; return; } /*=============================================*/ /* The declare statement is closed with a ')'. */ /*=============================================*/ GetToken(theEnv,readSource,&theToken); if (theToken.type == RPAREN) notDone = FALSE; else if (theToken.type != LPAREN) { ReturnExpression(theEnv,PatternData(theEnv)->SalienceExpression); PatternData(theEnv)->SalienceExpression = NULL; SyntaxErrorMessage(theEnv,"declare statement"); *error = TRUE; return; } else { PPBackup(theEnv); SavePPBuffer(theEnv," ("); } } /*==========================================*/ /* Return the value of the salience through */ /* the global variable SalienceExpression. */ /*==========================================*/ packPtr = PackExpression(theEnv,PatternData(theEnv)->SalienceExpression); ReturnExpression(theEnv,PatternData(theEnv)->SalienceExpression); PatternData(theEnv)->SalienceExpression = packPtr; return; }
globle struct expr *ParseAssertTemplate( char *readSource, struct token *theToken, int *error, int endType, int constantsOnly, struct deftemplate *theDeftemplate) { struct expr *firstSlot, *lastSlot, *nextSlot; struct expr *firstArg, *tempSlot; struct templateSlot *slotPtr; firstSlot = NULL; lastSlot = NULL; /*==============================================*/ /* Parse each of the slot fields in the assert. */ /*==============================================*/ while ((slotPtr = ParseSlotLabel(readSource,theToken,theDeftemplate,error,endType)) != NULL) { /*========================================================*/ /* Check to see that the slot hasn't already been parsed. */ /*========================================================*/ for (tempSlot = firstSlot; tempSlot != NULL; tempSlot = tempSlot->nextArg) { if (tempSlot->value == (void *) slotPtr->slotName) { AlreadyParsedErrorMessage("slot ",ValueToString(slotPtr->slotName)); *error = TRUE; ReturnExpression(firstSlot); return(NULL); } } /*============================================*/ /* Parse the values to be stored in the slot. */ /*============================================*/ nextSlot = ParseAssertSlotValues(readSource,theToken, slotPtr,error,constantsOnly); if (*error) { ReturnExpression(firstSlot); return(NULL); } /*============================================*/ /* Check to see if the values to be stored in */ /* the slot violate the slot's constraints. */ /*============================================*/ if (CheckRHSSlotTypes(nextSlot->argList,slotPtr,"assert") == 0) { *error = TRUE; ReturnExpression(firstSlot); ReturnExpression(nextSlot); return(NULL); } /*===================================================*/ /* Add the slot to the list of slots already parsed. */ /*===================================================*/ if (lastSlot == NULL) { firstSlot = nextSlot; } else { lastSlot->nextArg = nextSlot; } lastSlot = nextSlot; } /*=================================================*/ /* Return if an error occured parsing a slot name. */ /*=================================================*/ if (*error) { ReturnExpression(firstSlot); return(NULL); } /*=============================================================*/ /* Reorder the arguments to the order used by the deftemplate. */ /*=============================================================*/ firstArg = ReorderAssertSlotValues(theDeftemplate->slotList,firstSlot,error); ReturnExpression(firstSlot); /*==============================*/ /* Return the assert arguments. */ /*==============================*/ return(firstArg); }