00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "setup.h"
00035
00036 #if DEFRULE_CONSTRUCT && OBJECT_SYSTEM
00037
00038 #if (! BLOAD_ONLY) && (! RUN_TIME)
00039
00040 #include <string.h>
00041 #include <stdlib.h>
00042
00043 #include "classcom.h"
00044 #include "classfun.h"
00045 #include "cstrnutl.h"
00046 #include "constrnt.h"
00047 #include "cstrnchk.h"
00048 #include "cstrnops.h"
00049 #include "drive.h"
00050 #include "envrnmnt.h"
00051 #include "exprnpsr.h"
00052 #include "inscom.h"
00053 #include "insfun.h"
00054 #include "insmngr.h"
00055 #include "memalloc.h"
00056 #include "network.h"
00057 #include "object.h"
00058 #include "pattern.h"
00059 #include "reteutil.h"
00060 #include "ruledef.h"
00061 #include "rulepsr.h"
00062 #include "scanner.h"
00063 #include "symbol.h"
00064 #include "utility.h"
00065
00066 #endif
00067
00068 #include "constrct.h"
00069 #include "objrtmch.h"
00070 #include "objrtgen.h"
00071 #include "objrtfnx.h"
00072 #include "reorder.h"
00073 #include "router.h"
00074
00075 #if CONSTRUCT_COMPILER && (! RUN_TIME)
00076 #include "objrtcmp.h"
00077 #endif
00078
00079 #if BLOAD_AND_BSAVE || BLOAD || BLOAD_ONLY
00080 #include "objrtbin.h"
00081 #endif
00082
00083 #define _OBJRTBLD_SOURCE_
00084 #include "objrtbld.h"
00085
00086 #if ! DEFINSTANCES_CONSTRUCT
00087 #include "extnfunc.h"
00088 #include "classfun.h"
00089 #include "classcom.h"
00090 #endif
00091
00092 #if (! BLOAD_ONLY) && (! RUN_TIME)
00093
00094
00095
00096
00097
00098
00099 #define OBJECT_PATTERN_INDICATOR "object"
00100
00101
00102
00103
00104
00105
00106
00107 static intBool PatternParserFind(SYMBOL_HN *);
00108 static struct lhsParseNode *ObjectLHSParse(void *,char *,struct token *);
00109 static intBool ReorderAndAnalyzeObjectPattern(void *,struct lhsParseNode *);
00110 static struct patternNodeHeader *PlaceObjectPattern(void *,struct lhsParseNode *);
00111 static OBJECT_PATTERN_NODE *FindObjectPatternNode(OBJECT_PATTERN_NODE *,struct lhsParseNode *,
00112 OBJECT_PATTERN_NODE **,unsigned,unsigned);
00113 static OBJECT_PATTERN_NODE *CreateNewObjectPatternNode(void *,struct lhsParseNode *,OBJECT_PATTERN_NODE *,
00114 OBJECT_PATTERN_NODE *,unsigned,unsigned);
00115 static void DetachObjectPattern(void *,struct patternNodeHeader *);
00116 static void ClearObjectPatternMatches(void *,OBJECT_ALPHA_NODE *);
00117 static void RemoveObjectPartialMatches(void *,INSTANCE_TYPE *,struct patternNodeHeader *);
00118 static intBool CheckDuplicateSlots(void *,struct lhsParseNode *,SYMBOL_HN *);
00119 static struct lhsParseNode *ParseClassRestriction(void *,char *,struct token *);
00120 static struct lhsParseNode *ParseNameRestriction(void *,char *,struct token *);
00121 static struct lhsParseNode *ParseSlotRestriction(void *,char *,struct token *,CONSTRAINT_RECORD *,int);
00122 static CLASS_BITMAP *NewClassBitMap(void *,int,int);
00123 static void InitializeClassBitMap(void *,CLASS_BITMAP *,int);
00124 static void DeleteIntermediateClassBitMap(void *,CLASS_BITMAP *);
00125 static void *CopyClassBitMap(void *,void *);
00126 static void DeleteClassBitMap(void *,void *);
00127 static void MarkBitMapClassesBusy(void *,BITMAP_HN *,int);
00128 static intBool EmptyClassBitMap(CLASS_BITMAP *);
00129 static intBool IdenticalClassBitMap(CLASS_BITMAP *,CLASS_BITMAP *);
00130 static intBool ProcessClassRestriction(void *,CLASS_BITMAP *,struct lhsParseNode **,int);
00131 static CONSTRAINT_RECORD *ProcessSlotRestriction(void *,CLASS_BITMAP *,SYMBOL_HN *,int *);
00132 static void IntersectClassBitMaps(CLASS_BITMAP *,CLASS_BITMAP *);
00133 static void UnionClassBitMaps(CLASS_BITMAP *,CLASS_BITMAP *);
00134 static CLASS_BITMAP *PackClassBitMap(void *,CLASS_BITMAP *);
00135 static struct lhsParseNode *FilterObjectPattern(void *,struct patternParser *,
00136 struct lhsParseNode *,struct lhsParseNode **,
00137 struct lhsParseNode **,struct lhsParseNode **);
00138 static BITMAP_HN *FormSlotBitMap(void *,struct lhsParseNode *);
00139 static struct lhsParseNode *RemoveSlotExistenceTests(void *,struct lhsParseNode *,BITMAP_HN **);
00140 static struct lhsParseNode *CreateInitialObjectPattern(void *);
00141 static EXPRESSION *ObjectMatchDelayParse(void *,EXPRESSION *,char *);
00142 static void MarkObjectPtnIncrementalReset(void *,struct patternNodeHeader *,int);
00143 static void ObjectIncrementalReset(void *);
00144
00145 #endif
00146
00147 #if ! DEFINSTANCES_CONSTRUCT
00148 static void ResetInitialObject(void *);
00149 #endif
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 globle void SetupObjectPatternStuff(
00169 void *theEnv)
00170 {
00171 #if (! BLOAD_ONLY) && (! RUN_TIME)
00172 struct patternParser *newPtr;
00173
00174 if (ReservedPatternSymbol(theEnv,"object",NULL) == TRUE)
00175 {
00176 SystemError(theEnv,"OBJRTBLD",1);
00177 EnvExitRouter(theEnv,EXIT_FAILURE);
00178 }
00179 AddReservedPatternSymbol(theEnv,"object",NULL);
00180
00181
00182
00183
00184
00185
00186 newPtr = get_struct(theEnv,patternParser);
00187
00188 newPtr->name = "objects";
00189 newPtr->priority = 20;
00190 newPtr->entityType = &InstanceData(theEnv)->InstanceInfo;
00191
00192 newPtr->recognizeFunction = PatternParserFind;
00193 newPtr->parseFunction = ObjectLHSParse;
00194 newPtr->postAnalysisFunction = ReorderAndAnalyzeObjectPattern;
00195 newPtr->addPatternFunction = PlaceObjectPattern;
00196 newPtr->removePatternFunction = DetachObjectPattern;
00197 newPtr->genJNConstantFunction = NULL;
00198 newPtr->replaceGetJNValueFunction = ReplaceGetJNObjectValue;
00199 newPtr->genGetJNValueFunction = GenGetJNObjectValue;
00200 newPtr->genCompareJNValuesFunction = ObjectJNVariableComparison;
00201 newPtr->genPNConstantFunction = GenObjectPNConstantCompare;
00202 newPtr->replaceGetPNValueFunction = ReplaceGetPNObjectValue;
00203 newPtr->genGetPNValueFunction = GenGetPNObjectValue;
00204 newPtr->genComparePNValuesFunction = ObjectPNVariableComparison;
00205 newPtr->returnUserDataFunction = DeleteClassBitMap;
00206 newPtr->copyUserDataFunction = CopyClassBitMap;
00207
00208 newPtr->markIRPatternFunction = MarkObjectPtnIncrementalReset;
00209 newPtr->incrementalResetFunction = ObjectIncrementalReset;
00210
00211 newPtr->initialPatternFunction = CreateInitialObjectPattern;
00212
00213 #if CONSTRUCT_COMPILER && (! RUN_TIME)
00214 newPtr->codeReferenceFunction = ObjectPatternNodeReference;
00215 #else
00216 newPtr->codeReferenceFunction = NULL;
00217 #endif
00218
00219 AddPatternParser(theEnv,newPtr);
00220
00221 EnvDefineFunction2(theEnv,"object-pattern-match-delay",'u',
00222 PTIEF ObjectMatchDelay,"ObjectMatchDelay",NULL);
00223
00224 AddFunctionParser(theEnv,"object-pattern-match-delay",ObjectMatchDelayParse);
00225 FuncSeqOvlFlags(theEnv,"object-pattern-match-delay",FALSE,FALSE);
00226
00227 #endif
00228
00229 InstallObjectPrimitives(theEnv);
00230
00231 #if CONSTRUCT_COMPILER && (! RUN_TIME)
00232 ObjectPatternsCompilerSetup(theEnv);
00233 #endif
00234
00235 #if ! DEFINSTANCES_CONSTRUCT
00236 EnvAddResetFunction(theEnv,"reset-initial-object",ResetInitialObject,0);
00237 #endif
00238
00239
00240 #if BLOAD_AND_BSAVE || BLOAD || BLOAD_ONLY
00241 SetupObjectPatternsBload(theEnv);
00242 #endif
00243 }
00244
00245
00246
00247
00248
00249
00250
00251 #if ! DEFINSTANCES_CONSTRUCT
00252
00253 static void ResetInitialObject(
00254 void *theEnv)
00255 {
00256 EXPRESSION *tmp;
00257 DATA_OBJECT rtn;
00258
00259 tmp = GenConstant(theEnv,FCALL,(void *) FindFunction(theEnv,"make-instance"));
00260 tmp->argList = GenConstant(theEnv,INSTANCE_NAME,(void *) DefclassData(theEnv)->INITIAL_OBJECT_SYMBOL);
00261 tmp->argList->nextArg =
00262 GenConstant(theEnv,DEFCLASS_PTR,(void *) LookupDefclassInScope(theEnv,INITIAL_OBJECT_CLASS_NAME));
00263 EvaluateExpression(theEnv,tmp,&rtn);
00264 ReturnExpression(theEnv,tmp);
00265 }
00266
00267 #endif
00268
00269 #if (! BLOAD_ONLY) && (! RUN_TIME)
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 static intBool PatternParserFind(
00284 SYMBOL_HN *value)
00285 {
00286 if (strcmp(ValueToString(value),OBJECT_PATTERN_INDICATOR) == 0)
00287 return(TRUE);
00288
00289 return(FALSE);
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 #if WIN_BTC
00308 #pragma argsused
00309 #endif
00310 static struct lhsParseNode *ObjectLHSParse(
00311 void *theEnv,
00312 char *readSource,
00313 struct token *lastToken)
00314 {
00315 #if MAC_MCW || WIN_MCW || MAC_XCD
00316 #pragma unused(lastToken)
00317 #endif
00318 struct token theToken;
00319 struct lhsParseNode *firstNode = NULL,*lastNode = NULL,*tmpNode;
00320 CLASS_BITMAP *clsset,*tmpset;
00321 CONSTRAINT_RECORD *slotConstraints;
00322 int ppbackupReqd = FALSE,multip;
00323
00324
00325
00326
00327
00328
00329 clsset = NewClassBitMap(theEnv,((int) DefclassData(theEnv)->MaxClassID) - 1,1);
00330 if (EmptyClassBitMap(clsset))
00331 {
00332 PrintErrorID(theEnv,"OBJRTBLD",1,FALSE);
00333 EnvPrintRouter(theEnv,WERROR,"No objects of existing classes can satisfy pattern.\n");
00334 DeleteIntermediateClassBitMap(theEnv,clsset);
00335 return(NULL);
00336 }
00337 tmpset = NewClassBitMap(theEnv,((int) DefclassData(theEnv)->MaxClassID) - 1,1);
00338
00339 IncrementIndentDepth(theEnv,7);
00340
00341
00342
00343
00344 GetToken(theEnv,readSource,&theToken);
00345 while (theToken.type != RPAREN)
00346 {
00347 ppbackupReqd = TRUE;
00348 PPBackup(theEnv);
00349 SavePPBuffer(theEnv," ");
00350 SavePPBuffer(theEnv,theToken.printForm);
00351 if (theToken.type != LPAREN)
00352 {
00353 SyntaxErrorMessage(theEnv,"object pattern");
00354 goto ObjectLHSParseERROR;
00355 }
00356 GetToken(theEnv,readSource,&theToken);
00357 if (theToken.type != SYMBOL)
00358 {
00359 SyntaxErrorMessage(theEnv,"object pattern");
00360 goto ObjectLHSParseERROR;
00361 }
00362 if (CheckDuplicateSlots(theEnv,firstNode,(SYMBOL_HN *) theToken.value))
00363 goto ObjectLHSParseERROR;
00364 if (theToken.value == (void *) DefclassData(theEnv)->ISA_SYMBOL)
00365 {
00366 tmpNode = ParseClassRestriction(theEnv,readSource,&theToken);
00367 if (tmpNode == NULL)
00368 goto ObjectLHSParseERROR;
00369 InitializeClassBitMap(theEnv,tmpset,0);
00370 if (ProcessClassRestriction(theEnv,tmpset,&tmpNode->bottom,TRUE) == FALSE)
00371 {
00372 ReturnLHSParseNodes(theEnv,tmpNode);
00373 goto ObjectLHSParseERROR;
00374 }
00375 IntersectClassBitMaps(clsset,tmpset);
00376 }
00377 else if (theToken.value == (void *) DefclassData(theEnv)->NAME_SYMBOL)
00378 {
00379 tmpNode = ParseNameRestriction(theEnv,readSource,&theToken);
00380 if (tmpNode == NULL)
00381 goto ObjectLHSParseERROR;
00382 InitializeClassBitMap(theEnv,tmpset,1);
00383 }
00384 else
00385 {
00386 slotConstraints = ProcessSlotRestriction(theEnv,clsset,(SYMBOL_HN *) theToken.value,&multip);
00387 if (slotConstraints != NULL)
00388 {
00389 InitializeClassBitMap(theEnv,tmpset,1);
00390 tmpNode = ParseSlotRestriction(theEnv,readSource,&theToken,slotConstraints,multip);
00391 if (tmpNode == NULL)
00392 goto ObjectLHSParseERROR;
00393 }
00394 else
00395 {
00396 InitializeClassBitMap(theEnv,tmpset,0);
00397 tmpNode = GetLHSParseNode(theEnv);
00398 tmpNode->slot = (SYMBOL_HN *) theToken.value;
00399 }
00400 }
00401 if (EmptyClassBitMap(tmpset))
00402 {
00403 PrintErrorID(theEnv,"OBJRTBLD",2,FALSE);
00404 EnvPrintRouter(theEnv,WERROR,"No objects of existing classes can satisfy ");
00405 EnvPrintRouter(theEnv,WERROR,ValueToString(tmpNode->slot));
00406 EnvPrintRouter(theEnv,WERROR," restriction in object pattern.\n");
00407 ReturnLHSParseNodes(theEnv,tmpNode);
00408 goto ObjectLHSParseERROR;
00409 }
00410 if (EmptyClassBitMap(clsset))
00411 {
00412 PrintErrorID(theEnv,"OBJRTBLD",1,FALSE);
00413 EnvPrintRouter(theEnv,WERROR,"No objects of existing classes can satisfy pattern.\n");
00414 ReturnLHSParseNodes(theEnv,tmpNode);
00415 goto ObjectLHSParseERROR;
00416 }
00417 if (tmpNode != NULL)
00418 {
00419 if (firstNode == NULL)
00420 firstNode = tmpNode;
00421 else
00422 lastNode->right = tmpNode;
00423 lastNode = tmpNode;
00424 }
00425 PPCRAndIndent(theEnv);
00426 GetToken(theEnv,readSource,&theToken);
00427 }
00428 if (firstNode == NULL)
00429 {
00430 if (EmptyClassBitMap(clsset))
00431 {
00432 PrintErrorID(theEnv,"OBJRTBLD",1,FALSE);
00433 EnvPrintRouter(theEnv,WERROR,"No objects of existing classes can satisfy pattern.\n");
00434 goto ObjectLHSParseERROR;
00435 }
00436 firstNode = GetLHSParseNode(theEnv);
00437 firstNode->type = SF_WILDCARD;
00438 firstNode->slot = DefclassData(theEnv)->ISA_SYMBOL;
00439 firstNode->slotNumber = ISA_ID;
00440 firstNode->index = 1;
00441 }
00442 if (ppbackupReqd)
00443 {
00444 PPBackup(theEnv);
00445 PPBackup(theEnv);
00446 SavePPBuffer(theEnv,theToken.printForm);
00447 }
00448 DeleteIntermediateClassBitMap(theEnv,tmpset);
00449 clsset = PackClassBitMap(theEnv,clsset);
00450 firstNode->userData = EnvAddBitMap(theEnv,(void *) clsset,ClassBitMapSize(clsset));
00451 IncrementBitMapCount(firstNode->userData);
00452 DeleteIntermediateClassBitMap(theEnv,clsset);
00453 DecrementIndentDepth(theEnv,7);
00454 return(firstNode);
00455
00456 ObjectLHSParseERROR:
00457 DeleteIntermediateClassBitMap(theEnv,clsset);
00458 DeleteIntermediateClassBitMap(theEnv,tmpset);
00459 ReturnLHSParseNodes(theEnv,firstNode);
00460 DecrementIndentDepth(theEnv,7);
00461 return(NULL);
00462 }
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 static intBool ReorderAndAnalyzeObjectPattern(
00486 void *theEnv,
00487 struct lhsParseNode *topNode)
00488 {
00489 CLASS_BITMAP *clsset,*tmpset;
00490 EXPRESSION *rexp,*tmpmin,*tmpmax;
00491 DEFCLASS *cls;
00492 struct lhsParseNode *tmpNode,*subNode,*bitmap_node,*isa_node,*name_node;
00493 register unsigned short i;
00494 SLOT_DESC *sd;
00495 CONSTRAINT_RECORD *crossConstraints, *theConstraint;
00496 int incompatibleConstraint,clssetChanged = FALSE;
00497
00498
00499
00500
00501
00502
00503
00504 topNode->right = FilterObjectPattern(theEnv,topNode->patternType,topNode->right,
00505 &bitmap_node,&isa_node,&name_node);
00506 if (EnvGetStaticConstraintChecking(theEnv) == FALSE)
00507 return(FALSE);
00508
00509
00510
00511
00512 clsset = (CLASS_BITMAP *) ValueToBitMap(bitmap_node->userData);
00513 tmpset = NewClassBitMap(theEnv,(int) clsset->maxid,0);
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523 if ((isa_node == NULL) ? FALSE :
00524 ((isa_node->constraints == NULL) ? FALSE :
00525 (isa_node->constraints->restrictionList != NULL)))
00526 {
00527 rexp = isa_node->constraints->restrictionList;
00528 while (rexp != NULL)
00529 {
00530 cls = LookupDefclassInScope(theEnv,ValueToString(rexp->value));
00531 if (cls != NULL)
00532 {
00533 if ((cls->id <= (unsigned) clsset->maxid) ? TestBitMap(clsset->map,cls->id) : FALSE)
00534 SetBitMap(tmpset->map,cls->id);
00535 }
00536 rexp = rexp->nextArg;
00537 }
00538 clssetChanged = IdenticalClassBitMap(tmpset,clsset) ? FALSE : TRUE;
00539 }
00540 else
00541 GenCopyMemory(char,tmpset->maxid / BITS_PER_BYTE + 1,tmpset->map,clsset->map);
00542
00543
00544
00545
00546
00547
00548
00549
00550 tmpNode = topNode->right;
00551 while (tmpNode != bitmap_node)
00552 {
00553 if ((tmpNode == isa_node) || (tmpNode == name_node))
00554 {
00555 tmpNode = tmpNode->right;
00556 continue;
00557 }
00558 for (i = 0 ; i <= tmpset->maxid ; i++)
00559 if (TestBitMap(tmpset->map,i))
00560 {
00561 cls = DefclassData(theEnv)->ClassIDMap[i];
00562 sd = cls->instanceTemplate[FindInstanceTemplateSlot(theEnv,cls,tmpNode->slot)];
00563
00564
00565
00566
00567
00568 crossConstraints = IntersectConstraints(theEnv,tmpNode->constraints,sd->constraint);
00569 incompatibleConstraint = UnmatchableConstraint(crossConstraints);
00570 RemoveConstraint(theEnv,crossConstraints);
00571 if (incompatibleConstraint)
00572 {
00573 ClearBitMap(tmpset->map,i);
00574 clssetChanged = TRUE;
00575 }
00576 else if (tmpNode->type == MF_WILDCARD)
00577 {
00578
00579
00580
00581 for (subNode = tmpNode->bottom ; subNode != NULL ; subNode = subNode->right)
00582 {
00583
00584
00585
00586
00587 if ((subNode->type == MF_WILDCARD) || (subNode->type == MF_VARIABLE))
00588 { theConstraint = subNode->constraints->multifield; }
00589 else
00590 { theConstraint = subNode->constraints; }
00591
00592 tmpmin = theConstraint->minFields;
00593 theConstraint->minFields = sd->constraint->minFields;
00594 tmpmax = theConstraint->maxFields;
00595 theConstraint->maxFields = sd->constraint->maxFields;
00596 crossConstraints = IntersectConstraints(theEnv,theConstraint,sd->constraint);
00597 theConstraint->minFields = tmpmin;
00598 theConstraint->maxFields = tmpmax;
00599
00600 incompatibleConstraint = UnmatchableConstraint(crossConstraints);
00601 RemoveConstraint(theEnv,crossConstraints);
00602 if (incompatibleConstraint)
00603 {
00604 ClearBitMap(tmpset->map,i);
00605 clssetChanged = TRUE;
00606 break;
00607 }
00608 }
00609 }
00610 }
00611 tmpNode = tmpNode->right;
00612 }
00613
00614 if (clssetChanged)
00615 {
00616
00617
00618
00619
00620 if (EmptyClassBitMap(tmpset))
00621 {
00622 PrintErrorID(theEnv,"OBJRTBLD",3,TRUE);
00623 DeleteIntermediateClassBitMap(theEnv,tmpset);
00624 EnvPrintRouter(theEnv,WERROR,"No objects of existing classes can satisfy pattern #");
00625 PrintLongInteger(theEnv,WERROR,(long long) topNode->pattern);
00626 EnvPrintRouter(theEnv,WERROR,".\n");
00627 return(TRUE);
00628 }
00629 clsset = PackClassBitMap(theEnv,tmpset);
00630 DeleteClassBitMap(theEnv,(void *) bitmap_node->userData);
00631 bitmap_node->userData = EnvAddBitMap(theEnv,(void *) clsset,ClassBitMapSize(clsset));
00632 IncrementBitMapCount(bitmap_node->userData);
00633 DeleteIntermediateClassBitMap(theEnv,clsset);
00634 }
00635 else
00636 DeleteIntermediateClassBitMap(theEnv,tmpset);
00637 return(FALSE);
00638 }
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650 static struct patternNodeHeader *PlaceObjectPattern(
00651 void *theEnv,
00652 struct lhsParseNode *thePattern)
00653 {
00654 OBJECT_PATTERN_NODE *currentLevel,*lastLevel;
00655 struct lhsParseNode *tempPattern = NULL;
00656 OBJECT_PATTERN_NODE *nodeSlotGroup, *newNode;
00657 OBJECT_ALPHA_NODE *newAlphaNode;
00658 unsigned endSlot;
00659 BITMAP_HN *newClassBitMap,*newSlotBitMap;
00660 struct expr *rightHash;
00661
00662
00663
00664
00665
00666
00667 currentLevel = ObjectNetworkPointer(theEnv);
00668 lastLevel = NULL;
00669
00670
00671
00672
00673
00674
00675
00676 rightHash = thePattern->rightHash;
00677
00678 newSlotBitMap = FormSlotBitMap(theEnv,thePattern->right);
00679 thePattern->right = RemoveSlotExistenceTests(theEnv,thePattern->right,&newClassBitMap);
00680 thePattern = thePattern->right;
00681
00682
00683
00684
00685
00686
00687
00688 do
00689 {
00690 if (thePattern->multifieldSlot)
00691 {
00692 tempPattern = thePattern;
00693 thePattern = thePattern->bottom;
00694 }
00695
00696
00697
00698
00699
00700
00701 if (((thePattern->type == MF_WILDCARD) ||
00702 (thePattern->type == MF_VARIABLE)) &&
00703 (thePattern->right == NULL) && (tempPattern != NULL))
00704 { endSlot = TRUE; }
00705 else
00706 { endSlot = FALSE; }
00707
00708
00709
00710
00711
00712
00713 newNode = FindObjectPatternNode(currentLevel,thePattern,&nodeSlotGroup,endSlot,FALSE);
00714
00715
00716
00717
00718
00719
00720 if (newNode == NULL)
00721 { newNode = CreateNewObjectPatternNode(theEnv,thePattern,nodeSlotGroup,lastLevel,endSlot,FALSE); }
00722
00723 if (thePattern->constantSelector != NULL)
00724 {
00725 currentLevel = newNode->nextLevel;
00726 lastLevel = newNode;
00727 newNode = FindObjectPatternNode(currentLevel,thePattern,&nodeSlotGroup,endSlot,TRUE);
00728
00729 if (newNode == NULL)
00730 { newNode = CreateNewObjectPatternNode(theEnv,thePattern,nodeSlotGroup,lastLevel,endSlot,TRUE); }
00731 }
00732
00733
00734
00735
00736
00737 if ((thePattern->right == NULL) && (tempPattern != NULL))
00738 {
00739 thePattern = tempPattern;
00740 tempPattern = NULL;
00741 }
00742
00743 lastLevel = newNode;
00744 currentLevel = newNode->nextLevel;
00745 thePattern = thePattern->right;
00746 }
00747 while ((thePattern != NULL) ? (thePattern->userData == NULL) : FALSE);
00748
00749
00750
00751
00752
00753 newAlphaNode = lastLevel->alphaNode;
00754 while (newAlphaNode != NULL)
00755 {
00756 if ((newClassBitMap == newAlphaNode->classbmp) &&
00757 (newSlotBitMap == newAlphaNode->slotbmp) &&
00758 IdenticalExpression(newAlphaNode->header.rightHash,rightHash))
00759 return((struct patternNodeHeader *) newAlphaNode);
00760 newAlphaNode = newAlphaNode->nxtInGroup;
00761 }
00762
00763 newAlphaNode = get_struct(theEnv,objectAlphaNode);
00764 InitializePatternHeader(theEnv,&newAlphaNode->header);
00765 newAlphaNode->header.rightHash = AddHashedExpression(theEnv,rightHash);
00766 newAlphaNode->matchTimeTag = 0L;
00767 newAlphaNode->patternNode = lastLevel;
00768 newAlphaNode->classbmp = newClassBitMap;
00769 IncrementBitMapCount(newClassBitMap);
00770 MarkBitMapClassesBusy(theEnv,newClassBitMap,1);
00771 newAlphaNode->slotbmp = newSlotBitMap;
00772 if (newSlotBitMap != NULL)
00773 IncrementBitMapCount(newSlotBitMap);
00774 newAlphaNode->bsaveID = 0L;
00775 newAlphaNode->nxtInGroup = lastLevel->alphaNode;
00776 lastLevel->alphaNode = newAlphaNode;
00777 newAlphaNode->nxtTerminal = ObjectNetworkTerminalPointer(theEnv);
00778 SetObjectNetworkTerminalPointer(theEnv,newAlphaNode);
00779 return((struct patternNodeHeader *) newAlphaNode);
00780 }
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801 static OBJECT_PATTERN_NODE *FindObjectPatternNode(
00802 OBJECT_PATTERN_NODE *listOfNodes,
00803 struct lhsParseNode *thePattern,
00804 OBJECT_PATTERN_NODE **nodeSlotGroup,
00805 unsigned endSlot,
00806 unsigned constantSelector)
00807 {
00808 struct expr *compareTest;
00809 *nodeSlotGroup = NULL;
00810
00811 if (constantSelector)
00812 { compareTest = thePattern->constantValue; }
00813 else if (thePattern->constantSelector != NULL)
00814 { compareTest = thePattern->constantSelector; }
00815 else
00816 { compareTest = thePattern->networkTest; }
00817
00818
00819
00820
00821
00822
00823 while (listOfNodes != NULL)
00824 {
00825
00826
00827
00828
00829
00830
00831 if (((thePattern->type == MF_WILDCARD) || (thePattern->type == MF_VARIABLE)) ?
00832 listOfNodes->multifieldNode : (listOfNodes->multifieldNode == 0))
00833 {
00834 if ((thePattern->slotNumber == (int) listOfNodes->slotNameID) &&
00835 (thePattern->index == (int) listOfNodes->whichField) &&
00836 (thePattern->singleFieldsAfter == listOfNodes->leaveFields) &&
00837 (endSlot == listOfNodes->endSlot) &&
00838 IdenticalExpression(listOfNodes->networkTest,compareTest))
00839 return(listOfNodes);
00840 }
00841
00842
00843
00844
00845
00846
00847 if ((*nodeSlotGroup == NULL) &&
00848 (thePattern->index == (int) listOfNodes->whichField) &&
00849 (thePattern->slotNumber == (int) listOfNodes->slotNameID))
00850 *nodeSlotGroup = listOfNodes;
00851 listOfNodes = listOfNodes->rightNode;
00852 }
00853
00854
00855
00856
00857
00858 return(NULL);
00859 }
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878 static OBJECT_PATTERN_NODE *CreateNewObjectPatternNode(
00879 void *theEnv,
00880 struct lhsParseNode *thePattern,
00881 OBJECT_PATTERN_NODE *nodeSlotGroup,
00882 OBJECT_PATTERN_NODE *upperLevel,
00883 unsigned endSlot,
00884 unsigned constantSelector)
00885 {
00886 OBJECT_PATTERN_NODE *newNode,*prvNode,*curNode;
00887
00888 newNode = get_struct(theEnv,objectPatternNode);
00889 newNode->blocked = FALSE;
00890 newNode->multifieldNode = FALSE;
00891 newNode->alphaNode = NULL;
00892 newNode->matchTimeTag = 0L;
00893 newNode->nextLevel = NULL;
00894 newNode->rightNode = NULL;
00895 newNode->leftNode = NULL;
00896 newNode->bsaveID = 0L;
00897
00898 if ((thePattern->constantSelector != NULL) && (! constantSelector))
00899 { newNode->selector = TRUE; }
00900 else
00901 { newNode->selector = FALSE; }
00902
00903
00904
00905
00906
00907 if (constantSelector)
00908 { newNode->networkTest = AddHashedExpression(theEnv,thePattern->constantValue); }
00909 else if (thePattern->constantSelector != NULL)
00910 { newNode->networkTest = AddHashedExpression(theEnv,thePattern->constantSelector); }
00911 else
00912 { newNode->networkTest = AddHashedExpression(theEnv,thePattern->networkTest); }
00913
00914 newNode->whichField = thePattern->index;
00915 newNode->leaveFields = thePattern->singleFieldsAfter;
00916
00917
00918
00919
00920
00921 newNode->slotNameID = (unsigned) thePattern->slotNumber;
00922 if ((thePattern->type == MF_WILDCARD) || (thePattern->type == MF_VARIABLE))
00923 newNode->multifieldNode = TRUE;
00924 newNode->endSlot = endSlot;
00925
00926
00927
00928
00929
00930 newNode->lastLevel = upperLevel;
00931
00932 if ((upperLevel != NULL) && (upperLevel->selector))
00933 { AddHashedPatternNode(theEnv,upperLevel,newNode,newNode->networkTest->type,newNode->networkTest->value); }
00934
00935
00936
00937
00938
00939
00940 if (nodeSlotGroup == NULL)
00941 {
00942 if (upperLevel == NULL)
00943 {
00944 newNode->rightNode = ObjectNetworkPointer(theEnv);
00945 SetObjectNetworkPointer(theEnv,newNode);
00946 }
00947 else
00948 {
00949 newNode->rightNode = upperLevel->nextLevel;
00950 upperLevel->nextLevel = newNode;
00951 }
00952 if (newNode->rightNode != NULL)
00953 newNode->rightNode->leftNode = newNode;
00954 return(newNode);
00955 }
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967 prvNode = NULL;
00968 curNode = nodeSlotGroup;
00969 while ((curNode == NULL) ? FALSE :
00970 (curNode->slotNameID == nodeSlotGroup->slotNameID) &&
00971 (curNode->whichField == nodeSlotGroup->whichField))
00972 {
00973 if ((curNode->networkTest == NULL) ? FALSE :
00974 ((curNode->networkTest->type != OBJ_PN_CONSTANT) ? FALSE :
00975 ((struct ObjectCmpPNConstant *) ValueToBitMap(curNode->networkTest->value))->pass))
00976 break;
00977 prvNode = curNode;
00978 curNode = curNode->rightNode;
00979 }
00980 if (curNode != NULL)
00981 {
00982 newNode->leftNode = curNode->leftNode;
00983 newNode->rightNode = curNode;
00984 if (curNode->leftNode != NULL)
00985 curNode->leftNode->rightNode = newNode;
00986 else if (curNode->lastLevel != NULL)
00987 curNode->lastLevel->nextLevel = newNode;
00988 else
00989 SetObjectNetworkPointer(theEnv,newNode);
00990 curNode->leftNode = newNode;
00991 }
00992 else
00993 {
00994 newNode->leftNode = prvNode;
00995 prvNode->rightNode = newNode;
00996 }
00997
00998 return(newNode);
00999 }
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034 static void DetachObjectPattern(
01035 void *theEnv,
01036 struct patternNodeHeader *thePattern)
01037 {
01038 OBJECT_ALPHA_NODE *alphaPtr,*prv,*terminalPtr;
01039 OBJECT_PATTERN_NODE *patternPtr,*upperLevel;
01040
01041
01042
01043
01044
01045 alphaPtr = (OBJECT_ALPHA_NODE *) thePattern;
01046 ClearObjectPatternMatches(theEnv,alphaPtr);
01047
01048
01049
01050
01051
01052
01053
01054 MarkBitMapClassesBusy(theEnv,alphaPtr->classbmp,-1);
01055 DeleteClassBitMap(theEnv,alphaPtr->classbmp);
01056 if (alphaPtr->slotbmp != NULL)
01057 { DecrementBitMapCount(theEnv,alphaPtr->slotbmp); }
01058
01059
01060
01061
01062
01063
01064 prv = NULL;
01065 terminalPtr = ObjectNetworkTerminalPointer(theEnv);
01066 while (terminalPtr != alphaPtr)
01067 {
01068 prv = terminalPtr;
01069 terminalPtr = terminalPtr->nxtTerminal;
01070 }
01071
01072 if (prv == NULL)
01073 { SetObjectNetworkTerminalPointer(theEnv,terminalPtr->nxtTerminal); }
01074 else
01075 { prv->nxtTerminal = terminalPtr->nxtTerminal; }
01076
01077 prv = NULL;
01078 terminalPtr = alphaPtr->patternNode->alphaNode;
01079 while (terminalPtr != alphaPtr)
01080 {
01081 prv = terminalPtr;
01082 terminalPtr = terminalPtr->nxtInGroup;
01083 }
01084
01085 if (prv == NULL)
01086 {
01087 if (alphaPtr->nxtInGroup != NULL)
01088 {
01089 alphaPtr->patternNode->alphaNode = alphaPtr->nxtInGroup;
01090 RemoveHashedExpression(theEnv,alphaPtr->header.rightHash);
01091 rtn_struct(theEnv,objectAlphaNode,alphaPtr);
01092 return;
01093 }
01094 }
01095 else
01096 {
01097 prv->nxtInGroup = alphaPtr->nxtInGroup;
01098 RemoveHashedExpression(theEnv,alphaPtr->header.rightHash);
01099 rtn_struct(theEnv,objectAlphaNode,alphaPtr);
01100 return;
01101 }
01102 alphaPtr->patternNode->alphaNode = NULL;
01103 RemoveHashedExpression(theEnv,alphaPtr->header.rightHash);
01104 rtn_struct(theEnv,objectAlphaNode,alphaPtr);
01105
01106 upperLevel = alphaPtr->patternNode;
01107 if (upperLevel->nextLevel != NULL)
01108 return;
01109
01110
01111
01112
01113
01114 while (upperLevel != NULL)
01115 {
01116 if ((upperLevel->leftNode == NULL) &&
01117 (upperLevel->rightNode == NULL))
01118 {
01119
01120
01121
01122
01123
01124
01125
01126 patternPtr = upperLevel;
01127 upperLevel = patternPtr->lastLevel;
01128
01129 if (upperLevel == NULL)
01130 SetObjectNetworkPointer(theEnv,NULL);
01131 else
01132 {
01133 if (upperLevel->selector)
01134 { RemoveHashedPatternNode(theEnv,upperLevel,patternPtr,patternPtr->networkTest->type,patternPtr->networkTest->value); }
01135
01136 upperLevel->nextLevel = NULL;
01137 if (upperLevel->alphaNode != NULL)
01138 upperLevel = NULL;
01139 }
01140
01141 RemoveHashedExpression(theEnv,(EXPRESSION *) patternPtr->networkTest);
01142 rtn_struct(theEnv,objectPatternNode,patternPtr);
01143 }
01144 else if (upperLevel->leftNode != NULL)
01145 {
01146
01147
01148
01149
01150
01151
01152 patternPtr = upperLevel;
01153
01154 if ((patternPtr->lastLevel != NULL) &&
01155 (patternPtr->lastLevel->selector))
01156 { RemoveHashedPatternNode(theEnv,patternPtr->lastLevel,patternPtr,patternPtr->networkTest->type,patternPtr->networkTest->value); }
01157
01158 upperLevel->leftNode->rightNode = upperLevel->rightNode;
01159 if (upperLevel->rightNode != NULL)
01160 { upperLevel->rightNode->leftNode = upperLevel->leftNode; }
01161
01162 RemoveHashedExpression(theEnv,(EXPRESSION *) patternPtr->networkTest);
01163 rtn_struct(theEnv,objectPatternNode,patternPtr);
01164 upperLevel = NULL;
01165 }
01166 else
01167 {
01168
01169
01170
01171
01172
01173
01174 patternPtr = upperLevel;
01175 upperLevel = upperLevel->lastLevel;
01176 if (upperLevel == NULL)
01177 { SetObjectNetworkPointer(theEnv,patternPtr->rightNode); }
01178 else
01179 {
01180 if (upperLevel->selector)
01181 { RemoveHashedPatternNode(theEnv,upperLevel,patternPtr,patternPtr->networkTest->type,patternPtr->networkTest->value); }
01182
01183 upperLevel->nextLevel = patternPtr->rightNode;
01184 }
01185 patternPtr->rightNode->leftNode = NULL;
01186
01187 RemoveHashedExpression(theEnv,(EXPRESSION *) patternPtr->networkTest);
01188 rtn_struct(theEnv,objectPatternNode,patternPtr);
01189 upperLevel = NULL;
01190 }
01191 }
01192 }
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206 static void ClearObjectPatternMatches(
01207 void *theEnv,
01208 OBJECT_ALPHA_NODE *alphaPtr)
01209 {
01210 INSTANCE_TYPE *ins;
01211 IGARBAGE *igrb;
01212
01213
01214
01215
01216 ins = InstanceData(theEnv)->InstanceList;
01217 while (ins != NULL)
01218 {
01219 RemoveObjectPartialMatches(theEnv,(INSTANCE_TYPE *) ins,(struct patternNodeHeader *) alphaPtr);
01220 ins = ins->nxtList;
01221 }
01222
01223
01224
01225
01226 igrb = InstanceData(theEnv)->InstanceGarbageList;
01227 while (igrb != NULL)
01228 {
01229 RemoveObjectPartialMatches(theEnv,(INSTANCE_TYPE *) igrb->ins,(struct patternNodeHeader *) alphaPtr);
01230 igrb = igrb->nxt;
01231 }
01232 }
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246 static void RemoveObjectPartialMatches(
01247 void *theEnv,
01248 INSTANCE_TYPE *ins,
01249 struct patternNodeHeader *phead)
01250 {
01251 struct patternMatch *match_before, *match_ptr;
01252
01253 match_before = NULL;
01254 match_ptr = (struct patternMatch *) ins->partialMatchList;
01255
01256
01257
01258
01259 while (match_ptr != NULL)
01260 {
01261 if (match_ptr->matchingPattern == phead)
01262 {
01263 ins->busy--;
01264 if (match_before == NULL)
01265 {
01266 ins->partialMatchList = (void *) match_ptr->next;
01267 rtn_struct(theEnv,patternMatch,match_ptr);
01268 match_ptr = (struct patternMatch *) ins->partialMatchList;
01269 }
01270 else
01271 {
01272 match_before->next = match_ptr->next;
01273 rtn_struct(theEnv,patternMatch,match_ptr);
01274 match_ptr = match_before->next;
01275 }
01276 }
01277 else
01278 {
01279 match_before = match_ptr;
01280 match_ptr = match_ptr->next;
01281 }
01282 }
01283 }
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296 static intBool CheckDuplicateSlots(
01297 void *theEnv,
01298 struct lhsParseNode *nodeList,
01299 SYMBOL_HN *slotName)
01300 {
01301 while (nodeList != NULL)
01302 {
01303 if (nodeList->slot == slotName)
01304 {
01305 PrintErrorID(theEnv,"OBJRTBLD",4,TRUE);
01306 EnvPrintRouter(theEnv,WERROR,"Multiple restrictions on attribute ");
01307 EnvPrintRouter(theEnv,WERROR,ValueToString(slotName));
01308 EnvPrintRouter(theEnv,WERROR," not allowed.\n");
01309 return(TRUE);
01310 }
01311 nodeList = nodeList->right;
01312 }
01313 return(FALSE);
01314 }
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328 static struct lhsParseNode *ParseClassRestriction(
01329 void *theEnv,
01330 char *readSource,
01331 struct token *theToken)
01332 {
01333 struct lhsParseNode *tmpNode;
01334 SYMBOL_HN *rln;
01335 CONSTRAINT_RECORD *rv;
01336
01337 rv = GetConstraintRecord(theEnv);
01338 rv->anyAllowed = 0;
01339 rv->symbolsAllowed = 1;
01340 rln = (SYMBOL_HN *) theToken->value;
01341 SavePPBuffer(theEnv," ");
01342 GetToken(theEnv,readSource,theToken);
01343 tmpNode = RestrictionParse(theEnv,readSource,theToken,FALSE,rln,ISA_ID,rv,0);
01344 if (tmpNode == NULL)
01345 {
01346 RemoveConstraint(theEnv,rv);
01347 return(NULL);
01348 }
01349 if ((theToken->type != RPAREN) ||
01350 (tmpNode->type == MF_WILDCARD) ||
01351 (tmpNode->type == MF_VARIABLE))
01352 {
01353 PPBackup(theEnv);
01354 if (theToken->type != RPAREN)
01355 {
01356 SavePPBuffer(theEnv," ");
01357 SavePPBuffer(theEnv,theToken->printForm);
01358 }
01359 SyntaxErrorMessage(theEnv,"class restriction in object pattern");
01360 ReturnLHSParseNodes(theEnv,tmpNode);
01361 RemoveConstraint(theEnv,rv);
01362 return(NULL);
01363 }
01364 tmpNode->derivedConstraints = 1;
01365 return(tmpNode);
01366 }
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380 static struct lhsParseNode *ParseNameRestriction(
01381 void *theEnv,
01382 char *readSource,
01383 struct token *theToken)
01384 {
01385 struct lhsParseNode *tmpNode;
01386 SYMBOL_HN *rln;
01387 CONSTRAINT_RECORD *rv;
01388
01389 rv = GetConstraintRecord(theEnv);
01390 rv->anyAllowed = 0;
01391 rv->instanceNamesAllowed = 1;
01392 rln = (SYMBOL_HN *) theToken->value;
01393 SavePPBuffer(theEnv," ");
01394 GetToken(theEnv,readSource,theToken);
01395 tmpNode = RestrictionParse(theEnv,readSource,theToken,FALSE,rln,NAME_ID,rv,0);
01396 if (tmpNode == NULL)
01397 {
01398 RemoveConstraint(theEnv,rv);
01399 return(NULL);
01400 }
01401 if ((theToken->type != RPAREN) ||
01402 (tmpNode->type == MF_WILDCARD) ||
01403 (tmpNode->type == MF_VARIABLE))
01404 {
01405 PPBackup(theEnv);
01406 if (theToken->type != RPAREN)
01407 {
01408 SavePPBuffer(theEnv," ");
01409 SavePPBuffer(theEnv,theToken->printForm);
01410 }
01411 SyntaxErrorMessage(theEnv,"name restriction in object pattern");
01412 ReturnLHSParseNodes(theEnv,tmpNode);
01413 RemoveConstraint(theEnv,rv);
01414 return(NULL);
01415 }
01416
01417 tmpNode->derivedConstraints = 1;
01418 return(tmpNode);
01419 }
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440 static struct lhsParseNode *ParseSlotRestriction(
01441 void *theEnv,
01442 char *readSource,
01443 struct token *theToken,
01444 CONSTRAINT_RECORD *slotConstraints,
01445 int multip)
01446 {
01447 struct lhsParseNode *tmpNode;
01448 SYMBOL_HN *slotName;
01449
01450 slotName = (SYMBOL_HN *) theToken->value;
01451 SavePPBuffer(theEnv," ");
01452 GetToken(theEnv,readSource,theToken);
01453 tmpNode = RestrictionParse(theEnv,readSource,theToken,multip,slotName,FindSlotNameID(theEnv,slotName),
01454 slotConstraints,1);
01455 if (tmpNode == NULL)
01456 {
01457 RemoveConstraint(theEnv,slotConstraints);
01458 return(NULL);
01459 }
01460 if (theToken->type != RPAREN)
01461 {
01462 PPBackup(theEnv);
01463 SavePPBuffer(theEnv," ");
01464 SavePPBuffer(theEnv,theToken->printForm);
01465 SyntaxErrorMessage(theEnv,"object slot pattern");
01466 ReturnLHSParseNodes(theEnv,tmpNode);
01467 RemoveConstraint(theEnv,slotConstraints);
01468 return(NULL);
01469 }
01470 if ((tmpNode->bottom == NULL) && (tmpNode->multifieldSlot))
01471 {
01472 PPBackup(theEnv);
01473 PPBackup(theEnv);
01474 SavePPBuffer(theEnv,")");
01475 }
01476 tmpNode->derivedConstraints = 1;
01477 return(tmpNode);
01478 }
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494 static CLASS_BITMAP *NewClassBitMap(
01495 void *theEnv,
01496 int maxid,
01497 int set)
01498 {
01499 register CLASS_BITMAP *bmp;
01500 unsigned size;
01501
01502 if (maxid == -1)
01503 maxid = 0;
01504 size = sizeof(CLASS_BITMAP) +
01505 (sizeof(char) * (maxid / BITS_PER_BYTE));
01506 bmp = (CLASS_BITMAP *) gm2(theEnv,size);
01507 ClearBitString((void *) bmp,size);
01508 bmp->maxid = (unsigned short) maxid;
01509 InitializeClassBitMap(theEnv,bmp,set);
01510 return(bmp);
01511 }
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523 static void InitializeClassBitMap(
01524 void *theEnv,
01525 CLASS_BITMAP *bmp,
01526 int set)
01527 {
01528 register int i,bytes;
01529 DEFCLASS *cls;
01530 struct defmodule *currentModule;
01531
01532 bytes = bmp->maxid / BITS_PER_BYTE + 1;
01533 while (bytes > 0)
01534 {
01535 bmp->map[bytes - 1] = (char) 0;
01536 bytes--;
01537 }
01538 if (set)
01539 {
01540 currentModule = ((struct defmodule *) EnvGetCurrentModule(theEnv));
01541 for (i = 0 ; i <= (int) bmp->maxid ; i++)
01542 {
01543 cls = DefclassData(theEnv)->ClassIDMap[i];
01544 if ((cls != NULL) ? DefclassInScope(theEnv,cls,currentModule) : FALSE)
01545 {
01546 if (cls->reactive && (cls->abstract == 0))
01547 SetBitMap(bmp->map,i);
01548 }
01549 }
01550 }
01551 }
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561 static void DeleteIntermediateClassBitMap(
01562 void *theEnv,
01563 CLASS_BITMAP *bmp)
01564 {
01565 rm(theEnv,(void *) bmp,ClassBitMapSize(bmp));
01566 }
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580 #if WIN_BTC
01581 #pragma argsused
01582 #endif
01583 static void *CopyClassBitMap(
01584 void *theEnv,
01585 void *gset)
01586 {
01587 #if MAC_MCW || WIN_MCW || MAC_XCD
01588 #pragma unused(theEnv)
01589 #endif
01590
01591 if (gset != NULL)
01592 IncrementBitMapCount(gset);
01593 return(gset);
01594 }
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606 static void DeleteClassBitMap(
01607 void *theEnv,
01608 void *gset)
01609 {
01610 if (gset == NULL)
01611 return;
01612 DecrementBitMapCount(theEnv,(BITMAP_HN *) gset);
01613 }
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626 static void MarkBitMapClassesBusy(
01627 void *theEnv,
01628 BITMAP_HN *bmphn,
01629 int offset)
01630 {
01631 register CLASS_BITMAP *bmp;
01632 register unsigned short i;
01633 register DEFCLASS *cls;
01634
01635
01636
01637
01638
01639 if (ConstructData(theEnv)->ClearInProgress)
01640 return;
01641 bmp = (CLASS_BITMAP *) ValueToBitMap(bmphn);
01642 for (i = 0 ; i <= bmp->maxid ; i++)
01643 if (TestBitMap(bmp->map,i))
01644 {
01645 cls = DefclassData(theEnv)->ClassIDMap[i];
01646 cls->busy += (unsigned int) offset;
01647 }
01648 }
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660 static intBool EmptyClassBitMap(
01661 CLASS_BITMAP *bmp)
01662 {
01663 register unsigned short bytes;
01664
01665 bytes = (unsigned short) (bmp->maxid / BITS_PER_BYTE + 1);
01666 while (bytes > 0)
01667 {
01668 if (bmp->map[bytes - 1] != (char) 0)
01669 return(FALSE);
01670 bytes--;
01671 }
01672 return(TRUE);
01673 }
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686 static intBool IdenticalClassBitMap(
01687 CLASS_BITMAP *cs1,
01688 CLASS_BITMAP *cs2)
01689 {
01690 register int i;
01691
01692 if (cs1->maxid != cs2->maxid)
01693 return(FALSE);
01694 for (i = 0 ; i < (int) (cs1->maxid / BITS_PER_BYTE + 1) ; i++)
01695 if (cs1->map[i] != cs2->map[i])
01696 return(FALSE);
01697 return(TRUE);
01698 }
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714 static intBool ProcessClassRestriction(
01715 void *theEnv,
01716 CLASS_BITMAP *clsset,
01717 struct lhsParseNode **classRestrictions,
01718 int recursiveCall)
01719 {
01720 register struct lhsParseNode *chk,**oraddr;
01721 CLASS_BITMAP *tmpset1,*tmpset2;
01722 int constant_restriction = TRUE;
01723
01724 if (*classRestrictions == NULL)
01725 {
01726 if (recursiveCall)
01727 InitializeClassBitMap(theEnv,clsset,1);
01728 return(TRUE);
01729 }
01730
01731
01732
01733
01734
01735
01736
01737 tmpset1 = NewClassBitMap(theEnv,((int) DefclassData(theEnv)->MaxClassID) - 1,1);
01738 tmpset2 = NewClassBitMap(theEnv,((int) DefclassData(theEnv)->MaxClassID) - 1,0);
01739 for (chk = *classRestrictions ; chk != NULL ; chk = chk->right)
01740 {
01741 if (chk->type == SYMBOL)
01742 {
01743 chk->value = (void *) LookupDefclassInScope(theEnv,ValueToString(chk->value));
01744 if (chk->value == NULL)
01745 {
01746 PrintErrorID(theEnv,"OBJRTBLD",5,FALSE);
01747 EnvPrintRouter(theEnv,WERROR,"Undefined class in object pattern.\n");
01748 DeleteIntermediateClassBitMap(theEnv,tmpset1);
01749 DeleteIntermediateClassBitMap(theEnv,tmpset2);
01750 return(FALSE);
01751 }
01752 if (chk->negated)
01753 {
01754 InitializeClassBitMap(theEnv,tmpset2,1);
01755 MarkBitMapSubclasses(tmpset2->map,(DEFCLASS *) chk->value,0);
01756 }
01757 else
01758 {
01759 InitializeClassBitMap(theEnv,tmpset2,0);
01760 MarkBitMapSubclasses(tmpset2->map,(DEFCLASS *) chk->value,1);
01761 }
01762 IntersectClassBitMaps(tmpset1,tmpset2);
01763 }
01764 else
01765 constant_restriction = FALSE;
01766 }
01767 if (EmptyClassBitMap(tmpset1))
01768 {
01769 PrintErrorID(theEnv,"OBJRTBLD",2,FALSE);
01770 EnvPrintRouter(theEnv,WERROR,"No objects of existing classes can satisfy ");
01771 EnvPrintRouter(theEnv,WERROR,"is-a restriction in object pattern.\n");
01772 DeleteIntermediateClassBitMap(theEnv,tmpset1);
01773 DeleteIntermediateClassBitMap(theEnv,tmpset2);
01774 return(FALSE);
01775 }
01776 if (constant_restriction)
01777 {
01778 chk = *classRestrictions;
01779 *classRestrictions = chk->bottom;
01780 chk->bottom = NULL;
01781 ReturnLHSParseNodes(theEnv,chk);
01782 oraddr = classRestrictions;
01783 }
01784 else
01785 oraddr = &(*classRestrictions)->bottom;
01786 UnionClassBitMaps(clsset,tmpset1);
01787 DeleteIntermediateClassBitMap(theEnv,tmpset1);
01788 DeleteIntermediateClassBitMap(theEnv,tmpset2);
01789
01790
01791
01792
01793 return(ProcessClassRestriction(theEnv,clsset,oraddr,FALSE));
01794 }
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811 static CONSTRAINT_RECORD *ProcessSlotRestriction(
01812 void *theEnv,
01813 CLASS_BITMAP *clsset,
01814 SYMBOL_HN *slotName,
01815 int *multip)
01816 {
01817 register DEFCLASS *cls;
01818 register int si;
01819 CONSTRAINT_RECORD *totalConstraints = NULL,*tmpConstraints;
01820 register unsigned i;
01821
01822 *multip = FALSE;
01823 for (i = 0 ; i < CLASS_TABLE_HASH_SIZE ; i++)
01824 for (cls = DefclassData(theEnv)->ClassTable[i] ; cls != NULL ; cls = cls->nxtHash)
01825 {
01826 if (TestBitMap(clsset->map,cls->id))
01827 {
01828 si = FindInstanceTemplateSlot(theEnv,cls,slotName);
01829 if ((si != -1) ? cls->instanceTemplate[si]->reactive : FALSE)
01830 {
01831 if (cls->instanceTemplate[si]->multiple)
01832 *multip = TRUE;
01833 tmpConstraints =
01834 UnionConstraints(theEnv,cls->instanceTemplate[si]->constraint,totalConstraints);
01835 RemoveConstraint(theEnv,totalConstraints);
01836 totalConstraints = tmpConstraints;
01837 }
01838 else
01839 ClearBitMap(clsset->map,cls->id);
01840 }
01841 }
01842 return(totalConstraints);
01843 }
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855 static void IntersectClassBitMaps(
01856 CLASS_BITMAP *cs1,
01857 CLASS_BITMAP *cs2)
01858 {
01859 register unsigned short bytes;
01860
01861 bytes = (unsigned short) (cs2->maxid / BITS_PER_BYTE + 1);
01862 while (bytes > 0)
01863 {
01864 cs1->map[bytes - 1] &= cs2->map[bytes - 1];
01865 bytes--;
01866 }
01867 }
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879 static void UnionClassBitMaps(
01880 CLASS_BITMAP *cs1,
01881 CLASS_BITMAP *cs2)
01882 {
01883 register unsigned short bytes;
01884
01885 bytes = (unsigned short) (cs2->maxid / BITS_PER_BYTE + 1);
01886 while (bytes > 0)
01887 {
01888 cs1->map[bytes - 1] |= cs2->map[bytes - 1];
01889 bytes--;
01890 }
01891 }
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905 static CLASS_BITMAP *PackClassBitMap(
01906 void *theEnv,
01907 CLASS_BITMAP *oldset)
01908 {
01909 register unsigned short newmaxid;
01910 CLASS_BITMAP *newset;
01911
01912 for (newmaxid = oldset->maxid ; newmaxid > 0 ; newmaxid--)
01913 if (TestBitMap(oldset->map,newmaxid))
01914 break;
01915 if (newmaxid != oldset->maxid)
01916 {
01917 newset = NewClassBitMap(theEnv,(int) newmaxid,0);
01918 GenCopyMemory(char,newmaxid / BITS_PER_BYTE + 1,newset->map,oldset->map);
01919 DeleteIntermediateClassBitMap(theEnv,oldset);
01920 }
01921 else
01922 newset = oldset;
01923 return(newset);
01924 }
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945 static struct lhsParseNode *FilterObjectPattern(
01946 void *theEnv,
01947 struct patternParser *selfPatternType,
01948 struct lhsParseNode *unfilteredSlots,
01949 struct lhsParseNode **bitmap_slot,
01950 struct lhsParseNode **isa_slot,
01951 struct lhsParseNode **name_slot)
01952 {
01953 struct lhsParseNode *prv,*cur;
01954
01955 *isa_slot = NULL;
01956 *name_slot = NULL;
01957
01958
01959
01960
01961
01962 *bitmap_slot = GetLHSParseNode(theEnv);
01963 (*bitmap_slot)->type = SF_WILDCARD;
01964 (*bitmap_slot)->slot = DefclassData(theEnv)->ISA_SYMBOL;
01965 (*bitmap_slot)->slotNumber = ISA_ID;
01966 (*bitmap_slot)->index = 1;
01967 (*bitmap_slot)->patternType = selfPatternType;
01968 (*bitmap_slot)->userData = unfilteredSlots->userData;
01969 unfilteredSlots->userData = NULL;
01970
01971
01972
01973
01974 prv = NULL;
01975 cur = unfilteredSlots;
01976 while (cur != NULL)
01977 {
01978 if (cur->slot == DefclassData(theEnv)->ISA_SYMBOL)
01979 *isa_slot = cur;
01980 else if (cur->slot == DefclassData(theEnv)->NAME_SYMBOL)
01981 *name_slot = cur;
01982 prv = cur;
01983 cur = cur->right;
01984 }
01985
01986
01987
01988
01989
01990 if (prv == NULL)
01991 unfilteredSlots = *bitmap_slot;
01992 else
01993 prv->right = *bitmap_slot;
01994 return(unfilteredSlots);
01995 }
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010 static BITMAP_HN *FormSlotBitMap(
02011 void *theEnv,
02012 struct lhsParseNode *thePattern)
02013 {
02014 struct lhsParseNode *node;
02015 int maxSlotID = -1;
02016 unsigned size;
02017 SLOT_BITMAP *bmp;
02018 BITMAP_HN *hshBmp;
02019
02020
02021
02022
02023 for (node = thePattern ; node != NULL ; node = node->right)
02024 if (node->slotNumber > maxSlotID)
02025 maxSlotID = node->slotNumber;
02026
02027
02028
02029
02030
02031
02032 if ((maxSlotID == ISA_ID) || (maxSlotID == NAME_ID))
02033 return(NULL);
02034
02035
02036
02037
02038 size = (sizeof(SLOT_BITMAP) +
02039 (sizeof(char) * (maxSlotID / BITS_PER_BYTE)));
02040 bmp = (SLOT_BITMAP *) gm2(theEnv,size);
02041 ClearBitString((void *) bmp,size);
02042 bmp->maxid = (unsigned short) maxSlotID;
02043
02044
02045
02046
02047
02048
02049 for (node = thePattern ; node != NULL ; node = node->right)
02050 SetBitMap(bmp->map,node->slotNumber);
02051 hshBmp = (BITMAP_HN *) EnvAddBitMap(theEnv,(void *) bmp,SlotBitMapSize(bmp));
02052 rm(theEnv,(void *) bmp,size);
02053 return(hshBmp);
02054 }
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067 static struct lhsParseNode *RemoveSlotExistenceTests(
02068 void *theEnv,
02069 struct lhsParseNode *thePattern,
02070 BITMAP_HN **bmp)
02071 {
02072 struct lhsParseNode *tempPattern = thePattern;
02073 struct lhsParseNode *lastPattern = NULL, *head = thePattern;
02074
02075 while (tempPattern != NULL)
02076 {
02077
02078
02079
02080 if (tempPattern->userData != NULL)
02081 {
02082 *bmp = (BITMAP_HN *) tempPattern->userData;
02083 lastPattern = tempPattern;
02084 tempPattern = tempPattern->right;
02085 }
02086
02087
02088
02089
02090
02091
02092 else if (((tempPattern->type == SF_WILDCARD) ||
02093 (tempPattern->type == SF_VARIABLE)) &&
02094 (tempPattern->networkTest == NULL))
02095 {
02096 if (lastPattern != NULL) lastPattern->right = tempPattern->right;
02097 else head = tempPattern->right;
02098
02099 tempPattern->right = NULL;
02100 ReturnLHSParseNodes(theEnv,tempPattern);
02101
02102 if (lastPattern != NULL) tempPattern = lastPattern->right;
02103 else tempPattern = head;
02104 }
02105
02106
02107
02108
02109
02110
02111
02112
02113 else if (((tempPattern->type == MF_WILDCARD) || (tempPattern->type == MF_VARIABLE)) &&
02114 (tempPattern->multifieldSlot == FALSE) &&
02115 (tempPattern->networkTest == NULL) &&
02116 (tempPattern->multiFieldsBefore == 0) &&
02117 (tempPattern->multiFieldsAfter == 0))
02118 {
02119 if (lastPattern != NULL) lastPattern->right = tempPattern->right;
02120 else head = tempPattern->right;
02121
02122 tempPattern->right = NULL;
02123 ReturnLHSParseNodes(theEnv,tempPattern);
02124
02125 if (lastPattern != NULL) tempPattern = lastPattern->right;
02126 else tempPattern = head;
02127 }
02128
02129
02130
02131
02132
02133
02134
02135 else if (((tempPattern->type == MF_WILDCARD) || (tempPattern->type == MF_VARIABLE)) &&
02136 (tempPattern->multifieldSlot == FALSE) &&
02137 (tempPattern->networkTest != NULL) &&
02138 (tempPattern->multiFieldsBefore == 0) &&
02139 (tempPattern->multiFieldsAfter == 0))
02140 {
02141 tempPattern->type = SF_WILDCARD;
02142 lastPattern = tempPattern;
02143 tempPattern = tempPattern->right;
02144 }
02145
02146
02147
02148
02149
02150
02151
02152 else if ((tempPattern->type == MF_WILDCARD) &&
02153 (tempPattern->multifieldSlot == TRUE) &&
02154 (tempPattern->bottom == NULL))
02155 {
02156 tempPattern->type = SF_WILDCARD;
02157 GenObjectZeroLengthTest(theEnv,tempPattern);
02158 tempPattern->multifieldSlot = FALSE;
02159 lastPattern = tempPattern;
02160 tempPattern = tempPattern->right;
02161 }
02162
02163
02164
02165
02166
02167 else if ((tempPattern->type == MF_WILDCARD) &&
02168 (tempPattern->multifieldSlot == TRUE))
02169 {
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180 GenObjectLengthTest(theEnv,tempPattern->bottom);
02181
02182
02183
02184
02185 tempPattern->bottom = RemoveSlotExistenceTests(theEnv,tempPattern->bottom,bmp);
02186
02187
02188
02189
02190
02191
02192 if (tempPattern->bottom == NULL)
02193 {
02194 if (lastPattern != NULL) lastPattern->right = tempPattern->right;
02195 else head = tempPattern->right;
02196
02197 tempPattern->right = NULL;
02198 ReturnLHSParseNodes(theEnv,tempPattern);
02199
02200 if (lastPattern != NULL) tempPattern = lastPattern->right;
02201 else tempPattern = head;
02202 }
02203 else
02204 {
02205 lastPattern = tempPattern;
02206 tempPattern = tempPattern->right;
02207 }
02208 }
02209
02210
02211
02212
02213
02214
02215 else
02216 {
02217 lastPattern = tempPattern;
02218 tempPattern = tempPattern->right;
02219 }
02220 }
02221
02222
02223
02224
02225
02226 return(head);
02227 }
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240 static struct lhsParseNode *CreateInitialObjectPattern(
02241 void *theEnv)
02242 {
02243 struct lhsParseNode *topNode;
02244 CLASS_BITMAP *clsset;
02245 int initialObjectClassID;
02246
02247 initialObjectClassID = LookupDefclassInScope(theEnv,INITIAL_OBJECT_CLASS_NAME)->id;
02248 clsset = NewClassBitMap(theEnv,initialObjectClassID,0);
02249 SetBitMap(clsset->map,initialObjectClassID);
02250 clsset = PackClassBitMap(theEnv,clsset);
02251
02252 topNode = GetLHSParseNode(theEnv);
02253 topNode->userData = EnvAddBitMap(theEnv,(void *) clsset,ClassBitMapSize(clsset));
02254 IncrementBitMapCount(topNode->userData);
02255 DeleteIntermediateClassBitMap(theEnv,clsset);
02256 topNode->type = SF_WILDCARD;
02257 topNode->index = 1;
02258 topNode->slot = DefclassData(theEnv)->NAME_SYMBOL;
02259 topNode->slotNumber = NAME_ID;
02260
02261 topNode->bottom = GetLHSParseNode(theEnv);
02262 topNode->bottom->type = INSTANCE_NAME;
02263 topNode->bottom->value = (void *) DefclassData(theEnv)->INITIAL_OBJECT_SYMBOL;
02264
02265 return(topNode);
02266 }
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280 static EXPRESSION *ObjectMatchDelayParse(
02281 void *theEnv,
02282 struct expr *top,
02283 char *infile)
02284 {
02285 struct token tkn;
02286
02287 IncrementIndentDepth(theEnv,3);
02288 PPCRAndIndent(theEnv);
02289 top->argList = GroupActions(theEnv,infile,&tkn,TRUE,NULL,FALSE);
02290 PPBackup(theEnv);
02291 PPBackup(theEnv);
02292 SavePPBuffer(theEnv,tkn.printForm);
02293 DecrementIndentDepth(theEnv,3);
02294 if (top->argList == NULL)
02295 {
02296 ReturnExpression(theEnv,top);
02297 return(NULL);
02298 }
02299 return(top);
02300 }
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316 #if WIN_BTC
02317 #pragma argsused
02318 #endif
02319 static void MarkObjectPtnIncrementalReset(
02320 void *theEnv,
02321 struct patternNodeHeader *thePattern,
02322 int value)
02323 {
02324 #if MAC_MCW || WIN_MCW || MAC_XCD
02325 #pragma unused(theEnv)
02326 #endif
02327
02328 if (thePattern->initialize == FALSE)
02329 return;
02330 thePattern->initialize = value;
02331 }
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345 static void ObjectIncrementalReset(
02346 void *theEnv)
02347 {
02348 INSTANCE_TYPE *ins;
02349
02350 for (ins = InstanceData(theEnv)->InstanceList ; ins != NULL ; ins = ins->nxtList)
02351 ObjectNetworkAction(theEnv,OBJECT_ASSERT,(INSTANCE_TYPE *) ins,-1);
02352 }
02353
02354 #endif
02355
02356 #endif
02357
02358