📄 genrccom.c
字号:
RETURNS : Nothing useful
SIDE EFFECTS : Multifield set to list of method indices
NOTES : None
***********************************************************/
globle void EnvGetDefmethodList(
void *theEnv,
void *vgfunc,
DATA_OBJECT_PTR returnValue)
{
DEFGENERIC *gfunc,*svg,*svnxt;
unsigned i,j;
unsigned long count;
MULTIFIELD_PTR theList;
if (vgfunc != NULL)
{
gfunc = (DEFGENERIC *) vgfunc;
svnxt = (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,vgfunc);
SetNextDefgeneric(vgfunc,NULL);
}
else
{
gfunc = (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,NULL);
svnxt = (gfunc != NULL) ? (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,(void *) gfunc) : NULL;
}
count = 0;
for (svg = gfunc ;
gfunc != NULL ;
gfunc = (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,(void *) gfunc))
count += (unsigned long) gfunc->mcnt;
count *= 2;
SetpType(returnValue,MULTIFIELD);
SetpDOBegin(returnValue,1);
SetpDOEnd(returnValue,count);
theList = (MULTIFIELD_PTR) EnvCreateMultifield(theEnv,count);
SetpValue(returnValue,theList);
for (gfunc = svg , i = 1 ;
gfunc != NULL ;
gfunc = (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,(void *) gfunc))
{
for (j = 0 ; j < gfunc->mcnt ; j++)
{
SetMFType(theList,i,SYMBOL);
SetMFValue(theList,i++,GetDefgenericNamePointer((void *) gfunc));
SetMFType(theList,i,INTEGER);
SetMFValue(theList,i++,EnvAddLong(theEnv,(long) gfunc->methods[j].index));
}
}
if (svg != NULL)
SetNextDefgeneric((void *) svg,(void *) svnxt);
}
/***********************************************************************************
NAME : GetMethodRestrictionsCommand
DESCRIPTION : Stores restrictions of a method in multifield
INPUTS : A data object buffer to hold a multifield
RETURNS : Nothing useful
SIDE EFFECTS : Multifield created (length zero on errors)
NOTES : Syntax: (get-method-restrictions <generic-function> <method-index>)
***********************************************************************************/
globle void GetMethodRestrictionsCommand(
void *theEnv,
DATA_OBJECT *result)
{
DATA_OBJECT temp;
DEFGENERIC *gfunc;
if (EnvArgTypeCheck(theEnv,"get-method-restrictions",1,SYMBOL,&temp) == FALSE)
{
EnvSetMultifieldErrorValue(theEnv,result);
return;
}
gfunc = CheckGenericExists(theEnv,"get-method-restrictions",DOToString(temp));
if (gfunc == NULL)
{
EnvSetMultifieldErrorValue(theEnv,result);
return;
}
if (EnvArgTypeCheck(theEnv,"get-method-restrictions",2,INTEGER,&temp) == FALSE)
{
EnvSetMultifieldErrorValue(theEnv,result);
return;
}
if (CheckMethodExists(theEnv,"get-method-restrictions",gfunc,DOToInteger(temp)) == -1)
{
EnvSetMultifieldErrorValue(theEnv,result);
return;
}
EnvGetMethodRestrictions(theEnv,(void *) gfunc,(unsigned) DOToInteger(temp),result);
}
/***********************************************************************
NAME : EnvGetMethodRestrictions
DESCRIPTION : Stores restrictions of a method in multifield
INPUTS : 1) Pointer to the generic function
2) The method index
3) A data object buffer to hold a multifield
RETURNS : Nothing useful
SIDE EFFECTS : Multifield created (length zero on errors)
NOTES : The restrictions are stored in the multifield
in the following format:
<min-number-of-arguments>
<max-number-of-arguments> (-1 if wildcard allowed)
<restriction-count>
<index of 1st restriction>
.
.
<index of nth restriction>
<restriction 1>
<query TRUE/FALSE>
<number-of-classes>
<class 1>
.
.
<class n>
.
.
.
<restriction n>
Thus, for the method
(defmethod foo ((?a NUMBER SYMBOL) (?b (= 1 1)) $?c))
(get-method-restrictions foo 1) would yield
(2 -1 3 7 11 13 FALSE 2 NUMBER SYMBOL TRUE 0 FALSE 0)
***********************************************************************/
globle void EnvGetMethodRestrictions(
void *theEnv,
void *vgfunc,
unsigned mi,
DATA_OBJECT *result)
{
register unsigned i,j;
register DEFMETHOD *meth;
register RESTRICTION *rptr;
unsigned count;
int roffset,rstrctIndex;
MULTIFIELD_PTR theList;
meth = ((DEFGENERIC *) vgfunc)->methods + FindMethodByIndex((DEFGENERIC *) vgfunc,mi);
count = 3;
for (i = 0 ; i < (unsigned) meth->restrictionCount ; i++)
count += meth->restrictions[i].tcnt + 3;
theList = (MULTIFIELD_PTR) EnvCreateMultifield(theEnv,count);
SetpType(result,MULTIFIELD);
SetpValue(result,theList);
SetpDOBegin(result,1);
SetpDOEnd(result,count);
SetMFType(theList,1,INTEGER);
SetMFValue(theList,1,EnvAddLong(theEnv,(long) meth->minRestrictions));
SetMFType(theList,2,INTEGER);
SetMFValue(theList,2,EnvAddLong(theEnv,(long) meth->maxRestrictions));
SetMFType(theList,3,INTEGER);
SetMFValue(theList,3,EnvAddLong(theEnv,(long) meth->restrictionCount));
roffset = 3 + meth->restrictionCount + 1;
rstrctIndex = 4;
for (i = 0 ; i < (unsigned) meth->restrictionCount ; i++)
{
rptr = meth->restrictions + i;
SetMFType(theList,rstrctIndex,INTEGER);
SetMFValue(theList,rstrctIndex++,EnvAddLong(theEnv,(long) roffset));
SetMFType(theList,roffset,SYMBOL);
SetMFValue(theList,roffset++,(rptr->query != NULL) ? EnvTrueSymbol(theEnv) : EnvFalseSymbol(theEnv));
SetMFType(theList,roffset,INTEGER);
SetMFValue(theList,roffset++,EnvAddLong(theEnv,(long) rptr->tcnt));
for (j = 0 ; j < rptr->tcnt ; j++)
{
SetMFType(theList,roffset,SYMBOL);
#if OBJECT_SYSTEM
SetMFValue(theList,roffset++,EnvAddSymbol(theEnv,EnvGetDefclassName(theEnv,rptr->types[j])));
#else
SetMFValue(theList,roffset++,EnvAddSymbol(theEnv,TypeName(theEnv,ValueToInteger(rptr->types[j]))));
#endif
}
}
}
/* =========================================
*****************************************
INTERNALLY VISIBLE FUNCTIONS
=========================================
***************************************** */
/***************************************************
NAME : PrintGenericCall
DESCRIPTION : PrintExpression() support function
for generic function calls
INPUTS : 1) The output logical name
2) The generic function
RETURNS : Nothing useful
SIDE EFFECTS : Call expression printed
NOTES : None
***************************************************/
#if IBM_TBC && (! DEVELOPER)
#pragma argsused
#endif
static void PrintGenericCall(
void *theEnv,
char *logName,
void *value)
{
#if DEVELOPER
EnvPrintRouter(theEnv,logName,"(");
EnvPrintRouter(theEnv,logName,EnvGetDefgenericName(theEnv,value));
if (GetFirstArgument() != NULL)
{
EnvPrintRouter(theEnv,logName," ");
PrintExpression(theEnv,logName,GetFirstArgument());
}
EnvPrintRouter(theEnv,logName,")");
#else
#if MAC_MCW || IBM_MCW || MAC_XCD
#pragma unused(theEnv)
#pragma unused(logName)
#pragma unused(value)
#endif
#endif
}
/*******************************************************
NAME : EvaluateGenericCall
DESCRIPTION : Primitive support function for
calling a generic function
INPUTS : 1) The generic function
2) A data object buffer to hold
the evaluation result
RETURNS : FALSE if the generic function
returns the symbol FALSE,
TRUE otherwise
SIDE EFFECTS : Data obejct buffer set and any
side-effects of calling the generic
NOTES : None
*******************************************************/
static intBool EvaluateGenericCall(
void *theEnv,
void *value,
DATA_OBJECT *result)
{
GenericDispatch(theEnv,(DEFGENERIC *) value,NULL,NULL,GetFirstArgument(),result);
if ((GetpType(result) == SYMBOL) &&
(GetpValue(result) == EnvFalseSymbol(theEnv)))
return(FALSE);
return(TRUE);
}
/***************************************************
NAME : DecrementGenericBusyCount
DESCRIPTION : Lowers the busy count of a
generic function construct
INPUTS : The generic function
RETURNS : Nothing useful
SIDE EFFECTS : Busy count decremented if a clear
is not in progress (see comment)
NOTES : None
***************************************************/
static void DecrementGenericBusyCount(
void *theEnv,
void *value)
{
/* ==============================================
The generics to which expressions in other
constructs may refer may already have been
deleted - thus, it is important not to modify
the busy flag during a clear.
============================================== */
if (! ConstructData(theEnv)->ClearInProgress)
((DEFGENERIC *) value)->busy--;
}
/***************************************************
NAME : IncrementGenericBusyCount
DESCRIPTION : Raises the busy count of a
generic function construct
INPUTS : The generic function
RETURNS : Nothing useful
SIDE EFFECTS : Busy count incremented
NOTES : None
***************************************************/
#if IBM_TBC
#pragma argsused
#endif
static void IncrementGenericBusyCount(
void *theEnv,
void *value)
{
#if MAC_MCW || IBM_MCW || MAC_XCD
#pragma unused(theEnv)
#endif
((DEFGENERIC *) value)->busy++;
}
#if (! BLOAD_ONLY) && (! RUN_TIME)
/**********************************************************************
NAME : SaveDefgenerics
DESCRIPTION : Outputs pretty-print forms of generic function headers
INPUTS : The logical name of the output
RETURNS : Nothing useful
SIDE EFFECTS : None
NOTES : None
**********************************************************************/
static void SaveDefgenerics(
void *theEnv,
void *theModule,
char *logName)
{
SaveConstruct(theEnv,theModule,logName,DefgenericData(theEnv)->DefgenericConstruct);
}
/**********************************************************************
NAME : SaveDefmethods
DESCRIPTION : Outputs pretty-print forms of generic function methods
INPUTS : The logical name of the output
RETURNS : Nothing useful
SIDE EFFECTS : None
NOTES : None
**********************************************************************/
static void SaveDefmethods(
void *theEnv,
void *theModule,
char *logName)
{
DoForAllConstructsInModule(theEnv,theModule,SaveDefmethodsForDefgeneric,
DefgenericData(theEnv)->DefgenericModuleIndex,
FALSE,(void *) logName);
}
/***************************************************
NAME : SaveDefmethodsForDefgeneric
DESCRIPTION : Save the pretty-print forms of
all methods for a generic function
to a file
INPUTS : 1) The defgeneric
2) The logical name of the output
RETURNS : Nothing useful
SIDE EFFECTS : Methods written
NOTES : None
***************************************************/
static void SaveDefmethodsForDefgeneric(
void *theEnv,
struct constructHeader *theDefgeneric,
void *userBuffer)
{
DEFGENERIC *gfunc = (DEFGENERIC *) theDefgeneric;
char *logName = (char *) userBuffer;
register unsigned i;
for (i = 0 ; i < gfunc->mcnt ; i++)
{
if (gfunc->methods[i].ppForm != NULL)
{
PrintInChunks(theEnv,logName,gfunc->methods[i].ppForm);
EnvPrintRouter(theEnv,logName,"\n");
}
}
}
/****************************************************
NAME : RemoveDefgenericMethod
DESCRIPTION : Removes a generic function method
from the array and removes the
generic too if its the last method
INPUTS : 1) The generic function
2) The array index of the method
RETURNS : Nothing useful
SIDE EFFECTS : List adjusted
Nodes deallocated
NOTES : Assumes deletion is safe
****************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -