📄 insfun.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.24 05/17/06 */
/* */
/* INSTANCE FUNCTIONS MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Internal instance manipulation routines */
/* */
/* Principal Programmer(s): */
/* Brian L. Donnell */
/* */
/* Contributing Programmer(s): */
/* */
/* */
/* Revision History: */
/* 6.23: Correction for FalseSymbol/TrueSymbol. DR0859 */
/* */
/* Changed name of variable log to logName */
/* because of Unix compiler warnings of shadowed */
/* definitions. */
/* */
/* Changed name of variable exp to theExp */
/* because of Unix compiler warnings of shadowed */
/* definitions. */
/* */
/* 6.24: Link error occurs for the SlotExistError */
/* function when OBJECT_SYSTEM is set to 0 in */
/* setup.h. DR0865 */
/* */
/* Converted INSTANCE_PATTERN_MATCHING to */
/* DEFRULE_CONSTRUCT. */
/* */
/* Renamed BOOLEAN macro type to intBool. */
/* */
/* Moved EvaluateAndStoreInDataObject to */
/* evaluatn.c */
/* */
/*************************************************************/
/* =========================================
*****************************************
EXTERNAL DEFINITIONS
=========================================
***************************************** */
#include <stdlib.h>
#include "setup.h"
#if OBJECT_SYSTEM
#include "argacces.h"
#include "classcom.h"
#include "classfun.h"
#include "cstrnchk.h"
#include "engine.h"
#include "envrnmnt.h"
#include "inscom.h"
#include "insmngr.h"
#include "memalloc.h"
#include "modulutl.h"
#include "msgcom.h"
#include "msgfun.h"
#include "prccode.h"
#include "router.h"
#include "utility.h"
#if DEFRULE_CONSTRUCT
#include "drive.h"
#include "objrtmch.h"
#endif
#define _INSFUN_SOURCE_
#include "insfun.h"
/* =========================================
*****************************************
CONSTANTS
=========================================
***************************************** */
#define BIG_PRIME 11329
/* =========================================
*****************************************
INTERNALLY VISIBLE FUNCTION HEADERS
=========================================
***************************************** */
static INSTANCE_TYPE *FindImportedInstance(void *,struct defmodule *,struct defmodule *,INSTANCE_TYPE *);
#if DEFRULE_CONSTRUCT
static void NetworkModifyForSharedSlot(void *,int,DEFCLASS *,SLOT_DESC *);
#endif
/* =========================================
*****************************************
EXTERNALLY VISIBLE FUNCTIONS
=========================================
***************************************** */
/***************************************************
NAME : EnvIncrementInstanceCount
DESCRIPTION : Increments instance busy count -
prevents it from being deleted
INPUTS : The address of the instance
RETURNS : Nothing useful
SIDE EFFECTS : Count set
NOTES : None
***************************************************/
#if IBM_TBC
#pragma argsused
#endif
globle void EnvIncrementInstanceCount(
void *theEnv,
void *vptr)
{
#if MAC_MCW || IBM_MCW || MAC_XCD
#pragma unused(theEnv)
#endif
((INSTANCE_TYPE *) vptr)->busy++;
}
/***************************************************
NAME : EnvDecrementInstanceCount
DESCRIPTION : Decrements instance busy count -
might allow it to be deleted
INPUTS : The address of the instance
RETURNS : Nothing useful
SIDE EFFECTS : Count set
NOTES : None
***************************************************/
#if IBM_TBC
#pragma argsused
#endif
globle void EnvDecrementInstanceCount(
void *theEnv,
void *vptr)
{
#if MAC_MCW || IBM_MCW || MAC_XCD
#pragma unused(theEnv)
#endif
((INSTANCE_TYPE *) vptr)->busy--;
}
/***************************************************
NAME : InitializeInstanceTable
DESCRIPTION : Initializes instance hash table
to all NULL addresses
INPUTS : None
RETURNS : Nothing useful
SIDE EFFECTS : Hash table initialized
NOTES : None
***************************************************/
globle void InitializeInstanceTable(
void *theEnv)
{
register int i;
InstanceData(theEnv)->InstanceTable = (INSTANCE_TYPE **)
gm2(theEnv,(int) (sizeof(INSTANCE_TYPE *) * INSTANCE_TABLE_HASH_SIZE));
for (i = 0 ; i < INSTANCE_TABLE_HASH_SIZE ; i++)
InstanceData(theEnv)->InstanceTable[i] = NULL;
}
/*******************************************************
NAME : CleanupInstances
DESCRIPTION : Iterates through instance garbage
list looking for nodes that
have become unused - and purges
them
INPUTS : None
RETURNS : Nothing useful
SIDE EFFECTS : Non-busy instance garbage nodes deleted
NOTES : None
*******************************************************/
globle void CleanupInstances(
void *theEnv)
{
IGARBAGE *gprv,*gtmp,*dump;
if (InstanceData(theEnv)->MaintainGarbageInstances)
return;
gprv = NULL;
gtmp = InstanceData(theEnv)->InstanceGarbageList;
while (gtmp != NULL)
{
if ((gtmp->ins->busy == 0) && (gtmp->ins->depth > EvaluationData(theEnv)->CurrentEvaluationDepth)
#if DEFRULE_CONSTRUCT
&& (gtmp->ins->header.busyCount == 0)
#endif
)
{
UtilityData(theEnv)->EphemeralItemCount -= 2;
UtilityData(theEnv)->EphemeralItemSize -= InstanceSizeHeuristic(gtmp->ins) + sizeof(IGARBAGE);
DecrementSymbolCount(theEnv,gtmp->ins->name);
rtn_struct(theEnv,instance,gtmp->ins);
if (gprv == NULL)
InstanceData(theEnv)->InstanceGarbageList = gtmp->nxt;
else
gprv->nxt = gtmp->nxt;
dump = gtmp;
gtmp = gtmp->nxt;
rtn_struct(theEnv,igarbage,dump);
}
else
{
gprv = gtmp;
gtmp = gtmp->nxt;
}
}
}
/*******************************************************
NAME : HashInstance
DESCRIPTION : Generates a hash index for a given
instance name
INPUTS : The address of the instance name SYMBOL_HN
RETURNS : The hash index value
SIDE EFFECTS : None
NOTES : Counts on the fact that the symbol
has already been hashed into the
symbol table - uses that hash value
multiplied by a prime for a new hash
*******************************************************/
globle unsigned HashInstance(
SYMBOL_HN *cname)
{
unsigned long tally;
tally = ((unsigned long) cname->bucket) * BIG_PRIME;
return((unsigned) (tally % INSTANCE_TABLE_HASH_SIZE));
}
/***************************************************
NAME : DestroyAllInstances
DESCRIPTION : Deallocates all instances,
reinitializes hash table and
resets class instance pointers
INPUTS : None
RETURNS : Nothing useful
SIDE EFFECTS : All instances deallocated
NOTES : None
***************************************************/
globle void DestroyAllInstances(
void *theEnv)
{
INSTANCE_TYPE *iptr;
int svmaintain;
SaveCurrentModule(theEnv);
svmaintain = InstanceData(theEnv)->MaintainGarbageInstances;
InstanceData(theEnv)->MaintainGarbageInstances = TRUE;
iptr = InstanceData(theEnv)->InstanceList;
while (iptr != NULL)
{
EnvSetCurrentModule(theEnv,(void *) iptr->cls->header.whichModule->theModule);
DirectMessage(theEnv,MessageHandlerData(theEnv)->DELETE_SYMBOL,iptr,NULL,NULL);
iptr = iptr->nxtList;
while ((iptr != NULL) ? iptr->garbage : FALSE)
iptr = iptr->nxtList;
}
InstanceData(theEnv)->MaintainGarbageInstances = svmaintain;
RestoreCurrentModule(theEnv);
}
/******************************************************
NAME : RemoveInstanceData
DESCRIPTION : Deallocates all the data objects
in instance slots and then dealloactes
the slots themeselves
INPUTS : The instance
RETURNS : Nothing useful
SIDE EFFECTS : Instance slots removed
NOTES : An instance made with CopyInstanceData
will have shared values removed
in all cases because they are not
"real" instances.
Instance class busy count decremented
******************************************************/
globle void RemoveInstanceData(
void *theEnv,
INSTANCE_TYPE *ins)
{
register unsigned i;
INSTANCE_SLOT *sp;
DecrementDefclassBusyCount(theEnv,(void *) ins->cls);
for (i = 0 ; i < ins->cls->instanceSlotCount ; i++)
{
sp = ins->slotAddresses[i];
if ((sp == &sp->desc->sharedValue) ?
(--sp->desc->sharedCount == 0) : TRUE)
{
if (sp->desc->multiple)
{
MultifieldDeinstall(theEnv,(MULTIFIELD_PTR) sp->value);
AddToMultifieldList(theEnv,(MULTIFIELD_PTR) sp->value);
}
else
AtomDeinstall(theEnv,(int) sp->type,sp->value);
sp->value = NULL;
}
}
if (ins->cls->instanceSlotCount != 0)
{
rm(theEnv,(void *) ins->slotAddresses,
(ins->cls->instanceSlotCount * sizeof(INSTANCE_SLOT *)));
if (ins->cls->localInstanceSlotCount != 0)
rm(theEnv,(void *) ins->slots,
(ins->cls->localInstanceSlotCount * sizeof(INSTANCE_SLOT)));
}
ins->slots = NULL;
ins->slotAddresses = NULL;
}
/***************************************************************************
NAME : FindInstanceBySymbol
DESCRIPTION : Looks up a specified instance in the instance hash table
INPUTS : The symbol for the name of the instance
RETURNS : The address of the found instance, NULL otherwise
SIDE EFFECTS : None
NOTES : An instance is searched for by name first in the
current module - then in imported modules according
to the order given in the current module's definition
***************************************************************************/
globle INSTANCE_TYPE *FindInstanceBySymbol(
void *theEnv,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -