Implements unary operation evaluation

This commit is contained in:
Deukhoofd 2019-05-25 14:59:12 +02:00
parent 9131fbfee7
commit b536187593
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
7 changed files with 82 additions and 2 deletions

View File

@ -180,6 +180,14 @@ public:
BoundExpressionKind GetKind() final{
return BoundExpressionKind ::Unary;
}
BoundExpression* GetOperand(){
return _operand;
}
BoundUnaryOperation GetOperation(){
return _operation;
}
};

View File

@ -15,7 +15,6 @@ enum class BoundBinaryOperation{
};
enum class BoundUnaryOperation{
Identity,
Negation,
LogicalNegation,
};

View File

@ -41,6 +41,7 @@ NumericEvalValue* Evaluator::EvaluateIntegerExpression(BoundExpression *expressi
switch (expression->GetKind()){
case BoundExpressionKind ::LiteralInteger: return new IntegerEvalValue(((BoundLiteralIntegerExpression*)expression)->GetValue());
case BoundExpressionKind ::LiteralFloat: return new FloatEvalValue(((BoundLiteralFloatExpression*)expression)->GetValue());
case BoundExpressionKind::Unary: return this -> EvaluateIntegerUnary((BoundUnaryExpression*)expression);
case BoundExpressionKind ::Binary: return this -> EvaluateIntegerBinary((BoundBinaryExpression*)expression);
case BoundExpressionKind ::LiteralString:
@ -53,7 +54,7 @@ NumericEvalValue* Evaluator::EvaluateIntegerExpression(BoundExpression *expressi
BooleanEvalValue* Evaluator::EvaluateBoolExpression(BoundExpression *expression) {
switch (expression->GetKind()) {
case BoundExpressionKind::LiteralBool: return new BooleanEvalValue(((BoundLiteralBoolExpression*)expression)->GetValue());
case BoundExpressionKind::Unary:break;
case BoundExpressionKind::Unary: return this -> EvaluateBooleanUnary((BoundUnaryExpression*)expression);
case BoundExpressionKind::Binary: return this -> EvaluateBooleanBinary((BoundBinaryExpression*)expression);
case BoundExpressionKind::Bad:
case BoundExpressionKind::LiteralInteger:

View File

@ -28,6 +28,9 @@ class Evaluator {
NumericEvalValue* EvaluateIntegerBinary(BoundBinaryExpression* expression);
BooleanEvalValue *EvaluateBooleanBinary(BoundBinaryExpression *expression);
NumericEvalValue* EvaluateIntegerUnary(BoundUnaryExpression* expression);
BooleanEvalValue *EvaluateBooleanUnary(BoundUnaryExpression *expression);
public:
Evaluator(Script* script){
_scriptData = script;

View File

@ -0,0 +1,39 @@
#include "EvalValues/NumericEvalValue.hpp"
#include "Evaluator.hpp"
#include "EvaluationException.hpp"
#include "../Script.hpp"
NumericEvalValue *Evaluator::EvaluateIntegerUnary(BoundUnaryExpression *expression) {
switch (expression->GetOperation()){
case BoundUnaryOperation::Negation:
{
auto operandValue = EvaluateIntegerExpression(expression->GetOperand());
if (operandValue->IsFloat()){
double f = operandValue->EvaluateFloat();
delete operandValue;
return new FloatEvalValue(-f);
} else{
long l = operandValue->EvaluateInteger();
delete operandValue;
return new IntegerEvalValue(-l);
}
}
case BoundUnaryOperation::LogicalNegation:
throw;
}
}
BooleanEvalValue *Evaluator::EvaluateBooleanUnary(BoundUnaryExpression *expression) {
switch (expression->GetOperation()){
case BoundUnaryOperation::LogicalNegation:
{
auto val = EvaluateBoolExpression(expression->GetOperand());
bool b = val->EvaluateBool();
delete val;
return new BooleanEvalValue(!b);
}
case BoundUnaryOperation::Negation:
throw;
}
}

View File

@ -76,6 +76,21 @@ TEST_CASE( "False or False", "[integration]" ) {
REQUIRE(!lastValue->EvaluateBool());
}
TEST_CASE( "Not True", "[integration]" ) {
Script script = Script::Create("not true");
REQUIRE(!script.Diagnostics -> HasErrors());
script.Evaluate();
auto lastValue = script.GetLastValue();
REQUIRE(!lastValue->EvaluateBool());
}
TEST_CASE( "Not False", "[integration]" ) {
Script script = Script::Create("not false");
REQUIRE(!script.Diagnostics -> HasErrors());
script.Evaluate();
auto lastValue = script.GetLastValue();
REQUIRE(lastValue->EvaluateBool());
}
#endif

View File

@ -2,6 +2,21 @@
#include <catch.hpp>
#include "../src/Script.hpp"
TEST_CASE( "Integer Negation", "[integration]" ) {
Script script = Script::Create("-60");
REQUIRE(!script.Diagnostics -> HasErrors());
script.Evaluate();
auto lastValue = script.GetLastValue();
REQUIRE(lastValue->EvaluateInteger() == -60);
}
TEST_CASE( "Float Negation", "[integration]" ) {
Script script = Script::Create("-5.65");
REQUIRE(!script.Diagnostics -> HasErrors());
script.Evaluate();
auto lastValue = script.GetLastValue();
REQUIRE(lastValue->EvaluateFloat() == Approx(-5.65));
}
TEST_CASE( "Integer Addition", "[integration]" ) {
Script script = Script::Create("1 + 5");
REQUIRE(!script.Diagnostics -> HasErrors());