📄 evaluate.cpp
字号:
#include "stdafx.h"
#include <math.h>
#include "date.h"
#include "evaluate.h"
#define EVAL_MAX_ARGUMENT_COUNT 16
/* evaluate variables */
#define EVAL_VARIABLE_PI 3.1415926535
/* evaluate functions */
#define EVAL_FUNCTION_ABS 0x01
#define EVAL_FUNCTION_MOD 0x02
#define EVAL_FUNCTION_CEIL 0x03
#define EVAL_FUNCTION_FLOOR 0x04
#define EVAL_FUNCTION_ROUND 0x05
#define EVAL_FUNCTION_MIN 0x06
#define EVAL_FUNCTION_MAX 0x07
#define EVAL_FUNCTION_ACOS 0x08
#define EVAL_FUNCTION_ASIN 0x09
#define EVAL_FUNCTION_ATAN 0x0A
#define EVAL_FUNCTION_ATAN2 0x0B
#define EVAL_FUNCTION_COS 0x0C
#define EVAL_FUNCTION_SIN 0x0D
#define EVAL_FUNCTION_TAN 0x0E
#define EVAL_FUNCTION_COSH 0x0F
#define EVAL_FUNCTION_SINH 0x10
#define EVAL_FUNCTION_TANH 0x11
#define EVAL_FUNCTION_EXP 0x12
#define EVAL_FUNCTION_LOG 0x13
#define EVAL_FUNCTION_LOG10 0x14
#define EVAL_FUNCTION_POW 0x15
#define EVAL_FUNCTION_SQR 0x16
#define EVAL_FUNCTION_SQRT 0x17
#define EVAL_FUNCTION_TODAY 0x18
#define EVAL_FUNCTION_YEARDAYS 0x19
#define EVAL_FUNCTION_MONTHDAYS 0x20
#define EVAL_FUNCTION_DATE2DAYS 0x21
#define EVAL_FUNCTION_DAYS2DATE 0x22
#define EVAL_FUNCTION_EOMDAY 0x23
#define EVAL_FUNCTION_EOMDATE 0x24
#define EVAL_FUNCTION_WEEKDAY 0x25
#define EVAL_FUNCTION_ISBIZDATE 0x26
#define EVAL_FUNCTION_NBIZDATE 0x27
#define EVAL_FUNCTION_PBIZDATE 0x28
#define EVAL_FUNCTION_ADDDAYS 0x29
#define EVAL_FUNCTION_ADDMONTHS 0x30
#define EVAL_FUNCTION_ADDTERMS 0x31
#define EVAL_FUNCTION_DAYS360 0x32
#define EVAL_FUNCTION_DAYS365 0x33
#define EVAL_FUNCTION_DAYSACT 0x34
#define EVAL_FUNCTION_DAYSBET 0x35
#define EVAL_FUNCTION_MONTHSBET 0x36
#define EVAL_FUNCTION_TERMSBET 0x37
#define EVAL_FUNCTION_TERMFRAC 0x38
#define EVAL_FUNCTION_YEARFRAC 0x39
/* evaluate macros */
#define EVAL_EAT_WHITE(p) while( * p == ' ' || * p == '\t' ) p++;
namespace EVAL {
TCHAR szErrorMessage[][64] = {
"successful",
"internal error",
"wrong syntax",
"variable not defined",
"function not defined",
"function argument count",
};
CMap<CString, LPCTSTR, double, double> hashVariables;
CMap<CString, LPCTSTR, INT, INT> hashFunctions;
BOOL bInitialized = FALSE;
void Initialize();
TCHAR * EvalExpression(TCHAR * pExpr, double * pValue, INT * pError);
TCHAR * EvalTerm(TCHAR * pExpr, double * pValue, INT * pError);
TCHAR * EvalSignedFactor(TCHAR * pExpr, double * pValue, INT * pError);
TCHAR * EvalFactor(TCHAR * pExpr, double * pValue, INT * pError);
TCHAR * EvalConstant(TCHAR * pExpr, double * pValue, INT * pError);
TCHAR * EvalParentheses(TCHAR * pExpr, double * pValue, INT * pError);
TCHAR * EvalVariable(TCHAR * pExpr, double * pValue, INT * pError);
TCHAR * EvalFunction(TCHAR * pExpr, double * pValue, INT * pError);
BOOL EvalFunction(INT nFunction, INT argc, double * argv, double * pValue);
};
void EVAL::SetVariable(TCHAR * pVarName, double dValue)
{
}
void EVAL::GetVariable(TCHAR * pVarName, double * pValue, INT * pError)
{
* pError = EVAL_ERROR_SUCCESSFUL;
}
TCHAR * EVAL::Evaluate(TCHAR * pExpr, double * pValue, INT * pError)
{
if( ! bInitialized ) Initialize();
* pValue = 0.0;
* pError = EVAL_ERROR_SUCCESSFUL;
EVAL_EAT_WHITE( pExpr );
pExpr = EvalExpression( pExpr, pValue, pError );
if( * pError == EVAL_ERROR_SUCCESSFUL && * pExpr != '\0' ) * pError = EVAL_ERROR_WRONG_SYNTAX;
if( * pError == EVAL_ERROR_SUCCESSFUL ) hashVariables.SetAt("ans", * pValue);
return pExpr;
}
TCHAR * EVAL::GetErrorMessage(INT nError)
{
return szErrorMessage[nError];
}
void EVAL::Initialize()
{
hashVariables.InitHashTable(30);
hashVariables.SetAt("ans", 0.0);
hashVariables.SetAt("pi", EVAL_VARIABLE_PI);
hashVariables.SetAt("annual", FRE_ANNUAL);
hashVariables.SetAt("semiannual", FRE_SEMIANNUAL);
hashVariables.SetAt("quarterly", FRE_QUARTERLY);
hashVariables.SetAt("bimonthly", FRE_BIMONTHLY);
hashVariables.SetAt("monthly", FRE_MONTHLY);
hashVariables.SetAt("actact", DCB_ACTACT);
hashVariables.SetAt("act360", DCB_ACT360);
hashVariables.SetAt("act365", DCB_ACT365);
hashVariables.SetAt("30360", DCB_30360);
hashVariables.SetAt("30e360", DCB_30E360);
hashVariables.SetAt("nl365", DCB_NL365);
hashVariables.SetAt("actual", EMR_ACTUAL);
hashVariables.SetAt("endofmonth", EMR_ENDOFMONTH);
hashVariables.SetAt("sunday", HDC_SUNDAY);
hashVariables.SetAt("sunsat", HDC_SUNSAT);
hashFunctions.InitHashTable(100);
hashFunctions.SetAt("abs", EVAL_FUNCTION_ABS);
hashFunctions.SetAt("fabs", EVAL_FUNCTION_ABS);
hashFunctions.SetAt("mod", EVAL_FUNCTION_MOD);
hashFunctions.SetAt("fmod", EVAL_FUNCTION_MOD);
hashFunctions.SetAt("ceil", EVAL_FUNCTION_CEIL);
hashFunctions.SetAt("floor", EVAL_FUNCTION_FLOOR);
hashFunctions.SetAt("round", EVAL_FUNCTION_ROUND);
hashFunctions.SetAt("min", EVAL_FUNCTION_MIN);
hashFunctions.SetAt("max", EVAL_FUNCTION_MAX);
hashFunctions.SetAt("acos", EVAL_FUNCTION_ACOS);
hashFunctions.SetAt("asin", EVAL_FUNCTION_ASIN);
hashFunctions.SetAt("atan", EVAL_FUNCTION_ATAN);
hashFunctions.SetAt("atan2", EVAL_FUNCTION_ATAN2);
hashFunctions.SetAt("cos", EVAL_FUNCTION_COS);
hashFunctions.SetAt("sin", EVAL_FUNCTION_SIN);
hashFunctions.SetAt("tan", EVAL_FUNCTION_TAN);
hashFunctions.SetAt("cosh", EVAL_FUNCTION_COSH);
hashFunctions.SetAt("sinh", EVAL_FUNCTION_SINH);
hashFunctions.SetAt("tanh", EVAL_FUNCTION_TANH);
hashFunctions.SetAt("exp", EVAL_FUNCTION_EXP);
hashFunctions.SetAt("log", EVAL_FUNCTION_LOG);
hashFunctions.SetAt("log10", EVAL_FUNCTION_LOG10);
hashFunctions.SetAt("pow", EVAL_FUNCTION_POW);
hashFunctions.SetAt("sqr", EVAL_FUNCTION_SQR);
hashFunctions.SetAt("sqrt", EVAL_FUNCTION_SQRT);
hashFunctions.SetAt("today", EVAL_FUNCTION_TODAY);
hashFunctions.SetAt("yeardays", EVAL_FUNCTION_YEARDAYS);
hashFunctions.SetAt("monthdays", EVAL_FUNCTION_MONTHDAYS);
hashFunctions.SetAt("date2days", EVAL_FUNCTION_DATE2DAYS);
hashFunctions.SetAt("days2date", EVAL_FUNCTION_DAYS2DATE);
hashFunctions.SetAt("eomday", EVAL_FUNCTION_EOMDAY);
hashFunctions.SetAt("eomdate", EVAL_FUNCTION_EOMDATE);
hashFunctions.SetAt("weekday", EVAL_FUNCTION_WEEKDAY);
hashFunctions.SetAt("isbizdate", EVAL_FUNCTION_ISBIZDATE);
hashFunctions.SetAt("nbizdate", EVAL_FUNCTION_NBIZDATE);
hashFunctions.SetAt("pbizdate", EVAL_FUNCTION_PBIZDATE);
hashFunctions.SetAt("adddays", EVAL_FUNCTION_ADDDAYS);
hashFunctions.SetAt("addmonths", EVAL_FUNCTION_ADDMONTHS);
hashFunctions.SetAt("addterms", EVAL_FUNCTION_ADDTERMS);
hashFunctions.SetAt("days360", EVAL_FUNCTION_DAYS360);
hashFunctions.SetAt("days365", EVAL_FUNCTION_DAYS365);
hashFunctions.SetAt("daysact", EVAL_FUNCTION_DAYSACT);
hashFunctions.SetAt("daysbet", EVAL_FUNCTION_DAYSBET);
hashFunctions.SetAt("monthsbet", EVAL_FUNCTION_MONTHSBET);
hashFunctions.SetAt("termsbet", EVAL_FUNCTION_TERMSBET);
hashFunctions.SetAt("termfrac", EVAL_FUNCTION_TERMFRAC);
hashFunctions.SetAt("yearfrac", EVAL_FUNCTION_YEARFRAC);
bInitialized = TRUE;
}
TCHAR * EVAL::EvalExpression(TCHAR * pExpr, double * pValue, INT * pError)
{
EVAL_EAT_WHITE( pExpr );
pExpr = EvalTerm( pExpr, pValue, pError );
if( * pError ) return pExpr;
EVAL_EAT_WHITE( pExpr );
TCHAR op = * pExpr;
while( op == '+' || op == '-' ) {
pExpr++; // skip operator
double value;
EVAL_EAT_WHITE( pExpr );
pExpr = EvalTerm( pExpr, & value, pError );
if( * pError ) return pExpr;
if( op == '+' ) * pValue += value;
if( op == '-' ) * pValue -= value;
EVAL_EAT_WHITE( pExpr );
op = * pExpr;
}
return pExpr;
}
TCHAR * EVAL::EvalTerm(TCHAR * pExpr, double * pValue, INT * pError)
{
EVAL_EAT_WHITE( pExpr );
pExpr = EvalSignedFactor( pExpr, pValue, pError );
if( * pError ) return pExpr;
EVAL_EAT_WHITE( pExpr );
TCHAR op = * pExpr;
while( op == '*' || op == '/' || op == '%' ) {
pExpr++; // skip operator
double value;
EVAL_EAT_WHITE( pExpr );
pExpr = EvalFactor( pExpr, & value, pError );
if( * pError ) return pExpr;
if( op == '*' ) * pValue *= value;
if( op == '/' ) * pValue /= value;
if( op == '%' ) * pValue = fmod(* pValue, value);
EVAL_EAT_WHITE( pExpr );
op = * pExpr;
}
return pExpr;
}
TCHAR * EVAL::EvalSignedFactor(TCHAR * pExpr, double * pValue, INT * pError)
{
EVAL_EAT_WHITE( pExpr );
TCHAR op = * pExpr;
if( op == '+' || op == '-' ) pExpr++; // skip operator
EVAL_EAT_WHITE( pExpr );
pExpr = EvalFactor( pExpr, pValue, pError );
if( * pError ) return pExpr;
if( op == '-' ) * pValue = - (* pValue);
return pExpr;
}
TCHAR * EVAL::EvalFactor(TCHAR * pExpr, double * pValue, INT * pError)
{
EVAL_EAT_WHITE( pExpr );
if ( * pExpr == '\0' ) return pExpr;
else if( isdigit(* pExpr) ) return EvalConstant( pExpr, pValue, pError );
else if( * pExpr == '(' ) return EvalParentheses( pExpr, pValue, pError );
else if( * pExpr == '$' ) return EvalVariable( pExpr, pValue, pError );
else if( isalpha(* pExpr) ) return EvalFunction( pExpr, pValue, pError );
else /* other cases */ { * pError = EVAL_ERROR_WRONG_SYNTAX; return pExpr; }
}
TCHAR * EVAL::EvalConstant(TCHAR * pExpr, double * pValue, INT * pError)
{
EVAL_EAT_WHITE( pExpr );
TCHAR * pEnd = pExpr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -