diff --git a/src/Binder/BoundExpressions/BoundExpression.hpp b/src/Binder/BoundExpressions/BoundExpression.hpp index 3425681..20f8b19 100644 --- a/src/Binder/BoundExpressions/BoundExpression.hpp +++ b/src/Binder/BoundExpressions/BoundExpression.hpp @@ -180,6 +180,14 @@ public: BoundExpressionKind GetKind() final{ return BoundExpressionKind ::Unary; } + + BoundExpression* GetOperand(){ + return _operand; + } + + BoundUnaryOperation GetOperation(){ + return _operation; + } }; diff --git a/src/Binder/BoundOperators.hpp b/src/Binder/BoundOperators.hpp index cd2315d..2385eb2 100644 --- a/src/Binder/BoundOperators.hpp +++ b/src/Binder/BoundOperators.hpp @@ -15,7 +15,6 @@ enum class BoundBinaryOperation{ }; enum class BoundUnaryOperation{ - Identity, Negation, LogicalNegation, }; diff --git a/src/Evaluator/Evaluator.cpp b/src/Evaluator/Evaluator.cpp index 9a099ad..3b19f33 100644 --- a/src/Evaluator/Evaluator.cpp +++ b/src/Evaluator/Evaluator.cpp @@ -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: diff --git a/src/Evaluator/Evaluator.hpp b/src/Evaluator/Evaluator.hpp index 7577b0b..4b17db4 100644 --- a/src/Evaluator/Evaluator.hpp +++ b/src/Evaluator/Evaluator.hpp @@ -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; diff --git a/src/Evaluator/UnaryEvaluation.cpp b/src/Evaluator/UnaryEvaluation.cpp new file mode 100644 index 0000000..86011c7 --- /dev/null +++ b/src/Evaluator/UnaryEvaluation.cpp @@ -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; + } +} \ No newline at end of file diff --git a/tests/integration/LogicalOperationsTests.cpp b/tests/integration/LogicalOperationsTests.cpp index 0f00eba..024e86b 100644 --- a/tests/integration/LogicalOperationsTests.cpp +++ b/tests/integration/LogicalOperationsTests.cpp @@ -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 diff --git a/tests/integration/NumericalOperationsTests.cpp b/tests/integration/NumericalOperationsTests.cpp index 57dc208..b11e650 100644 --- a/tests/integration/NumericalOperationsTests.cpp +++ b/tests/integration/NumericalOperationsTests.cpp @@ -2,6 +2,21 @@ #include #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());