📄 objrtfnx.c
字号:
/****************************************************
NAME : GetPatternObjectAndMarks
DESCRIPTION : Finds the instance and multfiield
markers corresponding to a specified
pattern in the join network
INPUTS : 1) The index of the desired pattern
2) A buffer to hold the instance
address
3) A buffer to hold the list of
multifield markers
RETURNS : Nothing useful
SIDE EFFECTS : Buffers set
NOTES : None
****************************************************/
static void GetPatternObjectAndMarks(
void *theEnv,
int pattern,
INSTANCE_TYPE **theInstance,
struct multifieldMarker **theMarkers)
{
if (EngineData(theEnv)->GlobalRHSBinds == NULL)
{
*theInstance = (INSTANCE_TYPE *)
get_nth_pm_match(EngineData(theEnv)->GlobalLHSBinds,pattern)->matchingItem;
*theMarkers =
get_nth_pm_match(EngineData(theEnv)->GlobalLHSBinds,pattern)->markers;
}
else if ((((int) EngineData(theEnv)->GlobalJoin->depth) - 1) == pattern)
{
*theInstance = (INSTANCE_TYPE *) get_nth_pm_match(EngineData(theEnv)->GlobalRHSBinds,0)->matchingItem;
*theMarkers = get_nth_pm_match(EngineData(theEnv)->GlobalRHSBinds,0)->markers;
}
else
{
*theInstance = (INSTANCE_TYPE *)
get_nth_pm_match(EngineData(theEnv)->GlobalLHSBinds,pattern)->matchingItem;
*theMarkers =
get_nth_pm_match(EngineData(theEnv)->GlobalLHSBinds,pattern)->markers;
}
}
/***************************************************
NAME : GetObjectValueGeneral
DESCRIPTION : Access function for getting
pattern variable values within the
object pattern and join networks
INPUTS : 1) The result data object buffer
2) The instance to access
3) The list of multifield markers
for the pattern
4) Data for variable reference
RETURNS : Nothing useful
SIDE EFFECTS : Data object is filled with the
values of the pattern variable
NOTES : None
***************************************************/
static void GetObjectValueGeneral(
void *theEnv,
DATA_OBJECT *result,
INSTANCE_TYPE *theInstance,
struct multifieldMarker *theMarks,
struct ObjectMatchVar1 *matchVar)
{
long field, extent; /* 6.04 Bug Fix */
INSTANCE_SLOT **insSlot,*basisSlot;
if (matchVar->objectAddress)
{
result->type = INSTANCE_ADDRESS;
result->value = (void *) theInstance;
return;
}
if (matchVar->whichSlot == ISA_ID)
{
result->type = SYMBOL;
result->value = (void *) GetDefclassNamePointer((void *) theInstance->cls);
return;
}
if (matchVar->whichSlot == NAME_ID)
{
result->type = INSTANCE_NAME;
result->value = (void *) theInstance->name;
return;
}
insSlot =
&theInstance->slotAddresses
[theInstance->cls->slotNameMap[matchVar->whichSlot] - 1];
/* =========================================
We need to reference the basis slots if
the slot of this object has changed while
the RHS was executing
However, if the reference is being done
by the LHS of a rule (as a consequence of
an RHS action), give the pattern matcher
the real value of the slot
========================================= */
if ((theInstance->basisSlots != NULL) &&
(! EngineData(theEnv)->JoinOperationInProgress))
{
basisSlot = theInstance->basisSlots + (insSlot - theInstance->slotAddresses);
if (basisSlot->value != NULL)
insSlot = &basisSlot;
}
/* ==================================================
If we know we are accessing the entire slot,
the don't bother with searching multifield markers
or calculating offsets
================================================== */
if (matchVar->allFields)
{
result->type = (unsigned short) (*insSlot)->type;
result->value = (*insSlot)->value;
if (result->type == MULTIFIELD)
{
result->begin = 0;
SetpDOEnd(result,GetMFLength((*insSlot)->value));
}
return;
}
/* =============================================
Access a general field in a slot pattern with
two or more multifield variables
============================================= */
field = CalculateSlotField(theMarks,*insSlot,matchVar->whichField,&extent);
if (extent == -1)
{
if ((*insSlot)->desc->multiple)
{
result->type = GetMFType((*insSlot)->value,field);
result->value = GetMFValue((*insSlot)->value,field);
}
else
{
result->type = (unsigned short) (*insSlot)->type;
result->value = (*insSlot)->value;
}
}
else
{
result->type = MULTIFIELD;
result->value = (*insSlot)->value;
result->begin = field - 1;
result->end = field + extent - 2;
}
}
/***************************************************
NAME : GetObjectValueSimple
DESCRIPTION : Access function for getting
pattern variable values within the
object pattern and join networks
INPUTS : 1) The result data object buffer
2) The instance to access
3) Data for variable reference
RETURNS : Nothing useful
SIDE EFFECTS : Data object is filled with the
values of the pattern variable
NOTES : None
***************************************************/
static void GetObjectValueSimple(
void *theEnv,
DATA_OBJECT *result,
INSTANCE_TYPE *theInstance,
struct ObjectMatchVar2 *matchVar)
{
INSTANCE_SLOT **insSlot,*basisSlot;
SEGMENT *segmentPtr;
FIELD *fieldPtr;
insSlot =
&theInstance->slotAddresses
[theInstance->cls->slotNameMap[matchVar->whichSlot] - 1];
/* =========================================
We need to reference the basis slots if
the slot of this object has changed while
the RHS was executing
However, if the reference is being done
by the LHS of a rule (as a consequence of
an RHS action), give the pattern matcher
the real value of the slot
========================================= */
if ((theInstance->basisSlots != NULL) &&
(! EngineData(theEnv)->JoinOperationInProgress))
{
basisSlot = theInstance->basisSlots + (insSlot - theInstance->slotAddresses);
if (basisSlot->value != NULL)
insSlot = &basisSlot;
}
if ((*insSlot)->desc->multiple)
{
segmentPtr = (SEGMENT *) (*insSlot)->value;
if (matchVar->fromBeginning)
{
if (matchVar->fromEnd)
{
result->type = MULTIFIELD;
result->value = (void *) segmentPtr;
result->begin = matchVar->beginningOffset;
SetpDOEnd(result,GetMFLength(segmentPtr) - matchVar->endOffset);
}
else
{
fieldPtr = &segmentPtr->theFields[matchVar->beginningOffset];
result->type = fieldPtr->type;
result->value = fieldPtr->value;
}
}
else
{
fieldPtr = &segmentPtr->theFields[segmentPtr->multifieldLength -
(matchVar->endOffset + 1)];
result->type = fieldPtr->type;
result->value = fieldPtr->value;
}
}
else
{
result->type = (unsigned short) (*insSlot)->type;
result->value = (*insSlot)->value;
}
}
/****************************************************
NAME : CalculateSlotField
DESCRIPTION : Determines the actual index into the
an object slot for a given pattern
variable
INPUTS : 1) The list of markers to examine
2) The instance slot (can be NULL)
3) The pattern index of the variable
4) A buffer in which to store the
extent of the pattern variable
(-1 for single-field vars)
RETURNS : The actual index
SIDE EFFECTS : None
NOTES : None
****************************************************/
static long CalculateSlotField(
struct multifieldMarker *theMarkers,
INSTANCE_SLOT *theSlot,
long theIndex,
long *extent)
{
register long actualIndex;
void *theSlotName;
actualIndex = theIndex;
*extent = -1;
if (theSlot == NULL)
return(actualIndex);
theSlotName = (void *) theSlot->desc->slotName->name;
while (theMarkers != NULL)
{
if (theMarkers->where.whichSlot == theSlotName)
break;
theMarkers = theMarkers->next;
}
while ((theMarkers != NULL) ? (theMarkers->where.whichSlot == theSlotName) : FALSE)
{
if (theMarkers->whichField == theIndex)
{
*extent = theMarkers->endPosition - theMarkers->startPosition + 1;
return(actualIndex);
}
if (theMarkers->whichField > theIndex)
return(actualIndex);
actualIndex += theMarkers->endPosition - theMarkers->startPosition;
theMarkers = theMarkers->next;
}
return(actualIndex);
}
/****************************************************
NAME : GetInsMultiSlotField
DESCRIPTION : Gets the values of simple single
field references in multifield
slots for Rete comparisons
INPUTS : 1) A multifield field structure
to store the type and value in
2) The instance
3) The id of the slot
4) A flag indicating if offset is
from beginning or end of
multifield slot
5) The offset
RETURNS : The multifield field
SIDE EFFECTS : None
NOTES : Should only be used to access
single-field reference in multifield
slots for pattern and join network
comparisons
****************************************************/
static void GetInsMultiSlotField(
FIELD *theField,
INSTANCE_TYPE *theInstance,
unsigned theSlotID,
unsigned fromBeginning,
unsigned offset)
{
register INSTANCE_SLOT * insSlot;
register SEGMENT *theSegment;
register FIELD *tmpField;
insSlot = theInstance->slotAddresses
[theInstance->cls->slotNameMap[theSlotID] - 1];
/* Bug fix for 6.05 */
if (insSlot->desc->multiple)
{
theSegment = (SEGMENT *) insSlot->value;
if (fromBeginning)
tmpField = &theSegment->theFields[offset];
else
tmpField = &theSegment->theFields[theSegment->multifieldLength - offset - 1];
theField->type = tmpField->type;
theField->value = tmpField->value;
}
else
{
theField->type = (unsigned short) insSlot->type;
theField->value = insSlot->value;
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -