📄 objrtbld.c
字号:
SavePPBuffer(theEnv," ");
GetToken(theEnv,readSource,theToken);
tmpNode = RestrictionParse(theEnv,readSource,theToken,multip,slotName,FindSlotNameID(theEnv,slotName),
slotConstraints,1);
if (tmpNode == NULL)
{
RemoveConstraint(theEnv,slotConstraints);
return(NULL);
}
if (theToken->type != RPAREN)
{
PPBackup(theEnv);
SavePPBuffer(theEnv," ");
SavePPBuffer(theEnv,theToken->printForm);
SyntaxErrorMessage(theEnv,"object slot pattern");
ReturnLHSParseNodes(theEnv,tmpNode);
RemoveConstraint(theEnv,slotConstraints);
return(NULL);
}
if ((tmpNode->bottom == NULL) && (tmpNode->multifieldSlot))
{
PPBackup(theEnv);
PPBackup(theEnv);
SavePPBuffer(theEnv,")");
}
tmpNode->derivedConstraints = 1;
return(tmpNode);
}
/********************************************************
NAME : NewClassBitMap
DESCRIPTION : Creates a new bitmap large enough
to hold all ids of classes in the
system and initializes all the bits
to zero or one.
INPUTS : 1) The maximum id that will be set
in the bitmap
2) An integer code indicating if all
the bits are to be set to zero or one
RETURNS : The new bitmap
SIDE EFFECTS : BitMap allocated and initialized
NOTES : None
********************************************************/
static CLASS_BITMAP *NewClassBitMap(
void *theEnv,
int maxid,
int set)
{
register CLASS_BITMAP *bmp;
unsigned size;
if (maxid == -1)
maxid = 0;
size = sizeof(CLASS_BITMAP) +
(sizeof(char) * (maxid / BITS_PER_BYTE));
bmp = (CLASS_BITMAP *) gm2(theEnv,size);
ClearBitString((void *) bmp,size);
bmp->maxid = (unsigned short) maxid;
InitializeClassBitMap(theEnv,bmp,set);
return(bmp);
}
/***********************************************************
NAME : InitializeClassBitMap
DESCRIPTION : Initializes a bitmap to all zeroes or ones.
INPUTS : 1) The bitmap
2) An integer code indicating if all
the bits are to be set to zero or one
RETURNS : Nothing useful
SIDE EFFECTS : The bitmap is initialized
NOTES : None
***********************************************************/
static void InitializeClassBitMap(
void *theEnv,
CLASS_BITMAP *bmp,
int set)
{
register int i,bytes;
DEFCLASS *cls;
struct defmodule *currentModule;
bytes = bmp->maxid / BITS_PER_BYTE + 1;
while (bytes > 0)
{
bmp->map[bytes - 1] = (char) 0;
bytes--;
}
if (set)
{
currentModule = ((struct defmodule *) EnvGetCurrentModule(theEnv));
for (i = 0 ; i <= (int) bmp->maxid ; i++)
{
cls = DefclassData(theEnv)->ClassIDMap[i];
if ((cls != NULL) ? DefclassInScope(theEnv,cls,currentModule) : FALSE)
{
if (cls->reactive && (cls->abstract == 0))
SetBitMap(bmp->map,i);
}
}
}
}
/********************************************
NAME : DeleteIntermediateClassBitMap
DESCRIPTION : Deallocates a bitmap
INPUTS : The class set
RETURNS : Nothing useful
SIDE EFFECTS : Class set deallocated
NOTES : None
********************************************/
static void DeleteIntermediateClassBitMap(
void *theEnv,
CLASS_BITMAP *bmp)
{
rm(theEnv,(void *) bmp,ClassBitMapSize(bmp));
}
/******************************************************
NAME : CopyClassBitMap
DESCRIPTION : Increments the in use count of a
bitmap and returns the same pointer
INPUTS : The bitmap
RETURNS : The bitmap
SIDE EFFECTS : Increments the in use count
NOTES : Class sets are shared by multiple
copies of an object pattern within an
OR CE. The use count prevents having
to make duplicate copies of the bitmap
******************************************************/
#if IBM_TBC
#pragma argsused
#endif
static void *CopyClassBitMap(
void *theEnv,
void *gset)
{
#if MAC_MCW || IBM_MCW || MAC_XCD
#pragma unused(theEnv)
#endif
if (gset != NULL)
IncrementBitMapCount(gset);
return(gset);
}
/**********************************************************
NAME : DeleteClassBitMap
DESCRIPTION : Deallocates a bitmap,
and decrements the busy flags of the
classes marked in the bitmap
INPUTS : The bitmap
RETURNS : Nothing useful
SIDE EFFECTS : Class set deallocated and classes unmarked
NOTES : None
**********************************************************/
static void DeleteClassBitMap(
void *theEnv,
void *gset)
{
if (gset == NULL)
return;
DecrementBitMapCount(theEnv,(BITMAP_HN *) gset);
}
/***************************************************
NAME : MarkBitMapClassesBusy
DESCRIPTION : Increments/Decrements busy counts
of all classes marked in a bitmap
INPUTS : 1) The bitmap hash node
2) 1 or -1 (to increment or
decrement class busy counts)
RETURNS : Nothing useful
SIDE EFFECTS : Bitmap class busy counts updated
NOTES : None
***************************************************/
static void MarkBitMapClassesBusy(
void *theEnv,
BITMAP_HN *bmphn,
int offset)
{
register CLASS_BITMAP *bmp;
register unsigned short i;
register DEFCLASS *cls;
/* ====================================
If a clear is in progress, we do not
have to worry about busy counts
==================================== */
if (ConstructData(theEnv)->ClearInProgress)
return;
bmp = (CLASS_BITMAP *) ValueToBitMap(bmphn);
for (i = 0 ; i <= bmp->maxid ; i++)
if (TestBitMap(bmp->map,i))
{
cls = DefclassData(theEnv)->ClassIDMap[i];
cls->busy += (unsigned int) offset;
}
}
/****************************************************
NAME : EmptyClassBitMap
DESCRIPTION : Determines if one or more bits
are marked in a bitmap
INPUTS : The bitmap
RETURNS : TRUE if the set has no bits
marked, FALSE otherwise
SIDE EFFECTS : None
NOTES : None
****************************************************/
static intBool EmptyClassBitMap(
CLASS_BITMAP *bmp)
{
register unsigned short bytes;
bytes = (unsigned short) (bmp->maxid / BITS_PER_BYTE + 1);
while (bytes > 0)
{
if (bmp->map[bytes - 1] != (char) 0)
return(FALSE);
bytes--;
}
return(TRUE);
}
/***************************************************
NAME : IdenticalClassBitMap
DESCRIPTION : Determines if two bitmaps
are identical
INPUTS : 1) First bitmap
2) Second bitmap
RETURNS : TRUE if bitmaps are the same,
FALSE otherwise
SIDE EFFECTS : None
NOTES : None
***************************************************/
static intBool IdenticalClassBitMap(
CLASS_BITMAP *cs1,
CLASS_BITMAP *cs2)
{
register int i;
if (cs1->maxid != cs2->maxid)
return(FALSE);
for (i = 0 ; i < (int) (cs1->maxid / BITS_PER_BYTE + 1) ; i++)
if (cs1->map[i] != cs2->map[i])
return(FALSE);
return(TRUE);
}
/*****************************************************************
NAME : ProcessClassRestriction
DESCRIPTION : Examines a class restriction and forms a bitmap
corresponding to the maximal set of classes which
can satisfy a static analysis of the restriction
INPUTS : 1) The bitmap to mark classes in
2) The lhsParseNodes of the restriction
3) A flag indicating if this is the first
non-recursive call or not
RETURNS : TRUE if all OK, FALSE otherwise
SIDE EFFECTS : Class bitmap set and lhsParseNodes corressponding
to constant restrictions are removed
NOTES : None
*****************************************************************/
static intBool ProcessClassRestriction(
void *theEnv,
CLASS_BITMAP *clsset,
struct lhsParseNode **classRestrictions,
int recursiveCall)
{
register struct lhsParseNode *chk,**oraddr;
CLASS_BITMAP *tmpset1,*tmpset2;
int constant_restriction = TRUE;
if (*classRestrictions == NULL)
{
if (recursiveCall)
InitializeClassBitMap(theEnv,clsset,1);
return(TRUE);
}
/* ===============================================
Determine the corresponding class set and union
it with the current total class set. If an AND
restriction is comprised entirely of symbols,
it can be removed
=============================================== */
tmpset1 = NewClassBitMap(theEnv,((int) DefclassData(theEnv)->MaxClassID) - 1,1);
tmpset2 = NewClassBitMap(theEnv,((int) DefclassData(theEnv)->MaxClassID) - 1,0);
for (chk = *classRestrictions ; chk != NULL ; chk = chk->right)
{
if (chk->type == SYMBOL)
{
chk->value = (void *) LookupDefclassInScope(theEnv,ValueToString(chk->value));
if (chk->value == NULL)
{
PrintErrorID(theEnv,"OBJRTBLD",5,FALSE);
EnvPrintRouter(theEnv,WERROR,"Undefined class in object pattern.\n");
DeleteIntermediateClassBitMap(theEnv,tmpset1);
DeleteIntermediateClassBitMap(theEnv,tmpset2);
return(FALSE);
}
if (chk->negated)
{
InitializeClassBitMap(theEnv,tmpset2,1);
MarkBitMapSubclasses(tmpset2->map,(DEFCLASS *) chk->value,0);
}
else
{
InitializeClassBitMap(theEnv,tmpset2,0);
MarkBitMapSubclasses(tmpset2->map,(DEFCLASS *) chk->value,1);
}
IntersectClassBitMaps(tmpset1,tmpset2);
}
else
constant_restriction = FALSE;
}
if (EmptyClassBitMap(tmpset1))
{
PrintErrorID(theEnv,"OBJRTBLD",2,FALSE);
EnvPrintRouter(theEnv,WERROR,"No objects of existing classes can satisfy ");
EnvPrintRouter(theEnv,WERROR,"is-a restriction in object pattern.\n");
DeleteIntermediateClassBitMap(theEnv,tmpset1);
DeleteIntermediateClassBitMap(theEnv,tmpset2);
return(FALSE);
}
if (constant_restriction)
{
chk = *classRestrictions;
*classRestrictions = chk->bottom;
chk->bottom = NULL;
ReturnLHSParseNodes(theEnv,chk);
oraddr = classRestrictions;
}
else
oraddr = &(*classRestrictions)->bottom;
UnionClassBitMaps(clsset,tmpset1);
DeleteIntermediateClassBitMap(theEnv,tmpset1);
DeleteIntermediateClassBitMap(theEnv,tmpset2);
/* =====================================
Process the next OR class restriction
=============================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -