📄 miscfun.c
字号:
func->restrictions,CountArguments(newargexp)) == FALSE)
{
result->type = SYMBOL;
result->value = EnvFalseSymbol(theEnv);
ReturnExpression(theEnv,fcallexp);
return;
}
}
#if DEFFUNCTION_CONSTRUCT
else if (fcallexp->type == PCALL)
{
if (CheckDeffunctionCall(theEnv,fcallexp->value,
CountArguments(fcallexp->argList)) == FALSE)
{
result->type = SYMBOL;
result->value = EnvFalseSymbol(theEnv);
ReturnExpression(theEnv,fcallexp);
SetEvaluationError(theEnv,TRUE);
return;
}
}
#endif
EvaluateExpression(theEnv,fcallexp,result);
ReturnExpression(theEnv,fcallexp);
}
/***********************************************************************
NAME : DummyExpandFuncMultifield
DESCRIPTION : The expansion of multifield arguments is valid only
when done for a function call. All these expansions
are handled by the H/L wrap-around function
(expansion-call) - see ExpandFuncCall. If the H/L
function, epand-multifield is ever called directly,
it is an error.
INPUTS : Data object buffer
RETURNS : Nothing useful
SIDE EFFECTS : EvaluationError set
NOTES : None
**********************************************************************/
globle void DummyExpandFuncMultifield(
void *theEnv,
DATA_OBJECT *result)
{
result->type = SYMBOL;
result->value = EnvFalseSymbol(theEnv);
SetEvaluationError(theEnv,TRUE);
PrintErrorID(theEnv,"MISCFUN",1,FALSE);
EnvPrintRouter(theEnv,WERROR,"expand$ must be used in the argument list of a function call.\n");
}
/***********************************************************************
NAME : ExpandFuncMultifield
DESCRIPTION : Recursively examines an expression and replaces
PROC_EXPAND_MULTIFIELD expressions with the expanded
evaluation expression of its argument
INPUTS : 1) A data object result buffer
2) The expression to modify
3) The address of the expression, in case it is
deleted entirely
4) The address of the H/L function expand$
RETURNS : Nothing useful
SIDE EFFECTS : Expressions allocated/deallocated as necessary
Evaluations performed
On errors, argument expression set to call a function
which causes an evaluation error when evaluated
a second time by actual caller.
NOTES : THIS ROUTINE MODIFIES EXPRESSIONS AT RUNTIME!! MAKE
SURE THAT THE EXPRESSION PASSED IS SAFE TO CHANGE!!
**********************************************************************/
static void ExpandFuncMultifield(
void *theEnv,
DATA_OBJECT *result,
EXPRESSION *theExp,
EXPRESSION **sto,
void *expmult)
{
EXPRESSION *newexp,*top,*bot;
register long i; /* 6.04 Bug Fix */
while (theExp != NULL)
{
if (theExp->value == expmult)
{
EvaluateExpression(theEnv,theExp->argList,result);
ReturnExpression(theEnv,theExp->argList);
if ((EvaluationData(theEnv)->EvaluationError) || (result->type != MULTIFIELD))
{
theExp->argList = NULL;
if ((EvaluationData(theEnv)->EvaluationError == FALSE) && (result->type != MULTIFIELD))
ExpectedTypeError2(theEnv,"expand$",1);
theExp->value = (void *) FindFunction(theEnv,"(set-evaluation-error)");
EvaluationData(theEnv)->EvaluationError = FALSE;
EvaluationData(theEnv)->HaltExecution = FALSE;
return;
}
top = bot = NULL;
for (i = GetpDOBegin(result) ; i <= GetpDOEnd(result) ; i++)
{
newexp = get_struct(theEnv,expr);
newexp->type = GetMFType(result->value,i);
newexp->value = GetMFValue(result->value,i);
newexp->argList = NULL;
newexp->nextArg = NULL;
if (top == NULL)
top = newexp;
else
bot->nextArg = newexp;
bot = newexp;
}
if (top == NULL)
{
*sto = theExp->nextArg;
rtn_struct(theEnv,expr,theExp);
theExp = *sto;
}
else
{
bot->nextArg = theExp->nextArg;
*sto = top;
rtn_struct(theEnv,expr,theExp);
sto = &bot->nextArg;
theExp = bot->nextArg;
}
}
else
{
if (theExp->argList != NULL)
ExpandFuncMultifield(theEnv,result,theExp->argList,&theExp->argList,expmult);
sto = &theExp->nextArg;
theExp = theExp->nextArg;
}
}
}
/****************************************************************
NAME : CauseEvaluationError
DESCRIPTION : Dummy function use to cause evaluation errors on
a function call to generate error messages
INPUTS : None
RETURNS : A pointer to the FalseSymbol
SIDE EFFECTS : EvaluationError set
NOTES : None
****************************************************************/
globle void *CauseEvaluationError(
void *theEnv)
{
SetEvaluationError(theEnv,TRUE);
return((SYMBOL_HN *) EnvFalseSymbol(theEnv));
}
/****************************************************************
NAME : SetSORCommand
DESCRIPTION : Toggles SequenceOpMode - if TRUE, multifield
references are replaced with sequence
expansion operators
INPUTS : None
RETURNS : The old value of SequenceOpMode
SIDE EFFECTS : SequenceOpMode toggled
NOTES : None
****************************************************************/
globle intBool SetSORCommand(
void *theEnv)
{
#if (! RUN_TIME) && (! BLOAD_ONLY)
DATA_OBJECT arg;
if (EnvArgTypeCheck(theEnv,"set-sequence-operator-recognition",1,SYMBOL,&arg) == FALSE)
return(ExpressionData(theEnv)->SequenceOpMode);
return(EnvSetSequenceOperatorRecognition(theEnv,(arg.value == EnvFalseSymbol(theEnv)) ?
FALSE : TRUE));
#else
return(ExpressionData(theEnv)->SequenceOpMode);
#endif
}
/********************************************************************
NAME : GetFunctionRestrictions
DESCRIPTION : Gets DefineFunction2() restriction list for function
INPUTS : None
RETURNS : A string containing the function restriction codes
SIDE EFFECTS : EvaluationError set on errors
NOTES : None
********************************************************************/
globle void *GetFunctionRestrictions(
void *theEnv)
{
DATA_OBJECT temp;
struct FunctionDefinition *fptr;
if (EnvArgTypeCheck(theEnv,"get-function-restrictions",1,SYMBOL,&temp) == FALSE)
return((SYMBOL_HN *) EnvAddSymbol(theEnv,""));
fptr = FindFunction(theEnv,DOToString(temp));
if (fptr == NULL)
{
CantFindItemErrorMessage(theEnv,"function",DOToString(temp));
SetEvaluationError(theEnv,TRUE);
return((SYMBOL_HN *) EnvAddSymbol(theEnv,""));
}
if (fptr->restrictions == NULL)
return((SYMBOL_HN *) EnvAddSymbol(theEnv,"0**"));
return((SYMBOL_HN *) EnvAddSymbol(theEnv,fptr->restrictions));
}
/*************************************************/
/* GetFunctionListFunction: H/L access routine */
/* for the get-function-list function. */
/*************************************************/
globle void GetFunctionListFunction(
void *theEnv,
DATA_OBJECT *returnValue)
{
struct FunctionDefinition *theFunction;
struct multifield *theList;
unsigned long functionCount = 0;
if (EnvArgCountCheck(theEnv,"get-function-list",EXACTLY,0) == -1)
{
EnvSetMultifieldErrorValue(theEnv,returnValue);
return;
}
for (theFunction = GetFunctionList(theEnv);
theFunction != NULL;
theFunction = theFunction->next)
{ functionCount++; }
SetpType(returnValue,MULTIFIELD);
SetpDOBegin(returnValue,1);
SetpDOEnd(returnValue,functionCount);
theList = (struct multifield *) EnvCreateMultifield(theEnv,functionCount);
SetpValue(returnValue,(void *) theList);
for (theFunction = GetFunctionList(theEnv), functionCount = 1;
theFunction != NULL;
theFunction = theFunction->next, functionCount++)
{
SetMFType(theList,functionCount,SYMBOL);
SetMFValue(theList,functionCount,theFunction->callFunctionName);
}
}
/***************************************/
/* FuncallFunction: H/L access routine */
/* for the funcall function. */
/***************************************/
globle void FuncallFunction(
void *theEnv,
DATA_OBJECT *returnValue)
{
int argCount, i, j;
DATA_OBJECT theValue;
FUNCTION_REFERENCE theReference;
char *name;
struct multifield *theMultifield;
struct expr *lastAdd = NULL, *nextAdd, *multiAdd;
/*==================================*/
/* Set up the default return value. */
/*==================================*/
SetpType(returnValue,SYMBOL);
SetpValue(returnValue,EnvFalseSymbol(theEnv));
/*=================================================*/
/* The funcall function has at least one argument: */
/* the name of the function being called. */
/*=================================================*/
if ((argCount = EnvArgCountCheck(theEnv,"funcall",AT_LEAST,1)) == -1) return;
/*============================================*/
/* Get the name of the function to be called. */
/*============================================*/
if (EnvArgTypeCheck(theEnv,"funcall",1,SYMBOL_OR_STRING,&theValue) == FALSE)
{ return; }
/*====================*/
/* Find the function. */
/*====================*/
name = DOToString(theValue);
if (! GetFunctionReference(theEnv,name,&theReference))
{
ExpectedTypeError1(theEnv,"funcall",1,"function, deffunction, or generic function name");
return;
}
ExpressionInstall(theEnv,&theReference);
/*======================================*/
/* Add the arguments to the expression. */
/*======================================*/
for (i = 2; i <= argCount; i++)
{
EnvRtnUnknown(theEnv,i,&theValue);
if (GetEvaluationError(theEnv))
{
ExpressionDeinstall(theEnv,&theReference);
return;
}
switch(GetType(theValue))
{
case MULTIFIELD:
nextAdd = GenConstant(theEnv,FCALL,(void *) FindFunction(theEnv,"create$"));
if (lastAdd == NULL)
{ theReference.argList = nextAdd; }
else
{ lastAdd->nextArg = nextAdd; }
lastAdd = nextAdd;
multiAdd = NULL;
theMultifield = (struct multifield *) GetValue(theValue);
for (j = GetDOBegin(theValue); j <= GetDOEnd(theValue); j++)
{
nextAdd = GenConstant(theEnv,GetMFType(theMultifield,j),GetMFValue(theMultifield,j));
if (multiAdd == NULL)
{ lastAdd->argList = nextAdd; }
else
{ multiAdd->nextArg = nextAdd; }
multiAdd = nextAdd;
}
ExpressionInstall(theEnv,lastAdd);
break;
default:
nextAdd = GenConstant(theEnv,GetType(theValue),GetValue(theValue));
if (lastAdd == NULL)
{ theReference.argList = nextAdd; }
else
{ lastAdd->nextArg = nextAdd; }
lastAdd = nextAdd;
ExpressionInstall(theEnv,lastAdd);
break;
}
}
/*===========================================================*/
/* Verify a deffunction has the correct number of arguments. */
/*===========================================================*/
#if DEFFUNCTION_CONSTRUCT
if (theReference.type == PCALL)
{
if (CheckDeffunctionCall(theEnv,theReference.value,CountArguments(theReference.argList)) == FALSE)
{
PrintErrorID(theEnv,"MISCFUN",4,FALSE);
EnvPrintRouter(theEnv,WERROR,"Function funcall called with the wrong number of arguments for deffunction ");
EnvPrintRouter(theEnv,WERROR,EnvGetDeffunctionName(theEnv,theReference.value));
EnvPrintRouter(theEnv,WERROR,"\n");
ExpressionDeinstall(theEnv,&theReference);
ReturnExpression(theEnv,theReference.argList);
return;
}
}
#endif
/*======================*/
/* Call the expression. */
/*======================*/
EvaluateExpression(theEnv,&theReference,returnValue);
/*========================================*/
/* Return the expression data structures. */
/*========================================*/
ExpressionDeinstall(theEnv,&theReference);
ReturnExpression(theEnv,theReference.argList);
}
/************************************/
/* TimeFunction: H/L access routine */
/* for the time function. */
/************************************/
globle double TimeFunction(
void *theEnv)
{
/*=========================================*/
/* The time function accepts no arguments. */
/*=========================================*/
EnvArgCountCheck(theEnv,"time",EXACTLY,0);
/*==================*/
/* Return the time. */
/*==================*/
return(gentime());
}
/***************************************/
/* TimerFunction: H/L access routine */
/* for the timer function. */
/***************************************/
globle double TimerFunction(
void *theEnv)
{
int numa, i;
double startTime;
DATA_OBJECT returnValue;
startTime = gentime();
numa = EnvRtnArgCount(theEnv);
i = 1;
while ((i <= numa) && (GetHaltExecution(theEnv) != TRUE))
{
EnvRtnUnknown(theEnv,i,&returnValue);
i++;
}
return(gentime() - startTime);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -