| 898 | |
| 899 | |
| 900 | float StateDatabase::evaluate(Expression e) { |
| 901 | std::stack<ExpressionToken> evaluationStack; |
| 902 | ExpressionToken tok, lvalue, rvalue; |
| 903 | bool unary; |
| 904 | |
| 905 | for (Expression::reverse_iterator i = e.rbegin(); i != e.rend(); i++) { |
| 906 | unary = false; |
| 907 | switch (i->getTokenType()) { |
| 908 | case ExpressionToken::number: { |
| 909 | evaluationStack.push(*i); |
| 910 | break; |
| 911 | } |
| 912 | case ExpressionToken::variable: { |
| 913 | // strip off '$'? |
| 914 | tok.setNumber(eval(i->getVariable())); |
| 915 | evaluationStack.push(tok); |
| 916 | break; |
| 917 | } |
| 918 | case ExpressionToken::oper: { |
| 919 | if ((i->getOperator() == ExpressionToken::lparen) || |
| 920 | (i->getOperator() == ExpressionToken::rparen)) { |
| 921 | break; // should not have any parens here, skip them |
| 922 | } |
| 923 | if (evaluationStack.size() == 0) { |
| 924 | // syntax error |
| 925 | return getNaN(); |
| 926 | } |
| 927 | // rvalue and lvalue are switched, since we're reversed |
| 928 | rvalue = evaluationStack.top(); evaluationStack.pop(); |
| 929 | if (evaluationStack.size() == 0) { |
| 930 | unary = true; // syntax error or unary operator |
| 931 | } |
| 932 | if (!unary) { |
| 933 | lvalue = evaluationStack.top(); evaluationStack.pop(); |
| 934 | } |
| 935 | switch (i->getOperator()) { |
| 936 | case ExpressionToken::add: { |
| 937 | tok.setNumber(lvalue.getNumber() + rvalue.getNumber()); |
| 938 | evaluationStack.push(tok); |
| 939 | break; |
| 940 | } |
| 941 | case ExpressionToken::subtract: { |
| 942 | if (unary) { |
| 943 | tok.setNumber(-rvalue.getNumber()); |
| 944 | } |
| 945 | else { |
| 946 | tok.setNumber(lvalue.getNumber() - rvalue.getNumber()); |
| 947 | } |
| 948 | evaluationStack.push(tok); |
| 949 | break; |
| 950 | } |
| 951 | case ExpressionToken::multiply: { |
| 952 | tok.setNumber(lvalue.getNumber() * rvalue.getNumber()); |
| 953 | evaluationStack.push(tok); |
| 954 | break; |
| 955 | } |
| 956 | case ExpressionToken::divide: { |
| 957 | tok.setNumber(lvalue.getNumber() / rvalue.getNumber()); |
nothing calls this directly
no test coverage detected