📄 evaluatn.c
字号:
/* FunctionCall2: Allows Deffunctions and */
/* Generic Functions to be called from C. */
/* Allows only constants as arguments. */
/********************************************/
globle int FunctionCall2(
void *theEnv,
FUNCTION_REFERENCE *theReference,
char *args,
DATA_OBJECT *result)
{
EXPRESSION *argexps;
int error = FALSE;
/*=============================================*/
/* Force periodic cleanup if the function call */
/* was executed from an embedded application. */
/*=============================================*/
if ((EvaluationData(theEnv)->CurrentEvaluationDepth == 0) && (! CommandLineData(theEnv)->EvaluatingTopLevelCommand) &&
(EvaluationData(theEnv)->CurrentExpression == NULL))
{ PeriodicCleanup(theEnv,TRUE,FALSE); }
/*========================*/
/* Reset the error state. */
/*========================*/
if (EvaluationData(theEnv)->CurrentEvaluationDepth == 0) SetHaltExecution(theEnv,FALSE);
EvaluationData(theEnv)->EvaluationError = FALSE;
/*======================================*/
/* Initialize the default return value. */
/*======================================*/
result->type = SYMBOL;
result->value = EnvFalseSymbol(theEnv);
/*============================*/
/* Parse the argument string. */
/*============================*/
argexps = ParseConstantArguments(theEnv,args,&error);
if (error == TRUE) return(TRUE);
/*====================*/
/* Call the function. */
/*====================*/
theReference->argList = argexps;
error = EvaluateExpression(theEnv,theReference,result);
/*========================*/
/* Return the expression. */
/*========================*/
ReturnExpression(theEnv,argexps);
theReference->argList = NULL;
/*==========================*/
/* Return the error status. */
/*==========================*/
return(error);
}
#endif
/***************************************************/
/* CopyDataObject: Copies the values from a source */
/* DATA_OBJECT to a destination DATA_OBJECT. */
/***************************************************/
globle void CopyDataObject(
void *theEnv,
DATA_OBJECT *dst,
DATA_OBJECT *src,
int garbageMultifield)
{
if (src->type != MULTIFIELD)
{
dst->type = src->type;
dst->value = src->value;
}
else
{
DuplicateMultifield(theEnv,dst,src);
if (garbageMultifield)
{ AddToMultifieldList(theEnv,(struct multifield *) dst->value); }
}
}
/***********************************************/
/* TransferDataObjectValues: Copies the values */
/* directly from a source DATA_OBJECT to a */
/* destination DATA_OBJECT. */
/***********************************************/
globle void TransferDataObjectValues(
DATA_OBJECT *dst,
DATA_OBJECT *src)
{
dst->type = src->type;
dst->value = src->value;
dst->begin = src->begin;
dst->end = src->end;
dst->supplementalInfo = src->supplementalInfo;
dst->next = src->next;
}
/************************************************************************/
/* ConvertValueToExpression: Converts the value stored in a data object */
/* into an expression. For multifield values, a chain of expressions */
/* is generated and the chain is linked by the nextArg field. For a */
/* single field value, a single expression is created. */
/************************************************************************/
globle struct expr *ConvertValueToExpression(
void *theEnv,
DATA_OBJECT *theValue)
{
long i;
struct expr *head = NULL, *last = NULL, *newItem;
if (GetpType(theValue) != MULTIFIELD)
{ return(GenConstant(theEnv,GetpType(theValue),GetpValue(theValue))); }
for (i = GetpDOBegin(theValue); i <= GetpDOEnd(theValue); i++)
{
newItem = GenConstant(theEnv,GetMFType(GetpValue(theValue),i),
GetMFValue(GetpValue(theValue),i));
if (last == NULL) head = newItem;
else last->nextArg = newItem;
last = newItem;
}
if (head == NULL)
return(GenConstant(theEnv,FCALL,(void *) FindFunction(theEnv,"create$")));
return(head);
}
/****************************************/
/* GetAtomicHashValue: Returns the hash */
/* value for an atomic data type. */
/****************************************/
unsigned int GetAtomicHashValue(
unsigned short type,
void *value,
int position)
{
unsigned int tvalue;
union
{
double fv;
unsigned int liv;
} fis;
switch (type)
{
case FLOAT:
fis.fv = ValueToDouble(value);
tvalue = fis.liv;
break;
case INTEGER:
tvalue = (unsigned int) ValueToLong(value);
break;
case FACT_ADDRESS:
#if OBJECT_SYSTEM
case INSTANCE_ADDRESS:
#endif
case EXTERNAL_ADDRESS:
tvalue = (unsigned int) value;
break;
case STRING:
#if OBJECT_SYSTEM
case INSTANCE_NAME:
#endif
case SYMBOL:
tvalue = ((SYMBOL_HN *) value)->bucket;
break;
default:
tvalue = type;
}
if (position < 0) return(tvalue);
return((unsigned int) (tvalue * (position + 29)));
}
/***********************************************************/
/* FunctionReferenceExpression: Returns an expression with */
/* an appropriate expression reference to the specified */
/* name if it is the name of a deffunction, defgeneric, */
/* or user/system defined function. */
/***********************************************************/
globle struct expr *FunctionReferenceExpression(
void *theEnv,
char *name)
{
#if DEFGENERIC_CONSTRUCT
void *gfunc;
#endif
#if DEFFUNCTION_CONSTRUCT
void *dptr;
#endif
struct FunctionDefinition *fptr;
/*=====================================================*/
/* Check to see if the function call is a deffunction. */
/*=====================================================*/
#if DEFFUNCTION_CONSTRUCT
if ((dptr = (void *) LookupDeffunctionInScope(theEnv,name)) != NULL)
{ return(GenConstant(theEnv,PCALL,dptr)); }
#endif
/*====================================================*/
/* Check to see if the function call is a defgeneric. */
/*====================================================*/
#if DEFGENERIC_CONSTRUCT
if ((gfunc = (void *) LookupDefgenericInScope(theEnv,name)) != NULL)
{ return(GenConstant(theEnv,GCALL,gfunc)); }
#endif
/*======================================*/
/* Check to see if the function call is */
/* a system or user defined function. */
/*======================================*/
if ((fptr = FindFunction(theEnv,name)) != NULL)
{ return(GenConstant(theEnv,FCALL,fptr)); }
/*===================================================*/
/* The specified function name is not a deffunction, */
/* defgeneric, or user/system defined function. */
/*===================================================*/
return(NULL);
}
/******************************************************************/
/* GetFunctionReference: Fills an expression with an appropriate */
/* expression reference to the specified name if it is the */
/* name of a deffunction, defgeneric, or user/system defined */
/* function. */
/******************************************************************/
globle intBool GetFunctionReference(
void *theEnv,
char *name,
FUNCTION_REFERENCE *theReference)
{
#if DEFGENERIC_CONSTRUCT
void *gfunc;
#endif
#if DEFFUNCTION_CONSTRUCT
void *dptr;
#endif
struct FunctionDefinition *fptr;
theReference->nextArg = NULL;
theReference->argList = NULL;
theReference->type = RVOID;
theReference->value = NULL;
/*=====================================================*/
/* Check to see if the function call is a deffunction. */
/*=====================================================*/
#if DEFFUNCTION_CONSTRUCT
if ((dptr = (void *) LookupDeffunctionInScope(theEnv,name)) != NULL)
{
theReference->type = PCALL;
theReference->value = dptr;
return(TRUE);
}
#endif
/*====================================================*/
/* Check to see if the function call is a defgeneric. */
/*====================================================*/
#if DEFGENERIC_CONSTRUCT
if ((gfunc = (void *) LookupDefgenericInScope(theEnv,name)) != NULL)
{
theReference->type = GCALL;
theReference->value = gfunc;
return(TRUE);
}
#endif
/*======================================*/
/* Check to see if the function call is */
/* a system or user defined function. */
/*======================================*/
if ((fptr = FindFunction(theEnv,name)) != NULL)
{
theReference->type = FCALL;
theReference->value = fptr;
return(TRUE);
}
/*===================================================*/
/* The specified function name is not a deffunction, */
/* defgeneric, or user/system defined function. */
/*===================================================*/
return(FALSE);
}
/*******************************************************/
/* DOsEqual: Determines if two DATA_OBJECTS are equal. */
/*******************************************************/
globle intBool DOsEqual(
DATA_OBJECT_PTR dobj1,
DATA_OBJECT_PTR dobj2)
{
if (GetpType(dobj1) != GetpType(dobj2))
{ return(FALSE); }
if (GetpType(dobj1) == MULTIFIELD)
{
if (MultifieldDOsEqual(dobj1,dobj2) == FALSE)
{ return(FALSE); }
}
else if (GetpValue(dobj1) != GetpValue(dobj2))
{ return(FALSE); }
return(TRUE);
}
/***********************************************************
NAME : EvaluateAndStoreInDataObject
DESCRIPTION : Evaluates slot-value expressions
and stores the result in a
Kernel data object
INPUTS : 1) Flag indicating if multifields are OK
2) The value-expression
3) The data object structure
4) Flag indicating if a multifield value
should be placed on the garbage list.
RETURNS : FALSE on errors, TRUE otherwise
SIDE EFFECTS : Segment allocated for storing
multifield values
NOTES : None
***********************************************************/
globle int EvaluateAndStoreInDataObject(
void *theEnv,
int mfp,
EXPRESSION *theExp,
DATA_OBJECT *val,
int garbageSegment)
{
val->type = MULTIFIELD;
val->begin = 0;
val->end = -1;
if (theExp == NULL)
{
if (garbageSegment) val->value = EnvCreateMultifield(theEnv,0L);
else val->value = CreateMultifield2(theEnv,0L);
return(TRUE);
}
if ((mfp == 0) && (theExp->nextArg == NULL))
EvaluateExpression(theEnv,theExp,val);
else
StoreInMultifield(theEnv,val,theExp,garbageSegment);
return(EvaluationData(theEnv)->EvaluationError ? FALSE : TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -