Patch by John Scipione: Added cbrt() function to the supported functions
and factrorial expression support. Closes ticket #7945, thanks a bunch! git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42690 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -59,6 +59,7 @@ class ExpressionParser {
|
||||
int32 argumentCount);
|
||||
MAPM _ParseFunction(const Token& token);
|
||||
MAPM _ParseAtom();
|
||||
MAPM _ParseFactorial(MAPM value);
|
||||
|
||||
void _EatToken(int32 type);
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ enum {
|
||||
TOKEN_MODULO,
|
||||
|
||||
TOKEN_POWER,
|
||||
TOKEN_FACTORIAL,
|
||||
|
||||
TOKEN_OPENING_BRACKET,
|
||||
TOKEN_CLOSING_BRACKET,
|
||||
@@ -230,6 +231,9 @@ class Tokenizer {
|
||||
case '^':
|
||||
type = TOKEN_POWER;
|
||||
break;
|
||||
case '!':
|
||||
type = TOKEN_FACTORIAL;
|
||||
break;
|
||||
|
||||
case '(':
|
||||
type = TOKEN_OPENING_BRACKET;
|
||||
@@ -456,7 +460,7 @@ ExpressionParser::_ParseSum()
|
||||
|
||||
default:
|
||||
fTokenizer->RewindToken();
|
||||
return value;
|
||||
return _ParseFactorial(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -491,7 +495,7 @@ ExpressionParser::_ParseProduct()
|
||||
|
||||
default:
|
||||
fTokenizer->RewindToken();
|
||||
return value;
|
||||
return _ParseFactorial(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -506,7 +510,7 @@ ExpressionParser::_ParsePower()
|
||||
Token token = fTokenizer->NextToken();
|
||||
if (token.type != TOKEN_POWER) {
|
||||
fTokenizer->RewindToken();
|
||||
return value;
|
||||
return _ParseFactorial(value);
|
||||
}
|
||||
value = value.pow(_ParseUnary());
|
||||
}
|
||||
@@ -565,9 +569,9 @@ MAPM
|
||||
ExpressionParser::_ParseFunction(const Token& token)
|
||||
{
|
||||
if (strcasecmp("e", token.string.String()) == 0)
|
||||
return MAPM(MM_E);
|
||||
return _ParseFactorial(MAPM(MM_E));
|
||||
else if (strcasecmp("pi", token.string.String()) == 0)
|
||||
return MAPM(MM_PI);
|
||||
return _ParseFactorial(MAPM(MM_PI));
|
||||
|
||||
// hard coded cases for different count of arguments
|
||||
// supports functions with 3 arguments at most
|
||||
@@ -576,68 +580,71 @@ ExpressionParser::_ParseFunction(const Token& token)
|
||||
|
||||
if (strcasecmp("abs", token.string.String()) == 0) {
|
||||
_InitArguments(values, 1);
|
||||
return values[0].abs();
|
||||
return _ParseFactorial(values[0].abs());
|
||||
} else if (strcasecmp("acos", token.string.String()) == 0) {
|
||||
_InitArguments(values, 1);
|
||||
if (values[0] < -1 || values[0] > 1)
|
||||
throw ParseException("out of domain", token.position);
|
||||
return values[0].acos();
|
||||
return _ParseFactorial(values[0].acos());
|
||||
} else if (strcasecmp("asin", token.string.String()) == 0) {
|
||||
_InitArguments(values, 1);
|
||||
if (values[0] < -1 || values[0] > 1)
|
||||
throw ParseException("out of domain", token.position);
|
||||
return values[0].asin();
|
||||
return _ParseFactorial(values[0].asin());
|
||||
} else if (strcasecmp("atan", token.string.String()) == 0) {
|
||||
_InitArguments(values, 1);
|
||||
return values[0].atan();
|
||||
return _ParseFactorial(values[0].atan());
|
||||
} else if (strcasecmp("atan2", token.string.String()) == 0) {
|
||||
_InitArguments(values, 2);
|
||||
return values[0].atan2(values[1]);
|
||||
return _ParseFactorial(values[0].atan2(values[1]));
|
||||
} else if (strcasecmp("cbrt", token.string.String()) == 0) {
|
||||
_InitArguments(values, 1);
|
||||
return _ParseFactorial(values[0].cbrt());
|
||||
} else if (strcasecmp("ceil", token.string.String()) == 0) {
|
||||
_InitArguments(values, 1);
|
||||
return values[0].ceil();
|
||||
return _ParseFactorial(values[0].ceil());
|
||||
} else if (strcasecmp("cos", token.string.String()) == 0) {
|
||||
_InitArguments(values, 1);
|
||||
return values[0].cos();
|
||||
return _ParseFactorial(values[0].cos());
|
||||
} else if (strcasecmp("cosh", token.string.String()) == 0) {
|
||||
_InitArguments(values, 1);
|
||||
return values[0].cosh();
|
||||
return _ParseFactorial(values[0].cosh());
|
||||
} else if (strcasecmp("exp", token.string.String()) == 0) {
|
||||
_InitArguments(values, 1);
|
||||
return values[0].exp();
|
||||
return _ParseFactorial(values[0].exp());
|
||||
} else if (strcasecmp("floor", token.string.String()) == 0) {
|
||||
_InitArguments(values, 1);
|
||||
return values[0].floor();
|
||||
return _ParseFactorial(values[0].floor());
|
||||
} else if (strcasecmp("ln", token.string.String()) == 0) {
|
||||
_InitArguments(values, 1);
|
||||
if (values[0] <= 0)
|
||||
throw ParseException("out of domain", token.position);
|
||||
return values[0].log();
|
||||
return _ParseFactorial(values[0].log());
|
||||
} else if (strcasecmp("log", token.string.String()) == 0) {
|
||||
_InitArguments(values, 1);
|
||||
if (values[0] <= 0)
|
||||
throw ParseException("out of domain", token.position);
|
||||
return values[0].log10();
|
||||
return _ParseFactorial(values[0].log10());
|
||||
} else if (strcasecmp("pow", token.string.String()) == 0) {
|
||||
_InitArguments(values, 2);
|
||||
return values[0].pow(values[1]);
|
||||
return _ParseFactorial(values[0].pow(values[1]));
|
||||
} else if (strcasecmp("sin", token.string.String()) == 0) {
|
||||
_InitArguments(values, 1);
|
||||
return values[0].sin();
|
||||
return _ParseFactorial(values[0].sin());
|
||||
} else if (strcasecmp("sinh", token.string.String()) == 0) {
|
||||
_InitArguments(values, 1);
|
||||
return values[0].sinh();
|
||||
return _ParseFactorial(values[0].sinh());
|
||||
} else if (strcasecmp("sqrt", token.string.String()) == 0) {
|
||||
_InitArguments(values, 1);
|
||||
if (values[0] < 0)
|
||||
throw ParseException("out of domain", token.position);
|
||||
return values[0].sqrt();
|
||||
return _ParseFactorial(values[0].sqrt());
|
||||
} else if (strcasecmp("tan", token.string.String()) == 0) {
|
||||
_InitArguments(values, 1);
|
||||
return values[0].tan();
|
||||
return _ParseFactorial(values[0].tan());
|
||||
} else if (strcasecmp("tanh", token.string.String()) == 0) {
|
||||
_InitArguments(values, 1);
|
||||
return values[0].tanh();
|
||||
return _ParseFactorial(values[0].tanh());
|
||||
}
|
||||
|
||||
throw ParseException("unknown identifier", token.position);
|
||||
@@ -652,7 +659,7 @@ ExpressionParser::_ParseAtom()
|
||||
throw ParseException("unexpected end of expression", token.position);
|
||||
|
||||
if (token.type == TOKEN_CONSTANT)
|
||||
return token.value;
|
||||
return _ParseFactorial(token.value);
|
||||
|
||||
fTokenizer->RewindToken();
|
||||
|
||||
@@ -662,6 +669,20 @@ ExpressionParser::_ParseAtom()
|
||||
|
||||
_EatToken(TOKEN_CLOSING_BRACKET);
|
||||
|
||||
return _ParseFactorial(value);
|
||||
}
|
||||
|
||||
|
||||
MAPM
|
||||
ExpressionParser::_ParseFactorial(MAPM value)
|
||||
{
|
||||
if (fTokenizer->NextToken().type == TOKEN_FACTORIAL) {
|
||||
fTokenizer->RewindToken();
|
||||
_EatToken(TOKEN_FACTORIAL);
|
||||
return value.factorial();
|
||||
}
|
||||
|
||||
fTokenizer->RewindToken();
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user