int main() { TestBitMap(); TestBloomFilter(); system("pause"); return 0; }
static struct templateSlot *GetNextTemplateSlotToPrint( void *theEnv, struct fact *theFact, struct templateSlot *slotPtr, int *position, int ignoreDefaults, const char *changeMap) { DATA_OBJECT tempDO; struct field *sublist; sublist = theFact->theProposition.theFields; if (slotPtr == NULL) { slotPtr = theFact->whichDeftemplate->slotList; } else { slotPtr = slotPtr->next; (*position)++; } while (slotPtr != NULL) { if ((changeMap != NULL) && (TestBitMap(changeMap,*position) == 0)) { (*position)++; slotPtr = slotPtr->next; continue; } if (ignoreDefaults && (slotPtr->defaultDynamic == false)) { DeftemplateSlotDefault(theEnv,theFact->whichDeftemplate,slotPtr,&tempDO,true); if (slotPtr->multislot == false) { if ((GetType(tempDO) == sublist[*position].type) && (GetValue(tempDO) == sublist[*position].value)) { (*position)++; slotPtr = slotPtr->next; continue; } } else if (MultifieldsEqual((struct multifield*) GetValue(tempDO), (struct multifield *) sublist[*position].value)) { (*position)++; slotPtr = slotPtr->next; continue; } } return slotPtr; } return NULL; }
static struct templateSlot *GetNextTemplateSlotToPrint( Environment *theEnv, struct fact *theFact, struct templateSlot *slotPtr, int *position, int ignoreDefaults, const char *changeMap) { UDFValue tempDO; CLIPSValue *sublist; sublist = theFact->theProposition.contents; if (slotPtr == NULL) { slotPtr = theFact->whichDeftemplate->slotList; } else { slotPtr = slotPtr->next; (*position)++; } while (slotPtr != NULL) { if ((changeMap != NULL) && (TestBitMap(changeMap,*position) == 0)) { (*position)++; slotPtr = slotPtr->next; continue; } if (ignoreDefaults && (slotPtr->defaultDynamic == false)) { DeftemplateSlotDefault(theEnv,theFact->whichDeftemplate,slotPtr,&tempDO,true); if (slotPtr->multislot == false) { if (tempDO.value == sublist[*position].value) { (*position)++; slotPtr = slotPtr->next; continue; } } else if (MultifieldsEqual((Multifield *) tempDO.value, (Multifield *) sublist[*position].value)) { (*position)++; slotPtr = slotPtr->next; continue; } } return slotPtr; } return NULL; }
/************************************************************* NAME : ParseDefaultFacet DESCRIPTION : Parses the facet for a slot INPUTS : 1) The input logical name 2) The bitmap indicating which facets have already been parsed 3) The slot descriptor to set RETURNS : True if all OK, false otherwise SIDE EFFECTS : Slot set and parsed facet bitmap set NOTES : Syntax: (default ?NONE|<expression>*) (default-dynamic <expression>*) *************************************************************/ static bool ParseDefaultFacet( Environment *theEnv, const char *readSource, char *specbits, SlotDescriptor *slot) { Expression *tmp; bool error, noneSpecified, deriveSpecified; if (TestBitMap(specbits,DEFAULT_BIT)) { PrintErrorID(theEnv,"CLSLTPSR",2,false); WriteString(theEnv,STDERR,"The 'default' facet for slot '"); WriteString(theEnv,STDERR,slot->slotName->name->contents); WriteString(theEnv,STDERR,"' is already specified.\n"); return false; } SetBitMap(specbits,DEFAULT_BIT); error = false; tmp = ParseDefault(theEnv,readSource,true,TestBitMap(specbits,DEFAULT_DYNAMIC_BIT), false,&noneSpecified,&deriveSpecified,&error); if (error == true) return false; if (noneSpecified || deriveSpecified) { if (noneSpecified) { slot->noDefault = 1; slot->defaultSpecified = 1; } else ClearBitMap(specbits,DEFAULT_BIT); } else { slot->defaultValue = PackExpression(theEnv,tmp); ReturnExpression(theEnv,tmp); ExpressionInstall(theEnv,(Expression *) slot->defaultValue); slot->defaultSpecified = 1; } return true; }
/************************************************************* NAME : ParseDefaultFacet DESCRIPTION : Parses the facet for a slot INPUTS : 1) The input logical name 2) The bitmap indicating which facets have already been parsed 3) The slot descriptor to set RETURNS : TRUE if all OK, FALSE otherwise SIDE EFFECTS : Slot set and parsed facet bitmap set NOTES : Syntax: (default ?NONE|<expression>*) (default-dynamic <expression>*) *************************************************************/ static intBool ParseDefaultFacet( void *theEnv, EXEC_STATUS, char *readSource, char *specbits, SLOT_DESC *slot) { EXPRESSION *tmp; int error,noneSpecified,deriveSpecified; if (TestBitMap(specbits,DEFAULT_BIT)) { PrintErrorID(theEnv,execStatus,"CLSLTPSR",2,FALSE); EnvPrintRouter(theEnv,execStatus,WERROR,"default facet already specified.\n"); return(FALSE); } SetBitMap(specbits,DEFAULT_BIT); error = FALSE; tmp = ParseDefault(theEnv,execStatus,readSource,1,(int) TestBitMap(specbits,DEFAULT_DYNAMIC_BIT), 0,&noneSpecified,&deriveSpecified,&error); if (error == TRUE) return(FALSE); if (noneSpecified || deriveSpecified) { if (noneSpecified) { slot->noDefault = 1; slot->defaultSpecified = 1; } else ClearBitMap(specbits,DEFAULT_BIT); } else { slot->defaultValue = (void *) PackExpression(theEnv,execStatus,tmp); ReturnExpression(theEnv,execStatus,tmp); ExpressionInstall(theEnv,execStatus,(EXPRESSION *) slot->defaultValue); slot->defaultSpecified = 1; } return(TRUE); }
// // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) // // PURPOSE: Processes messages for the main window. // // WM_COMMAND - process the application menu // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_ABOUT: { TestBitMap(hWnd); } //DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_PAINT: { hdc = BeginPaint(hWnd, &ps); // TODO: Add any drawing code here... EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
/*************************************************** NAME : DefclassInScope DESCRIPTION : Determines if a defclass is in scope of the given module INPUTS : 1) The defclass 2) The module (NULL for current module) RETURNS : TRUE if in scope, FALSE otherwise SIDE EFFECTS : None NOTES : None ***************************************************/ globle intBool DefclassInScope( void *theEnv, DEFCLASS *theDefclass, struct defmodule *theModule) { #if DEFMODULE_CONSTRUCT int moduleID; char *scopeMap; scopeMap = (char *) ValueToBitMap(theDefclass->scopeMap); if (theModule == NULL) theModule = ((struct defmodule *) EnvGetCurrentModule(theEnv)); moduleID = (int) theModule->bsaveID; return(TestBitMap(scopeMap,moduleID) ? TRUE : FALSE); #else #if MAC_XCD #pragma unused(theEnv,theDefclass,theModule) #endif return(TRUE); #endif }
/********************************************************** NAME : PrintOPNLevel DESCRIPTION : Recursivley prints object pattern network INPUTS : 1) The current object pattern network node 2) A buffer holding preceding indentation text showing the level in the tree 3) The length of the indentation text RETURNS : Nothing useful SIDE EFFECTS : Pattern nodes recursively printed NOTES : None **********************************************************/ static void PrintOPNLevel( void *theEnv, OBJECT_PATTERN_NODE *pptr, char *indentbuf, int ilen) { CLASS_BITMAP *cbmp; SLOT_BITMAP *sbmp; register unsigned i; OBJECT_PATTERN_NODE *uptr; OBJECT_ALPHA_NODE *alphaPtr; while (pptr != NULL) { EnvPrintRouter(theEnv,WDISPLAY,indentbuf); if (pptr->alphaNode != NULL) EnvPrintRouter(theEnv,WDISPLAY,"+"); EnvPrintRouter(theEnv,WDISPLAY,ValueToString(FindIDSlotName(theEnv,pptr->slotNameID))); EnvPrintRouter(theEnv,WDISPLAY," ("); PrintLongInteger(theEnv,WDISPLAY,(long) pptr->slotNameID); EnvPrintRouter(theEnv,WDISPLAY,") "); EnvPrintRouter(theEnv,WDISPLAY,pptr->endSlot ? "EPF#" : "PF#"); PrintLongInteger(theEnv,WDISPLAY,(long) pptr->whichField); EnvPrintRouter(theEnv,WDISPLAY," "); EnvPrintRouter(theEnv,WDISPLAY,pptr->multifieldNode ? "$? " : "? "); if (pptr->networkTest != NULL) PrintExpression(theEnv,WDISPLAY,pptr->networkTest); EnvPrintRouter(theEnv,WDISPLAY,"\n"); alphaPtr = pptr->alphaNode; while (alphaPtr != NULL) { EnvPrintRouter(theEnv,WDISPLAY,indentbuf); EnvPrintRouter(theEnv,WDISPLAY," Classes:"); cbmp = (CLASS_BITMAP *) ValueToBitMap(alphaPtr->classbmp); for (i = 0 ; i <= cbmp->maxid ; i++) if (TestBitMap(cbmp->map,i)) { EnvPrintRouter(theEnv,WDISPLAY," "); EnvPrintRouter(theEnv,WDISPLAY,EnvGetDefclassName(theEnv,(void *) DefclassData(theEnv)->ClassIDMap[i])); } if (alphaPtr->slotbmp != NULL) { sbmp = (SLOT_BITMAP *) ValueToBitMap(pptr->alphaNode->slotbmp); EnvPrintRouter(theEnv,WDISPLAY," *** Slots:"); for (i = NAME_ID ; i <= sbmp->maxid ; i++) if (TestBitMap(sbmp->map,i)) { for (uptr = pptr ; uptr != NULL ; uptr = uptr->lastLevel) if (uptr->slotNameID == i) break; if (uptr == NULL) { EnvPrintRouter(theEnv,WDISPLAY," "); EnvPrintRouter(theEnv,WDISPLAY,ValueToString(FindIDSlotName(theEnv,i))); } } } EnvPrintRouter(theEnv,WDISPLAY,"\n"); alphaPtr = alphaPtr->nxtInGroup; } indentbuf[ilen++] = (char) ((pptr->rightNode != NULL) ? '|' : ' '); indentbuf[ilen++] = ' '; indentbuf[ilen++] = ' '; indentbuf[ilen] = '\0'; PrintOPNLevel(theEnv,pptr->nextLevel,indentbuf,ilen); ilen -= 3; indentbuf[ilen] = '\0'; pptr = pptr->rightNode; } }
globle void EnvSlotTypes( void *theEnv, void *clsptr, const char *sname, DATA_OBJECT *result) { register unsigned i,j; register SLOT_DESC *sp; char typemap[2]; unsigned msize; if ((sp = SlotInfoSlot(theEnv,result,(DEFCLASS *) clsptr,sname,"slot-types")) == NULL) return; if ((sp->constraint != NULL) ? sp->constraint->anyAllowed : TRUE) { typemap[0] = typemap[1] = (char) 0xFF; ClearBitMap(typemap,MULTIFIELD); msize = 8; } else { typemap[0] = typemap[1] = (char) 0x00; msize = 0; if (sp->constraint->symbolsAllowed) { msize++; SetBitMap(typemap,SYMBOL); } if (sp->constraint->stringsAllowed) { msize++; SetBitMap(typemap,STRING); } if (sp->constraint->floatsAllowed) { msize++; SetBitMap(typemap,FLOAT); } if (sp->constraint->integersAllowed) { msize++; SetBitMap(typemap,INTEGER); } if (sp->constraint->instanceNamesAllowed) { msize++; SetBitMap(typemap,INSTANCE_NAME); } if (sp->constraint->instanceAddressesAllowed) { msize++; SetBitMap(typemap,INSTANCE_ADDRESS); } if (sp->constraint->externalAddressesAllowed) { msize++; SetBitMap(typemap,EXTERNAL_ADDRESS); } if (sp->constraint->factAddressesAllowed) { msize++; SetBitMap(typemap,FACT_ADDRESS); } } SetpDOEnd(result,msize); result->value = EnvCreateMultifield(theEnv,msize); i = 1; j = 0; while (i <= msize) { if (TestBitMap(typemap,j)) { SetMFType(result->value,i,SYMBOL); SetMFValue(result->value,i, (void *) GetDefclassNamePointer((void *) DefclassData(theEnv)->PrimitiveClassMap[j])); i++; } j++; } }
/******************************************************************** NAME : EvaluateSlotDefaultValue DESCRIPTION : Checks the default value against the slot constraints and evaluates static default values INPUTS : 1) The slot descriptor 2) The bitmap marking which facets were specified in the original slot definition RETURNS : TRUE if all OK, FALSE otherwise SIDE EFFECTS : Static default value expressions deleted and replaced with data object evaluation NOTES : On errors, slot is marked as dynamix so that DeleteSlots() will erase the slot expression ********************************************************************/ static intBool EvaluateSlotDefaultValue( void *theEnv, EXEC_STATUS, SLOT_DESC *sd, char *specbits) { DATA_OBJECT temp; int oldce,olddcc,vCode; /* =================================================================== Slot default value expression is marked as dynamic until now so that DeleteSlots() would erase in the event of an error. The delay was so that the evaluation of a static default value could be delayed until all the constraints were parsed. =================================================================== */ if (TestBitMap(specbits,DEFAULT_DYNAMIC_BIT) == 0) sd->dynamicDefault = 0; if (sd->noDefault) return(TRUE); if (sd->dynamicDefault == 0) { if (TestBitMap(specbits,DEFAULT_BIT)) { oldce = ExecutingConstruct(theEnv,execStatus); SetExecutingConstruct(theEnv,execStatus,TRUE); olddcc = EnvSetDynamicConstraintChecking(theEnv,execStatus,EnvGetStaticConstraintChecking(theEnv,execStatus)); vCode = EvaluateAndStoreInDataObject(theEnv,execStatus,(int) sd->multiple, (EXPRESSION *) sd->defaultValue,&temp,TRUE); if (vCode != FALSE) vCode = ValidSlotValue(theEnv,execStatus,&temp,sd,NULL,"slot default value"); EnvSetDynamicConstraintChecking(theEnv,execStatus,olddcc); SetExecutingConstruct(theEnv,execStatus,oldce); if (vCode) { ExpressionDeinstall(theEnv,execStatus,(EXPRESSION *) sd->defaultValue); ReturnPackedExpression(theEnv,execStatus,(EXPRESSION *) sd->defaultValue); sd->defaultValue = (void *) get_struct(theEnv,execStatus,dataObject); GenCopyMemory(DATA_OBJECT,1,sd->defaultValue,&temp); ValueInstall(theEnv,execStatus,(DATA_OBJECT *) sd->defaultValue); } else { sd->dynamicDefault = 1; return(FALSE); } } else if (sd->defaultSpecified == 0) { sd->defaultValue = (void *) get_struct(theEnv,execStatus,dataObject); DeriveDefaultFromConstraints(theEnv,execStatus,sd->constraint, (DATA_OBJECT *) sd->defaultValue,(int) sd->multiple,TRUE); ValueInstall(theEnv,execStatus,(DATA_OBJECT *) sd->defaultValue); } } else if (EnvGetStaticConstraintChecking(theEnv,execStatus)) { vCode = ConstraintCheckExpressionChain(theEnv,execStatus,(EXPRESSION *) sd->defaultValue,sd->constraint); if (vCode != NO_VIOLATION) { PrintErrorID(theEnv,execStatus,"CSTRNCHK",1,FALSE); EnvPrintRouter(theEnv,execStatus,WERROR,"Expression for "); PrintSlot(theEnv,execStatus,WERROR,sd,NULL,"dynamic default value"); ConstraintViolationErrorMessage(theEnv,execStatus,NULL,NULL,0,0,NULL,0, vCode,sd->constraint,FALSE); return(FALSE); } } return(TRUE); }
/************************************************************************** NAME : BuildCompositeFacets DESCRIPTION : Composite slots are ones that get their facets from more than one class. By default, the most specific class in object's precedence list specifies the complete set of facets for a slot. The composite facet in a slot allows facets that are not overridden by the most specific class to be obtained from other classes. Since all superclasses are predetermined before creating a new class based on them, this routine need only examine the immediately next most specific class for extra facets. Even if that slot is also composite, the other facets have already been filtered down. If the slot is no-inherit, the next most specific class must be examined. INPUTS : 1) The slot descriptor 2) The class precedence list 3) The bitmap marking which facets were specified in the original slot definition RETURNS : Nothing useful SIDE EFFECTS : Composite slot is updated to reflect facets from a less specific class NOTES : Assumes slot is composite *************************************************************************/ static void BuildCompositeFacets( void *theEnv, EXEC_STATUS, SLOT_DESC *sd, PACKED_CLASS_LINKS *preclist, char *specbits, CONSTRAINT_PARSE_RECORD *parsedConstraint) { SLOT_DESC *compslot = NULL; long i; for (i = 1 ; i < preclist->classCount ; i++) { compslot = FindClassSlot(preclist->classArray[i],sd->slotName->name); if ((compslot != NULL) ? (compslot->noInherit == 0) : FALSE) break; } if (compslot != NULL) { if ((sd->defaultSpecified == 0) && (compslot->defaultSpecified == 1)) { sd->dynamicDefault = compslot->dynamicDefault; sd->noDefault = compslot->noDefault; sd->defaultSpecified = 1; if (compslot->defaultValue != NULL) { if (sd->dynamicDefault) { sd->defaultValue = (void *) PackExpression(theEnv,execStatus,(EXPRESSION *) compslot->defaultValue); ExpressionInstall(theEnv,execStatus,(EXPRESSION *) sd->defaultValue); } else { sd->defaultValue = (void *) get_struct(theEnv,execStatus,dataObject); GenCopyMemory(DATA_OBJECT,1,sd->defaultValue,compslot->defaultValue); ValueInstall(theEnv,execStatus,(DATA_OBJECT *) sd->defaultValue); } } } if (TestBitMap(specbits,FIELD_BIT) == 0) sd->multiple = compslot->multiple; if (TestBitMap(specbits,STORAGE_BIT) == 0) sd->shared = compslot->shared; if (TestBitMap(specbits,ACCESS_BIT) == 0) { sd->noWrite = compslot->noWrite; sd->initializeOnly = compslot->initializeOnly; } #if DEFRULE_CONSTRUCT if (TestBitMap(specbits,MATCH_BIT) == 0) sd->reactive = compslot->reactive; #endif if (TestBitMap(specbits,VISIBILITY_BIT) == 0) sd->publicVisibility = compslot->publicVisibility; if (TestBitMap(specbits,CREATE_ACCESSOR_BIT) == 0) { sd->createReadAccessor = compslot->createReadAccessor; sd->createWriteAccessor = compslot->createWriteAccessor; } if ((TestBitMap(specbits,OVERRIDE_MSG_BIT) == 0) && compslot->overrideMessageSpecified) { DecrementSymbolCount(theEnv,execStatus,sd->overrideMessage); sd->overrideMessage = compslot->overrideMessage; IncrementSymbolCount(sd->overrideMessage); sd->overrideMessageSpecified = TRUE; } OverlayConstraint(theEnv,execStatus,parsedConstraint,sd->constraint,compslot->constraint); } }
/**************************************************************** NAME : ParseSimpleFacet DESCRIPTION : Parses the following facets for a slot: access, source, propagation, storage, pattern-match, visibility and override-message INPUTS : 1) The input logical name 2) The bitmap indicating which facets have already been parsed 3) The name of the facet 4) The bit to test/set in arg #2 for this facet 5) The facet value string which indicates the facet should be false 6) The facet value string which indicates the facet should be TRUE 7) An alternate value string for use when the first two don't match (can be NULL) 7) An alternate value string for use when the first three don't match (can be NULL) (will be an SF_VARIABLE type) 9) A buffer to hold the facet value symbol (can be NULL - only set if args #5 and #6 are both NULL) RETURNS : -1 on errors 0 if first value string matched 1 if second value string matched 2 if alternate value string matched 3 if variable value string matched 4 if facet value buffer was set SIDE EFFECTS : Messages printed on errors Bitmap marked indicating facet was parsed Facet value symbol buffer set, if appropriate NOTES : None *****************************************************************/ static int ParseSimpleFacet( void *theEnv, EXEC_STATUS, char *readSource, char *specbits, char *facetName, int testBit, char *clearRelation, char *setRelation, char *alternateRelation, char *varRelation, SYMBOL_HN **facetSymbolicValue) { int rtnCode; if (TestBitMap(specbits,testBit)) { PrintErrorID(theEnv,execStatus,"CLSLTPSR",2,FALSE); EnvPrintRouter(theEnv,execStatus,WERROR,facetName); EnvPrintRouter(theEnv,execStatus,WERROR," facet already specified.\n"); return(-1); } SetBitMap(specbits,testBit); SavePPBuffer(theEnv,execStatus," "); GetToken(theEnv,execStatus,readSource,&DefclassData(theEnv,execStatus)->ObjectParseToken); /* =============================== Check for the variable relation =============================== */ if (DefclassData(theEnv,execStatus)->ObjectParseToken.type == SF_VARIABLE) { if ((varRelation == NULL) ? FALSE : (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),varRelation) == 0)) rtnCode = 3; else goto ParseSimpleFacetError; } else { if (DefclassData(theEnv,execStatus)->ObjectParseToken.type != SYMBOL) goto ParseSimpleFacetError; /* =================================================== If the facet value buffer is non-NULL simply get the value and do not check any relations =================================================== */ if (facetSymbolicValue == NULL) { if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),clearRelation) == 0) rtnCode = 0; else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),setRelation) == 0) rtnCode = 1; else if ((alternateRelation == NULL) ? FALSE : (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),alternateRelation) == 0)) rtnCode = 2; else goto ParseSimpleFacetError; } else { rtnCode = 4; *facetSymbolicValue = (SYMBOL_HN *) DefclassData(theEnv,execStatus)->ObjectParseToken.value; } } GetToken(theEnv,execStatus,readSource,&DefclassData(theEnv,execStatus)->ObjectParseToken); if (DefclassData(theEnv,execStatus)->ObjectParseToken.type != RPAREN) goto ParseSimpleFacetError; return(rtnCode); ParseSimpleFacetError: SyntaxErrorMessage(theEnv,execStatus,"slot facet"); return(-1); }
/************************************************************ NAME : ParseSlot DESCRIPTION : Parses slot definitions for a defclass statement INPUTS : 1) The logical name of the input source 2) The current slot list 3) The class precedence list for the class to which this slot is being attached (used to find facets for composite slots) 4) A flag indicating if this is a multifield slot or not 5) A flag indicating if the type of slot (single or multi) was explicitly specified or not RETURNS : The address of the list of slots, NULL if there was an error SIDE EFFECTS : The slot list is allocated NOTES : Assumes "(slot" has already been parsed. ************************************************************/ globle TEMP_SLOT_LINK *ParseSlot( void *theEnv, EXEC_STATUS, char *readSource, TEMP_SLOT_LINK *slist, PACKED_CLASS_LINKS *preclist, int multiSlot, int fieldSpecified) { SLOT_DESC *slot; CONSTRAINT_PARSE_RECORD parsedConstraint; char specbits[2]; int rtnCode; SYMBOL_HN *newOverrideMsg; /* =============================================================== Bits in specbits are when slot qualifiers are specified so that duplicate or conflicting qualifiers can be detected. Shared/local bit-0 Single/multiple bit-1 Read-only/Read-write/Initialize-Only bit-2 Inherit/No-inherit bit-3 Composite/Exclusive bit-4 Reactive/Nonreactive bit-5 Default bit-6 Default-dynamic bit-7 Visibility bit-8 Override-message bit-9 =============================================================== */ SavePPBuffer(theEnv,execStatus," "); specbits[0] = specbits[1] = '\0'; GetToken(theEnv,execStatus,readSource,&DefclassData(theEnv,execStatus)->ObjectParseToken); if (GetType(DefclassData(theEnv,execStatus)->ObjectParseToken) != SYMBOL) { DeleteSlots(theEnv,execStatus,slist); SyntaxErrorMessage(theEnv,execStatus,"defclass slot"); return(NULL); } if ((DefclassData(theEnv,execStatus)->ObjectParseToken.value == (void *) DefclassData(theEnv,execStatus)->ISA_SYMBOL) || (DefclassData(theEnv,execStatus)->ObjectParseToken.value == (void *) DefclassData(theEnv,execStatus)->NAME_SYMBOL)) { DeleteSlots(theEnv,execStatus,slist); SyntaxErrorMessage(theEnv,execStatus,"defclass slot"); return(NULL); } slot = NewSlot(theEnv,execStatus,(SYMBOL_HN *) GetValue(DefclassData(theEnv,execStatus)->ObjectParseToken)); slist = InsertSlot(theEnv,execStatus,slist,slot); if (slist == NULL) return(NULL); if (multiSlot) slot->multiple = TRUE; if (fieldSpecified) SetBitMap(specbits,FIELD_BIT); GetToken(theEnv,execStatus,readSource,&DefclassData(theEnv,execStatus)->ObjectParseToken); IncrementIndentDepth(theEnv,execStatus,3); InitializeConstraintParseRecord(&parsedConstraint); while (GetType(DefclassData(theEnv,execStatus)->ObjectParseToken) == LPAREN) { PPBackup(theEnv,execStatus); PPCRAndIndent(theEnv,execStatus); SavePPBuffer(theEnv,execStatus,"("); GetToken(theEnv,execStatus,readSource,&DefclassData(theEnv,execStatus)->ObjectParseToken); if (GetType(DefclassData(theEnv,execStatus)->ObjectParseToken) != SYMBOL) { SyntaxErrorMessage(theEnv,execStatus,"defclass slot"); goto ParseSlotError; } else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),DEFAULT_FACET) == 0) { if (ParseDefaultFacet(theEnv,execStatus,readSource,specbits,slot) == FALSE) goto ParseSlotError; } else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),DYNAMIC_FACET) == 0) { SetBitMap(specbits,DEFAULT_DYNAMIC_BIT); if (ParseDefaultFacet(theEnv,execStatus,readSource,specbits,slot) == FALSE) goto ParseSlotError; } else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),ACCESS_FACET) == 0) { rtnCode = ParseSimpleFacet(theEnv,execStatus,readSource,specbits,ACCESS_FACET,ACCESS_BIT, SLOT_RDWRT_RLN,SLOT_RDONLY_RLN,SLOT_INIT_RLN, NULL,NULL); if (rtnCode == -1) goto ParseSlotError; else if (rtnCode == 1) slot->noWrite = 1; else if (rtnCode == 2) slot->initializeOnly = 1; } else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),STORAGE_FACET) == 0) { rtnCode = ParseSimpleFacet(theEnv,execStatus,readSource,specbits,STORAGE_FACET,STORAGE_BIT, SLOT_LOCAL_RLN,SLOT_SHARE_RLN,NULL,NULL,NULL); if (rtnCode == -1) goto ParseSlotError; slot->shared = rtnCode; } else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),PROPAGATION_FACET) == 0) { rtnCode = ParseSimpleFacet(theEnv,execStatus,readSource,specbits,PROPAGATION_FACET,PROPAGATION_BIT, SLOT_INH_RLN,SLOT_NO_INH_RLN,NULL,NULL,NULL); if (rtnCode == -1) goto ParseSlotError; slot->noInherit = rtnCode; } else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),SOURCE_FACET) == 0) { rtnCode = ParseSimpleFacet(theEnv,execStatus,readSource,specbits,SOURCE_FACET,SOURCE_BIT, SLOT_EXCLUSIVE_RLN,SLOT_COMPOSITE_RLN,NULL,NULL,NULL); if (rtnCode == -1) goto ParseSlotError; slot->composite = rtnCode; } #if DEFRULE_CONSTRUCT else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),MATCH_FACET) == 0) { rtnCode = ParseSimpleFacet(theEnv,execStatus,readSource,specbits,MATCH_FACET,MATCH_BIT, SLOT_NONREACTIVE_RLN,SLOT_REACTIVE_RLN,NULL,NULL,NULL); if (rtnCode == -1) goto ParseSlotError; slot->reactive = rtnCode; } #endif else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),VISIBILITY_FACET) == 0) { rtnCode = ParseSimpleFacet(theEnv,execStatus,readSource,specbits,VISIBILITY_FACET,VISIBILITY_BIT, SLOT_PRIVATE_RLN,SLOT_PUBLIC_RLN,NULL,NULL,NULL); if (rtnCode == -1) goto ParseSlotError; slot->publicVisibility = rtnCode; } else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),CREATE_ACCESSOR_FACET) == 0) { rtnCode = ParseSimpleFacet(theEnv,execStatus,readSource,specbits,CREATE_ACCESSOR_FACET, CREATE_ACCESSOR_BIT, SLOT_READ_RLN,SLOT_WRITE_RLN,SLOT_RDWRT_RLN, SLOT_NONE_RLN,NULL); if (rtnCode == -1) goto ParseSlotError; if ((rtnCode == 0) || (rtnCode == 2)) slot->createReadAccessor = TRUE; if ((rtnCode == 1) || (rtnCode == 2)) slot->createWriteAccessor = TRUE; } else if (strcmp(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken),OVERRIDE_MSG_FACET) == 0) { rtnCode = ParseSimpleFacet(theEnv,execStatus,readSource,specbits,OVERRIDE_MSG_FACET,OVERRIDE_MSG_BIT, NULL,NULL,NULL,SLOT_DEFAULT_RLN,&newOverrideMsg); if (rtnCode == -1) goto ParseSlotError; if (rtnCode == 4) { DecrementSymbolCount(theEnv,execStatus,slot->overrideMessage); slot->overrideMessage = newOverrideMsg; IncrementSymbolCount(slot->overrideMessage); } slot->overrideMessageSpecified = TRUE; } else if (StandardConstraint(DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken))) { if (ParseStandardConstraint(theEnv,execStatus,readSource,DOToString(DefclassData(theEnv,execStatus)->ObjectParseToken), slot->constraint,&parsedConstraint,TRUE) == FALSE) goto ParseSlotError; } else { SyntaxErrorMessage(theEnv,execStatus,"defclass slot"); goto ParseSlotError; } GetToken(theEnv,execStatus,readSource,&DefclassData(theEnv,execStatus)->ObjectParseToken); } if (GetType(DefclassData(theEnv,execStatus)->ObjectParseToken) != RPAREN) { SyntaxErrorMessage(theEnv,execStatus,"defclass slot"); goto ParseSlotError; } if (DefclassData(theEnv,execStatus)->ClassDefaultsMode == CONVENIENCE_MODE) { if (! TestBitMap(specbits,CREATE_ACCESSOR_BIT)) { slot->createReadAccessor = TRUE; if (! slot->noWrite) { slot->createWriteAccessor = TRUE; } } } if (slot->composite) BuildCompositeFacets(theEnv,execStatus,slot,preclist,specbits,&parsedConstraint); if (CheckForFacetConflicts(theEnv,execStatus,slot,&parsedConstraint) == FALSE) goto ParseSlotError; if (CheckConstraintParseConflicts(theEnv,execStatus,slot->constraint) == FALSE) goto ParseSlotError; if (EvaluateSlotDefaultValue(theEnv,execStatus,slot,specbits) == FALSE) goto ParseSlotError; if ((slot->dynamicDefault == 0) && (slot->noWrite == 1) && (slot->initializeOnly == 0)) slot->shared = 1; slot->constraint = AddConstraint(theEnv,execStatus,slot->constraint); DecrementIndentDepth(theEnv,execStatus,3); return(slist); ParseSlotError: DecrementIndentDepth(theEnv,execStatus,3); DeleteSlots(theEnv,execStatus,slist); return(NULL); }
/******************************************************************** NAME : EvaluateSlotDefaultValue DESCRIPTION : Checks the default value against the slot constraints and evaluates static default values INPUTS : 1) The slot descriptor 2) The bitmap marking which facets were specified in the original slot definition RETURNS : True if all OK, false otherwise SIDE EFFECTS : Static default value expressions deleted and replaced with data object evaluation NOTES : On errors, slot is marked as dynamix so that DeleteSlots() will erase the slot expression ********************************************************************/ static bool EvaluateSlotDefaultValue( Environment *theEnv, SlotDescriptor *sd, const char *specbits) { UDFValue temp; bool oldce,olddcc, vPass; ConstraintViolationType vCode; /* =================================================================== Slot default value expression is marked as dynamic until now so that DeleteSlots() would erase in the event of an error. The delay was so that the evaluation of a static default value could be delayed until all the constraints were parsed. =================================================================== */ if (! TestBitMap(specbits,DEFAULT_DYNAMIC_BIT)) sd->dynamicDefault = 0; if (sd->noDefault) return true; if (sd->dynamicDefault == 0) { if (TestBitMap(specbits,DEFAULT_BIT)) { oldce = ExecutingConstruct(theEnv); SetExecutingConstruct(theEnv,true); olddcc = SetDynamicConstraintChecking(theEnv,true); vPass = EvaluateAndStoreInDataObject(theEnv,sd->multiple, (Expression *) sd->defaultValue,&temp,true); if (vPass != false) vPass = (ValidSlotValue(theEnv,&temp,sd,NULL,"the 'default' facet") == PSE_NO_ERROR); SetDynamicConstraintChecking(theEnv,olddcc); SetExecutingConstruct(theEnv,oldce); if (vPass) { ExpressionDeinstall(theEnv,(Expression *) sd->defaultValue); ReturnPackedExpression(theEnv,(Expression *) sd->defaultValue); sd->defaultValue = get_struct(theEnv,udfValue); GenCopyMemory(UDFValue,1,sd->defaultValue,&temp); RetainUDFV(theEnv,(UDFValue *) sd->defaultValue); } else { sd->dynamicDefault = 1; return false; } } else if (sd->defaultSpecified == 0) { sd->defaultValue = get_struct(theEnv,udfValue); DeriveDefaultFromConstraints(theEnv,sd->constraint, (UDFValue *) sd->defaultValue,sd->multiple,true); RetainUDFV(theEnv,(UDFValue *) sd->defaultValue); } } else { vCode = ConstraintCheckExpressionChain(theEnv,(Expression *) sd->defaultValue,sd->constraint); if (vCode != NO_VIOLATION) { PrintErrorID(theEnv,"CSTRNCHK",1,false); WriteString(theEnv,STDERR,"Expression for "); PrintSlot(theEnv,STDERR,sd,NULL,"dynamic default value"); ConstraintViolationErrorMessage(theEnv,NULL,NULL,0,0,NULL,0, vCode,sd->constraint,false); return false; } } return true; }
/************************************************************************** NAME : BuildCompositeFacets DESCRIPTION : Composite slots are ones that get their facets from more than one class. By default, the most specific class in object's precedence list specifies the complete set of facets for a slot. The composite facet in a slot allows facets that are not overridden by the most specific class to be obtained from other classes. Since all superclasses are predetermined before creating a new class based on them, this routine need only examine the immediately next most specific class for extra facets. Even if that slot is also composite, the other facets have already been filtered down. If the slot is no-inherit, the next most specific class must be examined. INPUTS : 1) The slot descriptor 2) The class precedence list 3) The bitmap marking which facets were specified in the original slot definition RETURNS : Nothing useful SIDE EFFECTS : Composite slot is updated to reflect facets from a less specific class NOTES : Assumes slot is composite *************************************************************************/ static void BuildCompositeFacets( Environment *theEnv, SlotDescriptor *sd, PACKED_CLASS_LINKS *preclist, const char *specbits, CONSTRAINT_PARSE_RECORD *parsedConstraint) { SlotDescriptor *compslot = NULL; unsigned long i; for (i = 1 ; i < preclist->classCount ; i++) { compslot = FindClassSlot(preclist->classArray[i],sd->slotName->name); if ((compslot != NULL) ? (compslot->noInherit == 0) : false) break; } if (compslot != NULL) { if ((sd->defaultSpecified == 0) && (compslot->defaultSpecified == 1)) { sd->dynamicDefault = compslot->dynamicDefault; sd->noDefault = compslot->noDefault; sd->defaultSpecified = 1; if (compslot->defaultValue != NULL) { if (sd->dynamicDefault) { sd->defaultValue = PackExpression(theEnv,(Expression *) compslot->defaultValue); ExpressionInstall(theEnv,(Expression *) sd->defaultValue); } else { sd->defaultValue = get_struct(theEnv,udfValue); GenCopyMemory(UDFValue,1,sd->defaultValue,compslot->defaultValue); RetainUDFV(theEnv,(UDFValue *) sd->defaultValue); } } } if (! TestBitMap(specbits,FIELD_BIT)) sd->multiple = compslot->multiple; if (! TestBitMap(specbits,STORAGE_BIT)) sd->shared = compslot->shared; if (! TestBitMap(specbits,ACCESS_BIT)) { sd->noWrite = compslot->noWrite; sd->initializeOnly = compslot->initializeOnly; } #if DEFRULE_CONSTRUCT if (! TestBitMap(specbits,MATCH_BIT)) sd->reactive = compslot->reactive; #endif if (! TestBitMap(specbits,VISIBILITY_BIT)) sd->publicVisibility = compslot->publicVisibility; if (! TestBitMap(specbits,CREATE_ACCESSOR_BIT)) { sd->createReadAccessor = compslot->createReadAccessor; sd->createWriteAccessor = compslot->createWriteAccessor; } if ((! TestBitMap(specbits,OVERRIDE_MSG_BIT)) && compslot->overrideMessageSpecified) { ReleaseLexeme(theEnv,sd->overrideMessage); sd->overrideMessage = compslot->overrideMessage; IncrementLexemeCount(sd->overrideMessage); sd->overrideMessageSpecified = true; } OverlayConstraint(theEnv,parsedConstraint,sd->constraint,compslot->constraint); } }
/**************************************************************** NAME : ParseSimpleFacet DESCRIPTION : Parses the following facets for a slot: access, source, propagation, storage, pattern-match, visibility and override-message INPUTS : 1) The input logical name 2) The bitmap indicating which facets have already been parsed 3) The name of the facet 4) The bit to test/set in arg #2 for this facet 5) The facet value string which indicates the facet should be false 6) The facet value string which indicates the facet should be true 7) An alternate value string for use when the first two don't match (can be NULL) 7) An alternate value string for use when the first three don't match (can be NULL) (will be an SF_VARIABLE type) 9) A buffer to hold the facet value symbol (can be NULL - only set if args #5 and #6 are both NULL) RETURNS : -1 on errors 0 if first value string matched 1 if second value string matched 2 if alternate value string matched 3 if variable value string matched 4 if facet value buffer was set SIDE EFFECTS : Messages printed on errors Bitmap marked indicating facet was parsed Facet value symbol buffer set, if appropriate NOTES : None *****************************************************************/ static int ParseSimpleFacet( Environment *theEnv, const char *readSource, SlotDescriptor *slot, char *specbits, const char *facetName, int testBit, const char *clearRelation, const char *setRelation, const char *alternateRelation, const char *varRelation, CLIPSLexeme **facetSymbolicValue) { int rtnCode; if (TestBitMap(specbits,testBit)) { PrintErrorID(theEnv,"CLSLTPSR",2,false); WriteString(theEnv,STDERR,"The '"); WriteString(theEnv,STDERR,facetName); WriteString(theEnv,STDERR,"' facet for slot '"); WriteString(theEnv,STDERR,slot->slotName->name->contents); WriteString(theEnv,STDERR,"' is already specified.\n"); return -1; } SetBitMap(specbits,testBit); SavePPBuffer(theEnv," "); GetToken(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken); /* =============================== Check for the variable relation =============================== */ if (DefclassData(theEnv)->ObjectParseToken.tknType == SF_VARIABLE_TOKEN) { if ((varRelation == NULL) ? false : (strcmp(DefclassData(theEnv)->ObjectParseToken.lexemeValue->contents,varRelation) == 0)) rtnCode = 3; else goto ParseSimpleFacetError; } else { if (DefclassData(theEnv)->ObjectParseToken.tknType != SYMBOL_TOKEN) goto ParseSimpleFacetError; /* =================================================== If the facet value buffer is non-NULL simply get the value and do not check any relations =================================================== */ if (facetSymbolicValue == NULL) { if (strcmp(DefclassData(theEnv)->ObjectParseToken.lexemeValue->contents,clearRelation) == 0) rtnCode = 0; else if (strcmp(DefclassData(theEnv)->ObjectParseToken.lexemeValue->contents,setRelation) == 0) rtnCode = 1; else if ((alternateRelation == NULL) ? false : (strcmp(DefclassData(theEnv)->ObjectParseToken.lexemeValue->contents,alternateRelation) == 0)) rtnCode = 2; else goto ParseSimpleFacetError; } else { rtnCode = 4; *facetSymbolicValue = DefclassData(theEnv)->ObjectParseToken.lexemeValue; } } GetToken(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken); if (DefclassData(theEnv)->ObjectParseToken.tknType != RIGHT_PARENTHESIS_TOKEN) goto ParseSimpleFacetError; return(rtnCode); ParseSimpleFacetError: SyntaxErrorMessage(theEnv,"slot facet"); return(-1); }