Added logical and and or binary operations

This commit is contained in:
Deukhoofd 2019-05-25 13:30:20 +02:00
parent ce3be6a039
commit 4a4a71ca73
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
5 changed files with 140 additions and 7 deletions

View File

@ -30,4 +30,26 @@ NumericEvalValue* Evaluator::EvaluateIntegerBinary(BoundBinaryExpression *expres
delete leftValue;
delete rightValue;
return result;
}
BooleanEvalValue* Evaluator::EvaluateBooleanBinary(BoundBinaryExpression* expression){
switch (expression->GetOperation()){
case BoundBinaryOperation::Equality:break;
case BoundBinaryOperation::LogicalAnd:
{
BooleanEvalValue* leftValue = this -> EvaluateBoolExpression(expression->GetLeft());
if (!leftValue->EvaluateBool()) return leftValue;
delete leftValue;
BooleanEvalValue* rightValue = this -> EvaluateBoolExpression(expression->GetRight());
return rightValue;
}
case BoundBinaryOperation::LogicalOr:
{
BooleanEvalValue* leftValue = this -> EvaluateBoolExpression(expression->GetLeft());
if (leftValue->EvaluateBool()) return leftValue;
delete leftValue;
BooleanEvalValue* rightValue = this -> EvaluateBoolExpression(expression->GetRight());
return rightValue;
}
}
}

View File

@ -25,4 +25,26 @@ public:
}
};
class BooleanEvalValue : public EvalValue{
bool _value;
ScriptType* _type;
public:
explicit BooleanEvalValue(bool val){
_value = val;
_type = new ScriptType(TypeClass::Bool);
}
~BooleanEvalValue() final{
delete _type;
}
ScriptType* GetType() final{
return _type;
};
bool EvaluateBool() final{
return _value;
}
};
#endif //PORYGONLANG_EVALVALUE_HPP

View File

@ -32,15 +32,12 @@ EvalValue *Evaluator::EvaluateExpression(BoundExpression *expression) {
auto type = expression -> GetType();
switch (type->GetClass()){
case TypeClass ::Number: return this -> EvaluateIntegerExpression(expression);
case TypeClass ::Bool: return this -> EvaluateBoolExpression(expression);
default: throw;
}
}
NumericEvalValue* Evaluator::EvaluateIntegerExpression(BoundExpression *expression) {
auto exprType = expression->GetType();
if (exprType->GetClass() != TypeClass::Number){
throw EvaluationException("Can't evaluate expression as integer, it will not return a number.");
}
switch (expression->GetKind()){
case BoundExpressionKind ::LiteralInteger: return new IntegerEvalValue(((BoundLiteralIntegerExpression*)expression)->GetValue());
case BoundExpressionKind ::LiteralFloat: return new FloatEvalValue(((BoundLiteralFloatExpression*)expression)->GetValue());
@ -53,8 +50,18 @@ NumericEvalValue* Evaluator::EvaluateIntegerExpression(BoundExpression *expressi
}
}
EvalValue* Evaluator::EvaluateBoolExpression(BoundExpression *expression) {
return nullptr;
BooleanEvalValue* Evaluator::EvaluateBoolExpression(BoundExpression *expression) {
switch (expression->GetKind()) {
case BoundExpressionKind::LiteralBool: return new BooleanEvalValue(((BoundLiteralBoolExpression*)expression)->GetValue());
case BoundExpressionKind::Unary:break;
case BoundExpressionKind::Binary: return this -> EvaluateBooleanBinary((BoundBinaryExpression*)expression);
case BoundExpressionKind::Bad:
case BoundExpressionKind::LiteralInteger:
case BoundExpressionKind::LiteralFloat:
case BoundExpressionKind::LiteralString:
throw;
}
}
EvalValue* Evaluator::EvaluateStringExpression(BoundExpression *expression) {

View File

@ -23,10 +23,11 @@ class Evaluator {
EvalValue* EvaluateExpression(BoundExpression* expression);
NumericEvalValue* EvaluateIntegerExpression(BoundExpression* expression);
EvalValue* EvaluateBoolExpression(BoundExpression* expression);
BooleanEvalValue* EvaluateBoolExpression(BoundExpression* expression);
EvalValue* EvaluateStringExpression(BoundExpression* expression);
NumericEvalValue* EvaluateIntegerBinary(BoundBinaryExpression* expression);
BooleanEvalValue *EvaluateBooleanBinary(BoundBinaryExpression *expression);
public:
Evaluator(Script* script){
_scriptData = script;

View File

@ -0,0 +1,81 @@
#ifdef TESTS_BUILD
#include <catch.hpp>
#include "../src/Script.hpp"
TEST_CASE( "Basic True", "[integration]" ) {
Script script = Script::Create("true");
REQUIRE(!script.Diagnostics -> HasErrors());
script.Evaluate();
auto lastValue = script.GetLastValue();
REQUIRE(lastValue->EvaluateBool());
}
TEST_CASE( "Basic False", "[integration]" ) {
Script script = Script::Create("false");
REQUIRE(!script.Diagnostics -> HasErrors());
script.Evaluate();
auto lastValue = script.GetLastValue();
REQUIRE(!lastValue->EvaluateBool());
}
TEST_CASE( "True and True", "[integration]" ) {
Script script = Script::Create("true and true");
REQUIRE(!script.Diagnostics -> HasErrors());
script.Evaluate();
auto lastValue = script.GetLastValue();
REQUIRE(lastValue->EvaluateBool());
}
TEST_CASE( "True and False", "[integration]" ) {
Script script = Script::Create("true and false");
REQUIRE(!script.Diagnostics -> HasErrors());
script.Evaluate();
auto lastValue = script.GetLastValue();
REQUIRE(!lastValue->EvaluateBool());
}
TEST_CASE( "False and True", "[integration]" ) {
Script script = Script::Create("false and true");
REQUIRE(!script.Diagnostics -> HasErrors());
script.Evaluate();
auto lastValue = script.GetLastValue();
REQUIRE(!lastValue->EvaluateBool());
}
TEST_CASE( "False and False", "[integration]" ) {
Script script = Script::Create("false and false");
REQUIRE(!script.Diagnostics -> HasErrors());
script.Evaluate();
auto lastValue = script.GetLastValue();
REQUIRE(!lastValue->EvaluateBool());
}
TEST_CASE( "True or True", "[integration]" ) {
Script script = Script::Create("true or true");
REQUIRE(!script.Diagnostics -> HasErrors());
script.Evaluate();
auto lastValue = script.GetLastValue();
REQUIRE(lastValue->EvaluateBool());
}
TEST_CASE( "True or False", "[integration]" ) {
Script script = Script::Create("true or false");
REQUIRE(!script.Diagnostics -> HasErrors());
script.Evaluate();
auto lastValue = script.GetLastValue();
REQUIRE(lastValue->EvaluateBool());
}
TEST_CASE( "False or True", "[integration]" ) {
Script script = Script::Create("false or true");
REQUIRE(!script.Diagnostics -> HasErrors());
script.Evaluate();
auto lastValue = script.GetLastValue();
REQUIRE(lastValue->EvaluateBool());
}
TEST_CASE( "False or False", "[integration]" ) {
Script script = Script::Create("false or false");
REQUIRE(!script.Diagnostics -> HasErrors());
script.Evaluate();
auto lastValue = script.GetLastValue();
REQUIRE(!lastValue->EvaluateBool());
}
#endif