Implemented comparison equality operators
This commit is contained in:
parent
fc66c15c2f
commit
7d75131822
|
@ -275,6 +275,26 @@ BoundExpression* Binder::BindBinaryOperator(BinaryExpression* expression){
|
|||
case BinaryOperatorKind ::Inequality:
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Inequality, std::make_shared<ScriptType>(TypeClass::Bool),
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
case BinaryOperatorKind ::Less:
|
||||
if (boundLeft->GetType()->GetClass() == TypeClass::Number && boundRight->GetType()->GetClass() == TypeClass::Number){
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::LessThan, std::make_shared<ScriptType>(TypeClass::Bool),
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
case BinaryOperatorKind ::LessOrEquals:
|
||||
if (boundLeft->GetType()->GetClass() == TypeClass::Number && boundRight->GetType()->GetClass() == TypeClass::Number){
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::LessThanEquals, std::make_shared<ScriptType>(TypeClass::Bool),
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
case BinaryOperatorKind ::Greater:
|
||||
if (boundLeft->GetType()->GetClass() == TypeClass::Number && boundRight->GetType()->GetClass() == TypeClass::Number){
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::GreaterThan, std::make_shared<ScriptType>(TypeClass::Bool),
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
case BinaryOperatorKind ::GreaterOrEquals:
|
||||
if (boundLeft->GetType()->GetClass() == TypeClass::Number && boundRight->GetType()->GetClass() == TypeClass::Number){
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::GreaterThanEquals, std::make_shared<ScriptType>(TypeClass::Bool),
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
case BinaryOperatorKind ::LogicalAnd:
|
||||
if (boundLeftType->GetClass() == TypeClass::Bool && boundRightType->GetClass() == TypeClass::Bool)
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::LogicalAnd, std::make_shared<ScriptType>(TypeClass::Bool),
|
||||
|
|
|
@ -9,6 +9,11 @@ enum class BoundBinaryOperation{
|
|||
Division,
|
||||
Equality,
|
||||
Inequality,
|
||||
LessThan,
|
||||
LessThanEquals,
|
||||
GreaterThan,
|
||||
GreaterThanEquals,
|
||||
|
||||
LogicalAnd,
|
||||
LogicalOr,
|
||||
Concatenation
|
||||
|
|
|
@ -45,6 +45,35 @@ shared_ptr<BooleanEvalValue> Evaluator::EvaluateBooleanBinary(BoundBinaryExpress
|
|||
bool equals = leftValue.get()->operator!=(rightValue.get());
|
||||
return make_shared<BooleanEvalValue>(equals);
|
||||
}
|
||||
case BoundBinaryOperation ::LessThan:
|
||||
{
|
||||
auto leftValue = this -> EvaluateIntegerExpression(expression->GetLeft());
|
||||
auto rightValue = this -> EvaluateIntegerExpression(expression->GetRight());
|
||||
BooleanEvalValue* b = leftValue->operator<(rightValue.get());
|
||||
return shared_ptr<BooleanEvalValue>(b);
|
||||
}
|
||||
case BoundBinaryOperation ::LessThanEquals:
|
||||
{
|
||||
auto leftValue = this -> EvaluateIntegerExpression(expression->GetLeft());
|
||||
auto rightValue = this -> EvaluateIntegerExpression(expression->GetRight());
|
||||
BooleanEvalValue* b = leftValue->operator<=(rightValue.get());
|
||||
return shared_ptr<BooleanEvalValue>(b);
|
||||
}
|
||||
case BoundBinaryOperation ::GreaterThan:
|
||||
{
|
||||
auto leftValue = this -> EvaluateIntegerExpression(expression->GetLeft());
|
||||
auto rightValue = this -> EvaluateIntegerExpression(expression->GetRight());
|
||||
BooleanEvalValue* b = leftValue->operator>(rightValue.get());
|
||||
return shared_ptr<BooleanEvalValue>(b);
|
||||
}
|
||||
case BoundBinaryOperation ::GreaterThanEquals:
|
||||
{
|
||||
auto leftValue = this -> EvaluateIntegerExpression(expression->GetLeft());
|
||||
auto rightValue = this -> EvaluateIntegerExpression(expression->GetRight());
|
||||
BooleanEvalValue* b = leftValue->operator>=(rightValue.get());
|
||||
return shared_ptr<BooleanEvalValue>(b);
|
||||
}
|
||||
|
||||
case BoundBinaryOperation::LogicalAnd:
|
||||
{
|
||||
auto leftValue = this -> EvaluateBoolExpression(expression->GetLeft());
|
||||
|
|
|
@ -78,3 +78,67 @@ bool NumericEvalValue::operator==(EvalValue *b) {
|
|||
return this->EvaluateInteger() == numVal->EvaluateInteger();
|
||||
}
|
||||
}
|
||||
|
||||
BooleanEvalValue *NumericEvalValue::operator<(NumericEvalValue *b) {
|
||||
if (this->IsFloat()){
|
||||
if (b->IsFloat()){
|
||||
return new BooleanEvalValue(this->GetFloatValue() < b->GetFloatValue());
|
||||
} else{
|
||||
return new BooleanEvalValue(this->GetFloatValue() < b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()){
|
||||
return new BooleanEvalValue(this->GetIntegerValue() < b->GetFloatValue());
|
||||
} else{
|
||||
return new BooleanEvalValue(this->GetIntegerValue() < b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BooleanEvalValue *NumericEvalValue::operator<=(NumericEvalValue *b) {
|
||||
if (this->IsFloat()){
|
||||
if (b->IsFloat()){
|
||||
return new BooleanEvalValue(this->GetFloatValue() <= b->GetFloatValue());
|
||||
} else{
|
||||
return new BooleanEvalValue(this->GetFloatValue() <= b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()){
|
||||
return new BooleanEvalValue(this->GetIntegerValue() <= b->GetFloatValue());
|
||||
} else{
|
||||
return new BooleanEvalValue(this->GetIntegerValue() <= b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BooleanEvalValue *NumericEvalValue::operator>(NumericEvalValue *b) {
|
||||
if (this->IsFloat()){
|
||||
if (b->IsFloat()){
|
||||
return new BooleanEvalValue(this->GetFloatValue() > b->GetFloatValue());
|
||||
} else{
|
||||
return new BooleanEvalValue(this->GetFloatValue() > b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()){
|
||||
return new BooleanEvalValue(this->GetIntegerValue() > b->GetFloatValue());
|
||||
} else{
|
||||
return new BooleanEvalValue(this->GetIntegerValue() > b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BooleanEvalValue *NumericEvalValue::operator>=(NumericEvalValue *b) {
|
||||
if (this->IsFloat()){
|
||||
if (b->IsFloat()){
|
||||
return new BooleanEvalValue(this->GetFloatValue() >= b->GetFloatValue());
|
||||
} else{
|
||||
return new BooleanEvalValue(this->GetFloatValue() >= b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()){
|
||||
return new BooleanEvalValue(this->GetIntegerValue() >= b->GetFloatValue());
|
||||
} else{
|
||||
return new BooleanEvalValue(this->GetIntegerValue() >= b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,10 @@ public:
|
|||
NumericEvalValue* operator -(NumericEvalValue* b);
|
||||
NumericEvalValue* operator *(NumericEvalValue* b);
|
||||
NumericEvalValue* operator /(NumericEvalValue* b);
|
||||
BooleanEvalValue* operator <(NumericEvalValue* b);
|
||||
BooleanEvalValue* operator <=(NumericEvalValue* b);
|
||||
BooleanEvalValue* operator >(NumericEvalValue* b);
|
||||
BooleanEvalValue* operator >=(NumericEvalValue* b);
|
||||
bool operator ==(EvalValue* b) final;
|
||||
};
|
||||
|
||||
|
|
|
@ -2,12 +2,21 @@
|
|||
#ifndef PORYGONLANG_BINARYOPERATORKIND_HPP
|
||||
#define PORYGONLANG_BINARYOPERATORKIND_HPP
|
||||
enum class BinaryOperatorKind{
|
||||
// Math
|
||||
Addition,
|
||||
Subtraction,
|
||||
Multiplication,
|
||||
Division,
|
||||
|
||||
// Equality
|
||||
Equality,
|
||||
Inequality,
|
||||
Less,
|
||||
LessOrEquals,
|
||||
Greater,
|
||||
GreaterOrEquals,
|
||||
|
||||
// Logical
|
||||
LogicalAnd,
|
||||
LogicalOr,
|
||||
};
|
||||
|
|
|
@ -79,6 +79,18 @@ IToken* Lexer::LexNext(char c){
|
|||
return new SimpleToken(TokenKind::EqualityToken, this -> _position - 2, 2);
|
||||
}
|
||||
return new SimpleToken(TokenKind::AssignmentToken, this -> _position - 1, 1);
|
||||
case '<':
|
||||
if (Lexer::Peek() == '='){
|
||||
Lexer::Next();
|
||||
return new SimpleToken(TokenKind::LessEquals, this -> _position - 2, 2);
|
||||
}
|
||||
return new SimpleToken(TokenKind::Less, this -> _position - 1, 1);
|
||||
case '>':
|
||||
if (Lexer::Peek() == '='){
|
||||
Lexer::Next();
|
||||
return new SimpleToken(TokenKind::GreaterEquals, this -> _position - 2, 2);
|
||||
}
|
||||
return new SimpleToken(TokenKind::Greater, this -> _position - 1, 1);
|
||||
case '~':
|
||||
if (Lexer::Peek() == '='){
|
||||
Lexer::Next();
|
||||
|
|
|
@ -223,12 +223,21 @@ UnaryOperatorKind GetUnaryOperatorKind(TokenKind kind){
|
|||
|
||||
BinaryOperatorKind GetBinaryOperatorKind(TokenKind kind){
|
||||
switch (kind){
|
||||
// Math operators
|
||||
case TokenKind::PlusToken: return BinaryOperatorKind ::Addition;
|
||||
case TokenKind::MinusToken: return BinaryOperatorKind ::Subtraction;
|
||||
case TokenKind::StarToken: return BinaryOperatorKind ::Multiplication;
|
||||
case TokenKind::SlashToken: return BinaryOperatorKind ::Division;
|
||||
|
||||
// Equality operators
|
||||
case TokenKind::EqualityToken: return BinaryOperatorKind ::Equality;
|
||||
case TokenKind::InequalityToken: return BinaryOperatorKind ::Inequality;
|
||||
case TokenKind ::Less: return BinaryOperatorKind ::Less;
|
||||
case TokenKind ::LessEquals: return BinaryOperatorKind ::LessOrEquals;
|
||||
case TokenKind ::Greater: return BinaryOperatorKind ::Greater;
|
||||
case TokenKind ::GreaterEquals: return BinaryOperatorKind ::GreaterOrEquals;
|
||||
|
||||
// logical operators
|
||||
case TokenKind::AndKeyword: return BinaryOperatorKind ::LogicalAnd;
|
||||
case TokenKind::OrKeyword: return BinaryOperatorKind ::LogicalOr;
|
||||
default: // This should never trigger, so throw.
|
||||
|
@ -238,12 +247,22 @@ BinaryOperatorKind GetBinaryOperatorKind(TokenKind kind){
|
|||
|
||||
OperatorPrecedence GetBinaryPrecedence(TokenKind kind){
|
||||
switch (kind){
|
||||
// Math
|
||||
case TokenKind::PlusToken: return OperatorPrecedence ::Additive;
|
||||
case TokenKind::MinusToken: return OperatorPrecedence ::Additive;
|
||||
case TokenKind::StarToken: return OperatorPrecedence ::Multiplication;
|
||||
case TokenKind::SlashToken: return OperatorPrecedence ::Multiplication;
|
||||
|
||||
// Equality
|
||||
case TokenKind::EqualityToken: return OperatorPrecedence ::Equality;
|
||||
case TokenKind::InequalityToken: return OperatorPrecedence ::Equality;
|
||||
case TokenKind ::Less: return OperatorPrecedence ::Equality;
|
||||
case TokenKind ::LessEquals: return OperatorPrecedence ::Equality;
|
||||
case TokenKind ::Greater: return OperatorPrecedence ::Equality;
|
||||
case TokenKind ::GreaterEquals: return OperatorPrecedence ::Equality;
|
||||
|
||||
|
||||
// Logical
|
||||
case TokenKind::AndKeyword: return OperatorPrecedence ::LogicalAnd;
|
||||
case TokenKind::OrKeyword: return OperatorPrecedence ::LogicalOr;
|
||||
default:
|
||||
|
|
|
@ -13,6 +13,11 @@ enum class TokenKind{
|
|||
AssignmentToken,
|
||||
EqualityToken,
|
||||
InequalityToken,
|
||||
Less,
|
||||
LessEquals,
|
||||
Greater,
|
||||
GreaterEquals,
|
||||
|
||||
OpenParenthesis,
|
||||
CloseParenthesis,
|
||||
OpenSquareBracket,
|
||||
|
|
|
@ -63,6 +63,113 @@ TEST_CASE( "10 Not Equals 5", "[integration]" ) {
|
|||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "10 < 5 == false", "[integration]" ) {
|
||||
auto script = Script::Create("10 < 5");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto lastValue = script->GetLastValue();
|
||||
REQUIRE_FALSE(lastValue->EvaluateBool());
|
||||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "2 < 60 == true", "[integration]" ) {
|
||||
auto script = Script::Create("2 < 60");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto lastValue = script->GetLastValue();
|
||||
REQUIRE(lastValue->EvaluateBool());
|
||||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "5 < 5 == false", "[integration]" ) {
|
||||
auto script = Script::Create("5 < 5");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto lastValue = script->GetLastValue();
|
||||
REQUIRE_FALSE(lastValue->EvaluateBool());
|
||||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "10 <= 5 == false", "[integration]" ) {
|
||||
auto script = Script::Create("10 <= 5");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto lastValue = script->GetLastValue();
|
||||
REQUIRE_FALSE(lastValue->EvaluateBool());
|
||||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "2 <= 60 == true", "[integration]" ) {
|
||||
auto script = Script::Create("2 <= 60");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto lastValue = script->GetLastValue();
|
||||
REQUIRE(lastValue->EvaluateBool());
|
||||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "5 <= 5 == true", "[integration]" ) {
|
||||
auto script = Script::Create("5 <= 5");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto lastValue = script->GetLastValue();
|
||||
REQUIRE(lastValue->EvaluateBool());
|
||||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "10 > 5 == true", "[integration]" ) {
|
||||
auto script = Script::Create("10 > 5");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto lastValue = script->GetLastValue();
|
||||
REQUIRE(lastValue->EvaluateBool());
|
||||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "2 > 60 == false", "[integration]" ) {
|
||||
auto script = Script::Create("2 > 60");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto lastValue = script->GetLastValue();
|
||||
REQUIRE_FALSE(lastValue->EvaluateBool());
|
||||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "5 > 5 == false", "[integration]" ) {
|
||||
auto script = Script::Create("5 > 5");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto lastValue = script->GetLastValue();
|
||||
REQUIRE_FALSE(lastValue->EvaluateBool());
|
||||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "10 >= 5 == true", "[integration]" ) {
|
||||
auto script = Script::Create("10 >= 5");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto lastValue = script->GetLastValue();
|
||||
REQUIRE(lastValue->EvaluateBool());
|
||||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "2 >= 60 == false", "[integration]" ) {
|
||||
auto script = Script::Create("2 >= 60");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto lastValue = script->GetLastValue();
|
||||
REQUIRE_FALSE(lastValue->EvaluateBool());
|
||||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "5 >= 5 == true", "[integration]" ) {
|
||||
auto script = Script::Create("5 >= 5");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto lastValue = script->GetLastValue();
|
||||
REQUIRE(lastValue->EvaluateBool());
|
||||
delete script;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue