📄 objrtbld.c
字号:
while (theToken.type != RPAREN)
{
ppbackupReqd = TRUE;
PPBackup(theEnv);
SavePPBuffer(theEnv," ");
SavePPBuffer(theEnv,theToken.printForm);
if (theToken.type != LPAREN)
{
SyntaxErrorMessage(theEnv,"object pattern");
goto ObjectLHSParseERROR;
}
GetToken(theEnv,readSource,&theToken);
if (theToken.type != SYMBOL)
{
SyntaxErrorMessage(theEnv,"object pattern");
goto ObjectLHSParseERROR;
}
if (CheckDuplicateSlots(theEnv,firstNode,(SYMBOL_HN *) theToken.value))
goto ObjectLHSParseERROR;
if (theToken.value == (void *) DefclassData(theEnv)->ISA_SYMBOL)
{
tmpNode = ParseClassRestriction(theEnv,readSource,&theToken);
if (tmpNode == NULL)
goto ObjectLHSParseERROR;
InitializeClassBitMap(theEnv,tmpset,0);
if (ProcessClassRestriction(theEnv,tmpset,&tmpNode->bottom,TRUE) == FALSE)
{
ReturnLHSParseNodes(theEnv,tmpNode);
goto ObjectLHSParseERROR;
}
IntersectClassBitMaps(clsset,tmpset);
}
else if (theToken.value == (void *) DefclassData(theEnv)->NAME_SYMBOL)
{
tmpNode = ParseNameRestriction(theEnv,readSource,&theToken);
if (tmpNode == NULL)
goto ObjectLHSParseERROR;
InitializeClassBitMap(theEnv,tmpset,1);
}
else
{
slotConstraints = ProcessSlotRestriction(theEnv,clsset,(SYMBOL_HN *) theToken.value,&multip);
if (slotConstraints != NULL)
{
InitializeClassBitMap(theEnv,tmpset,1);
tmpNode = ParseSlotRestriction(theEnv,readSource,&theToken,slotConstraints,multip);
if (tmpNode == NULL)
goto ObjectLHSParseERROR;
}
else
{
InitializeClassBitMap(theEnv,tmpset,0);
tmpNode = GetLHSParseNode(theEnv);
tmpNode->slot = (SYMBOL_HN *) theToken.value;
}
}
if (EmptyClassBitMap(tmpset))
{
PrintErrorID(theEnv,"OBJRTBLD",2,FALSE);
EnvPrintRouter(theEnv,WERROR,"No objects of existing classes can satisfy ");
EnvPrintRouter(theEnv,WERROR,ValueToString(tmpNode->slot));
EnvPrintRouter(theEnv,WERROR," restriction in object pattern.\n");
ReturnLHSParseNodes(theEnv,tmpNode);
goto ObjectLHSParseERROR;
}
if (EmptyClassBitMap(clsset))
{
PrintErrorID(theEnv,"OBJRTBLD",1,FALSE);
EnvPrintRouter(theEnv,WERROR,"No objects of existing classes can satisfy pattern.\n");
ReturnLHSParseNodes(theEnv,tmpNode);
goto ObjectLHSParseERROR;
}
if (tmpNode != NULL)
{
if (firstNode == NULL)
firstNode = tmpNode;
else
lastNode->right = tmpNode;
lastNode = tmpNode;
}
PPCRAndIndent(theEnv);
GetToken(theEnv,readSource,&theToken);
}
if (firstNode == NULL)
{
if (EmptyClassBitMap(clsset))
{
PrintErrorID(theEnv,"OBJRTBLD",1,FALSE);
EnvPrintRouter(theEnv,WERROR,"No objects of existing classes can satisfy pattern.\n");
goto ObjectLHSParseERROR;
}
firstNode = GetLHSParseNode(theEnv);
firstNode->type = SF_WILDCARD;
firstNode->slot = DefclassData(theEnv)->ISA_SYMBOL;
firstNode->slotNumber = ISA_ID;
firstNode->index = 1;
}
if (ppbackupReqd)
{
PPBackup(theEnv);
PPBackup(theEnv);
SavePPBuffer(theEnv,theToken.printForm);
}
DeleteIntermediateClassBitMap(theEnv,tmpset);
clsset = PackClassBitMap(theEnv,clsset);
firstNode->userData = AddBitMap(theEnv,(void *) clsset,ClassBitMapSize(clsset));
IncrementBitMapCount(firstNode->userData);
DeleteIntermediateClassBitMap(theEnv,clsset);
DecrementIndentDepth(theEnv,7);
return(firstNode);
ObjectLHSParseERROR:
DeleteIntermediateClassBitMap(theEnv,clsset);
DeleteIntermediateClassBitMap(theEnv,tmpset);
ReturnLHSParseNodes(theEnv,firstNode);
DecrementIndentDepth(theEnv,7);
return(NULL);
}
/**************************************************************
NAME : ReorderAndAnalyzeObjectPattern
DESCRIPTION : This function reexamines the object pattern
after constraint and variable analysis info
has been propagated from other patterns.
Any slots which are no longer applicable
to the pattern are eliminated from the
class set.
Also, the slot names are ordered according
to lexical value to aid in deteterming
sharing between object patterns. (The is-a
and name restrictions are always placed
first regardless of symbolic hash value.)
INPUTS : The pattern CE lhsParseNode
RETURNS : FALSE if all OK, otherwise TRUE
(e.g. all classes are eliminated as potential
matching candidates for the pattern)
SIDE EFFECTS : Slot restrictions are reordered (if necessary)
NOTES : Adds a default is-a slot if one does not
already exist
**************************************************************/
static intBool ReorderAndAnalyzeObjectPattern(
void *theEnv,
struct lhsParseNode *topNode)
{
CLASS_BITMAP *clsset,*tmpset;
EXPRESSION *rexp,*tmpmin,*tmpmax;
DEFCLASS *cls;
struct lhsParseNode *tmpNode,*subNode,*bitmap_node,*isa_node,*name_node;
register unsigned short i;
SLOT_DESC *sd;
CONSTRAINT_RECORD *crossConstraints, *theConstraint;
int incompatibleConstraint,clssetChanged = FALSE;
/* ==========================================================
Make sure that the bitmap marking which classes of object
can match the pattern is attached to the class restriction
(which will always be present and the last restriction
after the sort)
========================================================== */
topNode->right = FilterObjectPattern(theEnv,topNode->patternType,topNode->right,
&bitmap_node,&isa_node,&name_node);
if (EnvGetStaticConstraintChecking(theEnv) == FALSE)
return(FALSE);
/* ============================================
Allocate a temporary set for marking classes
============================================ */
clsset = (CLASS_BITMAP *) ValueToBitMap(bitmap_node->userData);
tmpset = NewClassBitMap(theEnv,(int) clsset->maxid,0);
/* ==========================================================
Check the allowed-values for the constraint on the is-a
slot. If there are any, make sure that only the classes
with those values as names are marked in the bitmap.
There will only be symbols in the list because the
original constraint on the is-a slot allowed only symbols.
========================================================== */
if ((isa_node == NULL) ? FALSE :
((isa_node->constraints == NULL) ? FALSE :
(isa_node->constraints->restrictionList != NULL)))
{
rexp = isa_node->constraints->restrictionList;
while (rexp != NULL)
{
cls = LookupDefclassInScope(theEnv,ValueToString(rexp->value));
if (cls != NULL)
{
if ((cls->id <= clsset->maxid) ? TestBitMap(clsset->map,cls->id) : FALSE)
SetBitMap(tmpset->map,cls->id);
}
rexp = rexp->nextArg;
}
clssetChanged = IdenticalClassBitMap(tmpset,clsset) ? FALSE : TRUE;
}
else
GenCopyMemory(char,tmpset->maxid / BITS_PER_BYTE + 1,tmpset->map,clsset->map);
/* ================================================================
For each of the slots (excluding name and is-a), check the total
constraints for the slot against the individual constraints
for each occurrence of the slot in the classes marked in
the bitmap. For any slot which is not compatible with
the overall constraint, clear its class's bit in the bitmap.
================================================================ */
tmpNode = topNode->right;
while (tmpNode != bitmap_node)
{
if ((tmpNode == isa_node) || (tmpNode == name_node))
{
tmpNode = tmpNode->right;
continue;
}
for (i = 0 ; i <= tmpset->maxid ; i++)
if (TestBitMap(tmpset->map,i))
{
cls = DefclassData(theEnv)->ClassIDMap[i];
sd = cls->instanceTemplate[FindInstanceTemplateSlot(theEnv,cls,tmpNode->slot)];
/* =========================================
Check the top-level lhsParseNode for type
and cardinality compatibility
========================================= */
crossConstraints = IntersectConstraints(theEnv,tmpNode->constraints,sd->constraint);
incompatibleConstraint = UnmatchableConstraint(crossConstraints);
RemoveConstraint(theEnv,crossConstraints);
if (incompatibleConstraint)
{
ClearBitMap(tmpset->map,i);
clssetChanged = TRUE;
}
else if (tmpNode->type == MF_WILDCARD)
{
/* ==========================================
Check the sub-nodes for type compatibility
========================================== */
for (subNode = tmpNode->bottom ; subNode != NULL ; subNode = subNode->right)
{
/* ========================================================
Temporarily reset cardinality of variables to
match slot so that no cardinality errors will be flagged
======================================================== */
if ((subNode->type == MF_WILDCARD) || (subNode->type == MF_VARIABLE))
{ theConstraint = subNode->constraints->multifield; }
else
{ theConstraint = subNode->constraints; }
tmpmin = theConstraint->minFields;
theConstraint->minFields = sd->constraint->minFields;
tmpmax = theConstraint->maxFields;
theConstraint->maxFields = sd->constraint->maxFields;
crossConstraints = IntersectConstraints(theEnv,theConstraint,sd->constraint);
theConstraint->minFields = tmpmin;
theConstraint->maxFields = tmpmax;
incompatibleConstraint = UnmatchableConstraint(crossConstraints);
RemoveConstraint(theEnv,crossConstraints);
if (incompatibleConstraint)
{
ClearBitMap(tmpset->map,i);
clssetChanged = TRUE;
break;
}
}
}
}
tmpNode = tmpNode->right;
}
if (clssetChanged)
{
/* =======================================================
Make sure that there are still classes of objects which
can satisfy this pattern. Otherwise, signal an error.
======================================================= */
if (EmptyClassBitMap(tmpset))
{
PrintErrorID(theEnv,"OBJRTBLD",3,TRUE);
DeleteIntermediateClassBitMap(theEnv,tmpset);
EnvPrintRouter(theEnv,WERROR,"No objects of existing classes can satisfy pattern #");
PrintLongInteger(theEnv,WERROR,(long) topNode->pattern);
EnvPrintRouter(theEnv,WERROR,".\n");
return(TRUE);
}
clsset = PackClassBitMap(theEnv,tmpset);
DeleteClassBitMap(theEnv,(void *) bitmap_node->userData);
bitmap_node->userData = AddBitMap(theEnv,(void *) clsset,ClassBitMapSize(clsset));
IncrementBitMapCount(bitmap_node->userData);
DeleteIntermediateClassBitMap(theEnv,clsset);
}
else
DeleteIntermediateClassBitMap(theEnv,tmpset);
return(FALSE);
}
/*****************************************************
NAME : PlaceObjectPattern
DESCRIPTION : Integrates an object pattern into the
object pattern network
INPUTS : The intermediate parse representation
of the pattern
RETURNS : The address of the new pattern
SIDE EFFECTS : Object pattern network updated
NOTES : None
*****************************************************/
static struct patternNodeHeader *PlaceObjectPattern(
void *theEnv,
struct lhsParseNode *thePattern)
{
OBJECT_PATTERN_NODE *currentLevel,*lastLevel;
struct lhsParseNode *tempPattern = NULL;
OBJECT_PATTERN_NODE *nodeSlotGroup, *newNode;
OBJECT_ALPHA_NODE *newAlphaNode;
unsigned endSlot;
BITMAP_HN *newClassBitMap,*newSlotBitMap;
/* =====================================================
Get the top of the object pattern network and prepare
for the traversal to look for shareable pattern nodes
===================================================== */
currentLevel = ObjectNetworkPointer(theEnv);
lastLevel = NULL;
/* ==================================================
Remove slot existence tests from the pattern since
these are accounted for by the class bitmap
and find the class and slot bitmaps
================================================== */
newSlotBitMap = FormSlotBitMap(theEnv,thePattern->right);
thePattern->right = RemoveSlotExistenceTests(theEnv,thePattern->right,&newClassBitMap);
thePattern = thePattern->right;
/* =========================================
Loop until all fields in the pattern have
been added to the pattern network
Process the bitmap node ONLY if it is
the only node in the pattern
========================================= */
do
{
if (thePattern->multifieldSlot)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -