Implements binding binary expressions

This commit is contained in:
Deukhoofd 2019-05-21 22:15:51 +02:00
parent c8183e5405
commit 62e938e039
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
5 changed files with 135 additions and 4 deletions

View File

@ -42,6 +42,9 @@ BoundExpression* Binder::BindExpression(ParsedExpression* expression){
case ParsedExpressionKind ::LiteralBool: case ParsedExpressionKind ::LiteralBool:
return new BoundLiteralBoolExpression(((LiteralBoolExpression*)expression)->GetValue(), expression->GetStartPosition(), expression->GetLength()); return new BoundLiteralBoolExpression(((LiteralBoolExpression*)expression)->GetValue(), expression->GetStartPosition(), expression->GetLength());
case ParsedExpressionKind ::Binary:
return this -> BindBinaryOperator((BinaryExpression*)expression);
case ParsedExpressionKind ::Parenthesized: case ParsedExpressionKind ::Parenthesized:
return BindExpression(((ParenthesizedExpression*)expression)->GetInnerExpression()); return BindExpression(((ParenthesizedExpression*)expression)->GetInnerExpression());
@ -50,3 +53,80 @@ BoundExpression* Binder::BindExpression(ParsedExpression* expression){
} }
} }
BoundExpression* Binder::BindBinaryOperator(BinaryExpression* expression){
auto boundLeft = this -> BindExpression(expression->GetLeft());
auto boundRight = this -> BindExpression(expression->GetRight());
auto boundLeftType = boundLeft->GetType();
auto boundRightType = boundRight->GetType();
switch (expression->GetOperatorKind()){
case BinaryOperatorKind ::Addition:
if (boundLeftType->GetClass() == TypeClass::Number && boundRightType->GetClass() == TypeClass::Number){
auto leftNumeric = (NumericScriptType*)boundLeftType;
auto rightNumeric = (NumericScriptType*)boundRightType;
if (leftNumeric->IsAwareOfFloat() && rightNumeric->IsAwareOfFloat()){
return new BoundBinaryExpression(boundLeft, boundRight,
BoundBinaryOperator::Addition, new NumericScriptType(true, leftNumeric->IsFloat() || rightNumeric->IsFloat()));
}
else{
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperator::Addition, new NumericScriptType(false, false));
}
}
//TODO: String Concatenation
break;
case BinaryOperatorKind ::Subtraction:
if (boundLeftType->GetClass() == TypeClass::Number && boundRightType->GetClass() == TypeClass::Number){
auto leftNumeric = (NumericScriptType*)boundLeftType;
auto rightNumeric = (NumericScriptType*)boundRightType;
if (leftNumeric->IsAwareOfFloat() && rightNumeric->IsAwareOfFloat()){
return new BoundBinaryExpression(boundLeft, boundRight,
BoundBinaryOperator::Subtraction, new NumericScriptType(true, leftNumeric->IsFloat() || rightNumeric->IsFloat()));
}
else{
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperator::Subtraction, new NumericScriptType(false, false));
}
}
break;
case BinaryOperatorKind ::Multiplication:
if (boundLeftType->GetClass() == TypeClass::Number && boundRightType->GetClass() == TypeClass::Number){
auto leftNumeric = (NumericScriptType*)boundLeftType;
auto rightNumeric = (NumericScriptType*)boundRightType;
if (leftNumeric->IsAwareOfFloat() && rightNumeric->IsAwareOfFloat()){
return new BoundBinaryExpression(boundLeft, boundRight,
BoundBinaryOperator::Multiplication, new NumericScriptType(true, leftNumeric->IsFloat() || rightNumeric->IsFloat()));
}
else{
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperator::Multiplication, new NumericScriptType(false, false));
}
}
break;
case BinaryOperatorKind ::Division:
if (boundLeftType->GetClass() == TypeClass::Number && boundRightType->GetClass() == TypeClass::Number){
auto leftNumeric = (NumericScriptType*)boundLeftType;
auto rightNumeric = (NumericScriptType*)boundRightType;
if (leftNumeric->IsAwareOfFloat() && rightNumeric->IsAwareOfFloat()){
return new BoundBinaryExpression(boundLeft, boundRight,
BoundBinaryOperator::Division, new NumericScriptType(true, leftNumeric->IsFloat() || rightNumeric->IsFloat()));
}
else{
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperator::Division, new NumericScriptType(false, false));
}
}
break;
case BinaryOperatorKind ::Equality:
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperator::Equality, new ScriptType(TypeClass::Bool));
case BinaryOperatorKind ::LogicalAnd:
if (boundLeftType->GetClass() == TypeClass::Bool && boundRightType->GetClass() == TypeClass::Bool)
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperator::LogicalAnd, new ScriptType(TypeClass::Bool));
break;
case BinaryOperatorKind ::LogicalOr:
if (boundLeftType->GetClass() == TypeClass::Bool && boundRightType->GetClass() == TypeClass::Bool)
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperator::LogicalOr, new ScriptType(TypeClass::Bool));
break;
default:
break;
}
//TODO: Log error
return new BoundBadExpression(boundLeft->GetStartPosition(), boundRight->GetEndPosition() - boundLeft->GetStartPosition());
}

View File

@ -8,12 +8,14 @@
class Binder { class Binder {
BoundStatement *BindStatement(ParsedStatement *statement); BoundStatement *BindStatement(ParsedStatement *statement);
BoundStatement *BindBlockStatement(ParsedStatement *statement); BoundStatement *BindBlockStatement(ParsedStatement *statement);
BoundStatement *BindExpressionStatement(ParsedStatement *statement);
BoundExpression *BindExpression(ParsedExpression *expression);
BoundExpression *BindBinaryOperator(BinaryExpression *expression);
public: public:
static BoundScriptStatement* Bind(ParsedScriptStatement* s); static BoundScriptStatement* Bind(ParsedScriptStatement* s);
BoundExpression *BindExpression(ParsedExpression *expression);
BoundStatement *BindExpressionStatement(ParsedStatement *statement);
}; };

View File

@ -6,6 +6,7 @@
#include <string> #include <string>
#include "../../ScriptType.hpp" #include "../../ScriptType.hpp"
#include "../BoundOperators.hpp"
using namespace std; using namespace std;
@ -47,6 +48,9 @@ public:
unsigned int GetLength(){ unsigned int GetLength(){
return _length; return _length;
} }
unsigned int GetEndPosition(){
return _start + _length - 1;
}
}; };
class BoundBadExpression : public BoundExpression{ class BoundBadExpression : public BoundExpression{
@ -126,6 +130,27 @@ public:
} }
}; };
class BoundBinaryExpression : public BoundExpression {
BoundExpression* _left;
BoundExpression* _right;
BoundBinaryOperator _operator;
public:
BoundBinaryExpression(BoundExpression* left, BoundExpression* right, BoundBinaryOperator op, ScriptType* result)
: BoundExpression(left->GetStartPosition(), right->GetEndPosition() - left->GetStartPosition(), result){
_left = left;
_right = right;
_operator = op;
}
~BoundBinaryExpression() final{
delete _left;
delete _right;
}
BoundExpressionKind GetKind() final{
return BoundExpressionKind ::Binary;
}
};

View File

@ -0,0 +1,16 @@
#ifndef PORYGONLANG_BOUNDOPERATORS_HPP
#define PORYGONLANG_BOUNDOPERATORS_HPP
enum class BoundBinaryOperator{
Addition,
Subtraction,
Multiplication,
Division,
Equality,
LogicalAnd,
LogicalOr,
Concatenation
};
#endif //PORYGONLANG_BOUNDOPERATORS_HPP

View File

@ -20,7 +20,7 @@ public:
_class = c; _class = c;
} }
explicit virtual operator TypeClass(){ TypeClass GetClass(){
return _class; return _class;
} }
}; };
@ -35,6 +35,14 @@ public:
_awareOfFloat = floatAware; _awareOfFloat = floatAware;
_isFloat = isFloat; _isFloat = isFloat;
} }
bool IsAwareOfFloat(){
return _awareOfFloat;
}
bool IsFloat(){
return _isFloat;
}
}; };
#endif //PORYGONLANG_SCRIPTTYPE_HPP #endif //PORYGONLANG_SCRIPTTYPE_HPP