globle int ParseDeftemplate( void *theEnv, char *readSource) { #if (! RUN_TIME) && (! BLOAD_ONLY) SYMBOL_HN *deftemplateName; struct deftemplate *newDeftemplate; struct templateSlot *slots; struct token inputToken; /*================================================*/ /* Initialize pretty print and error information. */ /*================================================*/ DeftemplateData(theEnv)->DeftemplateError = FALSE; SetPPBufferStatus(theEnv,ON); FlushPPBuffer(theEnv); SavePPBuffer(theEnv,(char*)"(deftemplate "); /*==============================================================*/ /* Deftemplates can not be added when a binary image is loaded. */ /*==============================================================*/ #if BLOAD || BLOAD_AND_BSAVE if ((Bloaded(theEnv) == TRUE) && (! ConstructData(theEnv)->CheckSyntaxMode)) { CannotLoadWithBloadMessage(theEnv,(char*)("deftemplate")); return(TRUE); } #endif /*=======================================================*/ /* Parse the name and comment fields of the deftemplate. */ /*=======================================================*/ #if DEBUGGING_FUNCTIONS DeftemplateData(theEnv)->DeletedTemplateDebugFlags = 0; #endif deftemplateName = GetConstructNameAndComment(theEnv,readSource,&inputToken,(char*)("deftemplate"), EnvFindDeftemplate,EnvUndeftemplate,(char*)("%"), TRUE,TRUE,TRUE); if (deftemplateName == NULL) return(TRUE); if (ReservedPatternSymbol(theEnv,ValueToString(deftemplateName),(char*)("deftemplate"))) { ReservedPatternSymbolErrorMsg(theEnv,ValueToString(deftemplateName), (char*)("a deftemplate name")); return(TRUE); } /*===========================================*/ /* Parse the slot fields of the deftemplate. */ /*===========================================*/ slots = SlotDeclarations(theEnv,readSource,&inputToken); if (DeftemplateData(theEnv)->DeftemplateError == TRUE) return(TRUE); /*==============================================*/ /* If we're only checking syntax, don't add the */ /* successfully parsed deftemplate to the KB. */ /*==============================================*/ if (ConstructData(theEnv)->CheckSyntaxMode) { ReturnSlots(theEnv,slots); return(FALSE); } /*=====================================*/ /* Create a new deftemplate structure. */ /*=====================================*/ newDeftemplate = get_struct(theEnv,deftemplate); newDeftemplate->header.name = deftemplateName; newDeftemplate->header.next = NULL; newDeftemplate->header.usrData = NULL; newDeftemplate->slotList = slots; newDeftemplate->implied = FALSE; newDeftemplate->numberOfSlots = 0; newDeftemplate->busyCount = 0; newDeftemplate->watch = 0; newDeftemplate->inScope = TRUE; newDeftemplate->patternNetwork = NULL; newDeftemplate->factList = NULL; newDeftemplate->lastFact = NULL; newDeftemplate->header.whichModule = (struct defmoduleItemHeader *) GetModuleItem(theEnv,NULL,DeftemplateData(theEnv)->DeftemplateModuleIndex); /*================================*/ /* Determine the number of slots. */ /*================================*/ while (slots != NULL) { newDeftemplate->numberOfSlots++; slots = slots->next; } /*====================================*/ /* Store pretty print representation. */ /*====================================*/ if (EnvGetConserveMemory(theEnv) == TRUE) { newDeftemplate->header.ppForm = NULL; } else { newDeftemplate->header.ppForm = CopyPPBuffer(theEnv); } /*=======================================================================*/ /* If a template is redefined, then we want to restore its watch status. */ /*=======================================================================*/ #if DEBUGGING_FUNCTIONS if ((BitwiseTest(DeftemplateData(theEnv)->DeletedTemplateDebugFlags,0)) || EnvGetWatchItem(theEnv,(char*)"facts")) { EnvSetDeftemplateWatch(theEnv,ON,(void *) newDeftemplate); } #endif /*==============================================*/ /* Add deftemplate to the list of deftemplates. */ /*==============================================*/ AddConstructToModule(&newDeftemplate->header); InstallDeftemplate(theEnv,newDeftemplate); #else #endif return(FALSE); }
static struct templateSlot *SlotDeclarations( void *theEnv, char *readSource, struct token *inputToken) { struct templateSlot *newSlot, *slotList = NULL, *lastSlot = NULL; struct templateSlot *multiSlot = NULL; while (inputToken->type != RPAREN) { /*====================================================*/ /* Slots begin with a '(' followed by a slot keyword. */ /*====================================================*/ if (inputToken->type != LPAREN) { SyntaxErrorMessage(theEnv,"deftemplate"); ReturnSlots(theEnv,slotList); ReturnSlots(theEnv,multiSlot); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } GetToken(theEnv,readSource,inputToken); if (inputToken->type != SYMBOL) { SyntaxErrorMessage(theEnv,"deftemplate"); ReturnSlots(theEnv,slotList); ReturnSlots(theEnv,multiSlot); DeftemplateData(theEnv)->DeftemplateError = TRUE; return(NULL); } /*=================*/ /* Parse the slot. */ /*=================*/ newSlot = ParseSlot(theEnv,readSource,inputToken,slotList); if (DeftemplateData(theEnv)->DeftemplateError == TRUE) { ReturnSlots(theEnv,newSlot); ReturnSlots(theEnv,slotList); ReturnSlots(theEnv,multiSlot); return(NULL); } /*===========================================*/ /* Attach the new slot to the list of slots. */ /*===========================================*/ if (newSlot != NULL) { if (lastSlot == NULL) { slotList = newSlot; } else { lastSlot->next = newSlot; } lastSlot = newSlot; } /*================================*/ /* Check for closing parenthesis. */ /*================================*/ GetToken(theEnv,readSource,inputToken); if (inputToken->type != RPAREN) { PPBackup(theEnv); SavePPBuffer(theEnv,"\n "); SavePPBuffer(theEnv,inputToken->printForm); } } SavePPBuffer(theEnv,"\n"); /*=======================*/ /* Return the slot list. */ /*=======================*/ return(slotList); }
globle void DeftemplateCompilerSetup( void *theEnv) { DeftemplateData(theEnv)->DeftemplateCodeItem = AddCodeGeneratorItem(theEnv,(char*)"deftemplate",0,NULL,InitDeftemplateCode,ConstructToCode,3); }
static int ConstructToCode( void *theEnv, char *fileName, char *pathName, char *fileNameBuffer, int fileID, FILE *headerFP, int imageID, int maxIndices) { int fileCount = 1; struct defmodule *theModule; struct deftemplate *theTemplate; struct templateSlot *slotPtr; int slotCount = 0, slotArrayCount = 0, slotArrayVersion = 1; int moduleCount = 0, moduleArrayCount = 0, moduleArrayVersion = 1; int templateArrayCount = 0, templateArrayVersion = 1; FILE *slotFile = NULL, *moduleFile = NULL, *templateFile = NULL; /*==================================================*/ /* Include the appropriate deftemplate header file. */ /*==================================================*/ fprintf(headerFP,"#include \"tmpltdef.h\"\n"); /*=============================================================*/ /* Loop through all the modules, all the deftemplates, and all */ /* the deftemplate slots writing their C code representation */ /* to the file as they are traversed. */ /*=============================================================*/ theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL); while (theModule != NULL) { EnvSetCurrentModule(theEnv,(void *) theModule); moduleFile = OpenFileIfNeeded(theEnv,moduleFile,fileName,pathName,fileNameBuffer,fileID,imageID,&fileCount, moduleArrayVersion,headerFP, (char*)"struct deftemplateModule",ModulePrefix(DeftemplateData(theEnv)->DeftemplateCodeItem), FALSE,NULL); if (moduleFile == NULL) { CloseDeftemplateFiles(theEnv,moduleFile,templateFile,slotFile,maxIndices); return(0); } DeftemplateModuleToCode(theEnv,moduleFile,theModule,imageID,maxIndices,moduleCount); moduleFile = CloseFileIfNeeded(theEnv,moduleFile,&moduleArrayCount,&moduleArrayVersion, maxIndices,NULL,NULL); /*=======================================================*/ /* Loop through each of the deftemplates in this module. */ /*=======================================================*/ theTemplate = (struct deftemplate *) EnvGetNextDeftemplate(theEnv,NULL); while (theTemplate != NULL) { templateFile = OpenFileIfNeeded(theEnv,templateFile,fileName,pathName,fileNameBuffer,fileID,imageID,&fileCount, templateArrayVersion,headerFP, (char*)"struct deftemplate",ConstructPrefix(DeftemplateData(theEnv)->DeftemplateCodeItem), FALSE,NULL); if (templateFile == NULL) { CloseDeftemplateFiles(theEnv,moduleFile,templateFile,slotFile,maxIndices); return(0); } DeftemplateToCode(theEnv,templateFile,theTemplate,imageID,maxIndices, moduleCount,slotCount); templateArrayCount++; templateFile = CloseFileIfNeeded(theEnv,templateFile,&templateArrayCount,&templateArrayVersion, maxIndices,NULL,NULL); /*======================================================*/ /* Loop through each of the slots for this deftemplate. */ /*======================================================*/ slotPtr = theTemplate->slotList; while (slotPtr != NULL) { slotFile = OpenFileIfNeeded(theEnv,slotFile,fileName,pathName,fileNameBuffer,fileID,imageID,&fileCount, slotArrayVersion,headerFP, (char*)"struct templateSlot",SlotPrefix(),FALSE,NULL); if (slotFile == NULL) { CloseDeftemplateFiles(theEnv,moduleFile,templateFile,slotFile,maxIndices); return(0); } SlotToCode(theEnv,slotFile,slotPtr,imageID,maxIndices,slotCount); slotCount++; slotArrayCount++; slotFile = CloseFileIfNeeded(theEnv,slotFile,&slotArrayCount,&slotArrayVersion, maxIndices,NULL,NULL); slotPtr = slotPtr->next; } theTemplate = (struct deftemplate *) EnvGetNextDeftemplate(theEnv,theTemplate); } theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,theModule); moduleCount++; moduleArrayCount++; } CloseDeftemplateFiles(theEnv,moduleFile,templateFile,slotFile,maxIndices); return(1); }
globle void *EnvGetNextDeftemplate( void *theEnv, void *deftemplatePtr) { return((void *) GetNextConstructItem(theEnv,(struct constructHeader *) deftemplatePtr,DeftemplateData(theEnv)->DeftemplateModuleIndex)); }
globle BOOLEAN UpdateModifyDuplicate( void *theEnv, struct expr *top, char *name, void *vTheLHS) { struct expr *functionArgs, *tempArg; SYMBOL_HN *templateName; struct deftemplate *theDeftemplate; struct templateSlot *slotPtr; short position; /*========================================*/ /* Determine the fact-address or index to */ /* be retracted by the modify command. */ /*========================================*/ functionArgs = top->argList; if (functionArgs->type == SF_VARIABLE) { templateName = FindTemplateForFactAddress((SYMBOL_HN *) functionArgs->value, (struct lhsParseNode *) vTheLHS); if (templateName == NULL) return(TRUE); } else { return(TRUE); } /*========================================*/ /* Make sure that the fact being modified */ /* has a corresponding deftemplate. */ /*========================================*/ theDeftemplate = (struct deftemplate *) LookupConstruct(theEnv,DeftemplateData(theEnv)->DeftemplateConstruct, ValueToString(templateName), FALSE); if (theDeftemplate == NULL) return(TRUE); if (theDeftemplate->implied) return(TRUE); /*=============================================================*/ /* Make sure all the slot names are valid for the deftemplate. */ /*=============================================================*/ tempArg = functionArgs->nextArg; while (tempArg != NULL) { /*======================*/ /* Does the slot exist? */ /*======================*/ if ((slotPtr = FindSlot(theDeftemplate,(SYMBOL_HN *) tempArg->value,&position)) == NULL) { InvalidDeftemplateSlotMessage(theEnv,ValueToString(tempArg->value), ValueToString(theDeftemplate->header.name)); return(FALSE); } /*=========================================================*/ /* Is a multifield value being put in a single field slot? */ /*=========================================================*/ if (slotPtr->multislot == FALSE) { if (tempArg->argList == NULL) { SingleFieldSlotCardinalityError(theEnv,slotPtr->slotName->contents); return(FALSE); } else if (tempArg->argList->nextArg != NULL) { SingleFieldSlotCardinalityError(theEnv,slotPtr->slotName->contents); return(FALSE); } else if ((tempArg->argList->type == MF_VARIABLE) || ((tempArg->argList->type == FCALL) ? (((struct FunctionDefinition *) tempArg->argList->value)->returnValueType == 'm') : FALSE)) { SingleFieldSlotCardinalityError(theEnv,slotPtr->slotName->contents); return(FALSE); } } /*======================================*/ /* Are the slot restrictions satisfied? */ /*======================================*/ if (CheckRHSSlotTypes(theEnv,tempArg->argList,slotPtr,name) == 0) return(FALSE); /*=============================================*/ /* Replace the slot with the integer position. */ /*=============================================*/ tempArg->type = INTEGER; tempArg->value = (void *) EnvAddLong(theEnv,(long) (FindSlotPosition(theDeftemplate,(SYMBOL_HN *) tempArg->value) - 1)); tempArg = tempArg->nextArg; } return(TRUE); }
globle struct deftemplateModule *GetDeftemplateModuleItem( void *theEnv, struct defmodule *theModule) { return((struct deftemplateModule *) GetConstructModuleItemByIndex(theEnv,theModule,DeftemplateData(theEnv)->DeftemplateModuleIndex)); }
globle void UndeftemplateCommand( void *theEnv) { UndefconstructCommand(theEnv,"undeftemplate",DeftemplateData(theEnv)->DeftemplateConstruct); }
globle void PPDeftemplateCommand( void *theEnv) { PPConstructCommand(theEnv,"ppdeftemplate",DeftemplateData(theEnv)->DeftemplateConstruct); }
globle void ListDeftemplatesCommand( void *theEnv) { ListConstructCommand(theEnv,"list-deftemplates",DeftemplateData(theEnv)->DeftemplateConstruct); }
globle void *DeftemplateModuleFunction( void *theEnv) { return(GetConstructModuleCommand(theEnv,"deftemplate-module",DeftemplateData(theEnv)->DeftemplateConstruct)); }
globle void GetDeftemplateListFunction( void *theEnv, DATA_OBJECT_PTR returnValue) { GetConstructListFunction(theEnv,"get-deftemplate-list",returnValue,DeftemplateData(theEnv)->DeftemplateConstruct); }
globle intBool EnvUndeftemplate( void *theEnv, void *theDeftemplate) { return(Undefconstruct(theEnv,theDeftemplate,DeftemplateData(theEnv)->DeftemplateConstruct)); }
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); }
globle void *EnvFindDeftemplate( void *theEnv, char *deftemplateName) { return(FindNamedConstruct(theEnv,deftemplateName,DeftemplateData(theEnv)->DeftemplateConstruct)); }
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); }
globle void DeftemplateRunTimeInitialize( void *theEnv) { DoForAllConstructs(theEnv,RuntimeDeftemplateAction,DeftemplateData(theEnv)->DeftemplateModuleIndex,TRUE,NULL); }