📄 exprnops.c
字号:
/************************************************************/
/* ExpressionContainsVariables: Determines if an expression */
/* contains any variables. Returns TRUE if the expression */
/* contains any variables, otherwise FALSE is returned. */
/************************************************************/
globle intBool ExpressionContainsVariables(
struct expr *theExpression,
intBool globalsAreVariables)
{
while (theExpression != NULL)
{
if (theExpression->argList != NULL)
{
if (ExpressionContainsVariables(theExpression->argList,globalsAreVariables))
{ return(TRUE); }
}
if ((theExpression->type == MF_VARIABLE) ||
(theExpression->type == SF_VARIABLE) ||
(theExpression->type == FACT_ADDRESS) ||
(((theExpression->type == GBL_VARIABLE) ||
(theExpression->type == MF_GBL_VARIABLE)) &&
(globalsAreVariables == TRUE)))
{ return(TRUE); }
theExpression = theExpression->nextArg;
}
return(FALSE);
}
/*****************************************/
/* ExpressionSize: Returns the number of */
/* structures stored in an expression. */
/*****************************************/
globle long ExpressionSize(
struct expr *testPtr)
{
long size = 0;
while (testPtr != NULL)
{
size++;
if (testPtr->argList != NULL)
{ size += ExpressionSize(testPtr->argList); }
testPtr = testPtr->nextArg;
}
return(size);
}
/************************************************/
/* GenConstant: Generates a constant expression */
/* value of type string, symbol, or number. */
/************************************************/
globle struct expr *GenConstant(
void *theEnv,
unsigned short type,
void *value)
{
struct expr *top;
top = get_struct(theEnv,expr);
top->nextArg = NULL;
top->argList = NULL;
top->type = type;
top->value = value;
return(top);
}
/*************************************************/
/* PrintExpression: Pretty prints an expression. */
/*************************************************/
globle void PrintExpression(
void *theEnv,
char *fileid,
struct expr *theExpression)
{
struct expr *oldExpression;
if (theExpression == NULL)
{ return; }
while (theExpression != NULL)
{
switch (theExpression->type)
{
case SF_VARIABLE:
case GBL_VARIABLE:
EnvPrintRouter(theEnv,fileid,"?");
EnvPrintRouter(theEnv,fileid,ValueToString(theExpression->value));
break;
case MF_VARIABLE:
case MF_GBL_VARIABLE:
EnvPrintRouter(theEnv,fileid,"$?");
EnvPrintRouter(theEnv,fileid,ValueToString(theExpression->value));
break;
case FCALL:
EnvPrintRouter(theEnv,fileid,"(");
EnvPrintRouter(theEnv,fileid,ValueToString(ExpressionFunctionCallName(theExpression)));
if (theExpression->argList != NULL) { EnvPrintRouter(theEnv,fileid," "); }
PrintExpression(theEnv,fileid,theExpression->argList);
EnvPrintRouter(theEnv,fileid,")");
break;
default:
oldExpression = EvaluationData(theEnv)->CurrentExpression;
EvaluationData(theEnv)->CurrentExpression = theExpression;
PrintAtom(theEnv,fileid,theExpression->type,theExpression->value);
EvaluationData(theEnv)->CurrentExpression = oldExpression;
break;
}
theExpression = theExpression->nextArg;
if (theExpression != NULL) EnvPrintRouter(theEnv,fileid," ");
}
return;
}
/*************************************************************************/
/* CombineExpressions: Combines two expressions into a single equivalent */
/* expression. Mainly serves to merge expressions containing "and" */
/* and "or" expressions without unnecessary duplication of the "and" */
/* and "or" expressions (i.e., two "and" expressions can be merged by */
/* placing them as arguments within another "and" expression, but it */
/* is more efficient to add the arguments of one of the "and" */
/* expressions to the list of arguments for the other and expression). */
/*************************************************************************/
globle struct expr *CombineExpressions(
void *theEnv,
struct expr *expr1,
struct expr *expr2)
{
struct expr *tempPtr;
/*===========================================================*/
/* If the 1st expression is NULL, return the 2nd expression. */
/*===========================================================*/
if (expr1 == NULL) return(expr2);
/*===========================================================*/
/* If the 2nd expression is NULL, return the 1st expression. */
/*===========================================================*/
if (expr2 == NULL) return(expr1);
/*============================================================*/
/* If the 1st expression is an "and" expression, and the 2nd */
/* expression is not an "and" expression, then include the */
/* 2nd expression in the argument list of the 1st expression. */
/*============================================================*/
if ((expr1->value == ExpressionData(theEnv)->PTR_AND) &&
(expr2->value != ExpressionData(theEnv)->PTR_AND))
{
tempPtr = expr1->argList;
if (tempPtr == NULL)
{
rtn_struct(theEnv,expr,expr1);
return(expr2);
}
while (tempPtr->nextArg != NULL)
{ tempPtr = tempPtr->nextArg; }
tempPtr->nextArg = expr2;
return(expr1);
}
/*============================================================*/
/* If the 2nd expression is an "and" expression, and the 1st */
/* expression is not an "and" expression, then include the */
/* 1st expression in the argument list of the 2nd expression. */
/*============================================================*/
if ((expr1->value != ExpressionData(theEnv)->PTR_AND) &&
(expr2->value == ExpressionData(theEnv)->PTR_AND))
{
tempPtr = expr2->argList;
if (tempPtr == NULL)
{
rtn_struct(theEnv,expr,expr2);
return(expr1);
}
expr2->argList = expr1;
expr1->nextArg = tempPtr;
return(expr2);
}
/*===========================================================*/
/* If both expressions are "and" expressions, then add the */
/* 2nd expression to the argument list of the 1st expression */
/* and throw away the extraneous "and" expression. */
/*===========================================================*/
if ((expr1->value == ExpressionData(theEnv)->PTR_AND) &&
(expr2->value == ExpressionData(theEnv)->PTR_AND))
{
tempPtr = expr1->argList;
if (tempPtr == NULL)
{
rtn_struct(theEnv,expr,expr1);
return(expr2);
}
while (tempPtr->nextArg != NULL)
{ tempPtr = tempPtr->nextArg; }
tempPtr->nextArg = expr2->argList;
rtn_struct(theEnv,expr,expr2);
return(expr1);
}
/*=====================================================*/
/* If neither expression is an "and" expression, then */
/* create an "and" expression and add both expressions */
/* to the argument list of that "and" expression. */
/*=====================================================*/
tempPtr = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_AND);
tempPtr->argList = expr1;
expr1->nextArg = expr2;
return(tempPtr);
}
/********************************************************/
/* AppendExpressions: Attaches an expression to the end */
/* of another expression's nextArg list. */
/********************************************************/
globle struct expr *AppendExpressions(
struct expr *expr1,
struct expr *expr2)
{
struct expr *tempPtr;
/*===========================================================*/
/* If the 1st expression is NULL, return the 2nd expression. */
/*===========================================================*/
if (expr1 == NULL) return(expr2);
/*===========================================================*/
/* If the 2nd expression is NULL, return the 1st expression. */
/*===========================================================*/
if (expr2 == NULL) return(expr1);
/*====================================*/
/* Find the end of the 1st expression */
/* and attach the 2nd expression. */
/*====================================*/
tempPtr = expr1;
while (tempPtr->nextArg != NULL) tempPtr = tempPtr->nextArg;
tempPtr->nextArg = expr2;
/*===============================*/
/* Return the merged expression. */
/*===============================*/
return(expr1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -