Implements binding unary expressions
This commit is contained in:
parent
62e938e039
commit
2cdb9abdb6
|
@ -1,8 +1,9 @@
|
||||||
|
|
||||||
#include "Binder.hpp"
|
#include "Binder.hpp"
|
||||||
|
|
||||||
BoundScriptStatement *Binder::Bind(ParsedScriptStatement *s) {
|
BoundScriptStatement *Binder::Bind(Script* script, ParsedScriptStatement *s) {
|
||||||
auto binder = Binder();
|
auto binder = Binder();
|
||||||
|
binder.ScriptData = script;
|
||||||
auto statements = s->GetStatements();
|
auto statements = s->GetStatements();
|
||||||
vector<BoundStatement*> boundStatements (statements.size());
|
vector<BoundStatement*> boundStatements (statements.size());
|
||||||
for (int i = 0; i < statements.size(); i++){
|
for (int i = 0; i < statements.size(); i++){
|
||||||
|
@ -44,6 +45,8 @@ BoundExpression* Binder::BindExpression(ParsedExpression* expression){
|
||||||
|
|
||||||
case ParsedExpressionKind ::Binary:
|
case ParsedExpressionKind ::Binary:
|
||||||
return this -> BindBinaryOperator((BinaryExpression*)expression);
|
return this -> BindBinaryOperator((BinaryExpression*)expression);
|
||||||
|
case ParsedExpressionKind ::Unary:
|
||||||
|
return this -> BindUnaryOperator((UnaryExpression*)expression);
|
||||||
|
|
||||||
case ParsedExpressionKind ::Parenthesized:
|
case ParsedExpressionKind ::Parenthesized:
|
||||||
return BindExpression(((ParenthesizedExpression*)expression)->GetInnerExpression());
|
return BindExpression(((ParenthesizedExpression*)expression)->GetInnerExpression());
|
||||||
|
@ -67,10 +70,10 @@ BoundExpression* Binder::BindBinaryOperator(BinaryExpression* expression){
|
||||||
auto rightNumeric = (NumericScriptType*)boundRightType;
|
auto rightNumeric = (NumericScriptType*)boundRightType;
|
||||||
if (leftNumeric->IsAwareOfFloat() && rightNumeric->IsAwareOfFloat()){
|
if (leftNumeric->IsAwareOfFloat() && rightNumeric->IsAwareOfFloat()){
|
||||||
return new BoundBinaryExpression(boundLeft, boundRight,
|
return new BoundBinaryExpression(boundLeft, boundRight,
|
||||||
BoundBinaryOperator::Addition, new NumericScriptType(true, leftNumeric->IsFloat() || rightNumeric->IsFloat()));
|
BoundBinaryOperation::Addition, new NumericScriptType(true, leftNumeric->IsFloat() || rightNumeric->IsFloat()));
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperator::Addition, new NumericScriptType(false, false));
|
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Addition, new NumericScriptType(false, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TODO: String Concatenation
|
//TODO: String Concatenation
|
||||||
|
@ -81,10 +84,10 @@ BoundExpression* Binder::BindBinaryOperator(BinaryExpression* expression){
|
||||||
auto rightNumeric = (NumericScriptType*)boundRightType;
|
auto rightNumeric = (NumericScriptType*)boundRightType;
|
||||||
if (leftNumeric->IsAwareOfFloat() && rightNumeric->IsAwareOfFloat()){
|
if (leftNumeric->IsAwareOfFloat() && rightNumeric->IsAwareOfFloat()){
|
||||||
return new BoundBinaryExpression(boundLeft, boundRight,
|
return new BoundBinaryExpression(boundLeft, boundRight,
|
||||||
BoundBinaryOperator::Subtraction, new NumericScriptType(true, leftNumeric->IsFloat() || rightNumeric->IsFloat()));
|
BoundBinaryOperation::Subtraction, new NumericScriptType(true, leftNumeric->IsFloat() || rightNumeric->IsFloat()));
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperator::Subtraction, new NumericScriptType(false, false));
|
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Subtraction, new NumericScriptType(false, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -94,10 +97,10 @@ BoundExpression* Binder::BindBinaryOperator(BinaryExpression* expression){
|
||||||
auto rightNumeric = (NumericScriptType*)boundRightType;
|
auto rightNumeric = (NumericScriptType*)boundRightType;
|
||||||
if (leftNumeric->IsAwareOfFloat() && rightNumeric->IsAwareOfFloat()){
|
if (leftNumeric->IsAwareOfFloat() && rightNumeric->IsAwareOfFloat()){
|
||||||
return new BoundBinaryExpression(boundLeft, boundRight,
|
return new BoundBinaryExpression(boundLeft, boundRight,
|
||||||
BoundBinaryOperator::Multiplication, new NumericScriptType(true, leftNumeric->IsFloat() || rightNumeric->IsFloat()));
|
BoundBinaryOperation::Multiplication, new NumericScriptType(true, leftNumeric->IsFloat() || rightNumeric->IsFloat()));
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperator::Multiplication, new NumericScriptType(false, false));
|
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Multiplication, new NumericScriptType(false, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -107,26 +110,57 @@ BoundExpression* Binder::BindBinaryOperator(BinaryExpression* expression){
|
||||||
auto rightNumeric = (NumericScriptType*)boundRightType;
|
auto rightNumeric = (NumericScriptType*)boundRightType;
|
||||||
if (leftNumeric->IsAwareOfFloat() && rightNumeric->IsAwareOfFloat()){
|
if (leftNumeric->IsAwareOfFloat() && rightNumeric->IsAwareOfFloat()){
|
||||||
return new BoundBinaryExpression(boundLeft, boundRight,
|
return new BoundBinaryExpression(boundLeft, boundRight,
|
||||||
BoundBinaryOperator::Division, new NumericScriptType(true, leftNumeric->IsFloat() || rightNumeric->IsFloat()));
|
BoundBinaryOperation::Division, new NumericScriptType(true, leftNumeric->IsFloat() || rightNumeric->IsFloat()));
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperator::Division, new NumericScriptType(false, false));
|
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Division, new NumericScriptType(false, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BinaryOperatorKind ::Equality:
|
case BinaryOperatorKind ::Equality:
|
||||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperator::Equality, new ScriptType(TypeClass::Bool));
|
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Equality, new ScriptType(TypeClass::Bool));
|
||||||
case BinaryOperatorKind ::LogicalAnd:
|
case BinaryOperatorKind ::LogicalAnd:
|
||||||
if (boundLeftType->GetClass() == TypeClass::Bool && boundRightType->GetClass() == TypeClass::Bool)
|
if (boundLeftType->GetClass() == TypeClass::Bool && boundRightType->GetClass() == TypeClass::Bool)
|
||||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperator::LogicalAnd, new ScriptType(TypeClass::Bool));
|
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::LogicalAnd, new ScriptType(TypeClass::Bool));
|
||||||
break;
|
break;
|
||||||
case BinaryOperatorKind ::LogicalOr:
|
case BinaryOperatorKind ::LogicalOr:
|
||||||
if (boundLeftType->GetClass() == TypeClass::Bool && boundRightType->GetClass() == TypeClass::Bool)
|
if (boundLeftType->GetClass() == TypeClass::Bool && boundRightType->GetClass() == TypeClass::Bool)
|
||||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperator::LogicalOr, new ScriptType(TypeClass::Bool));
|
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::LogicalOr, new ScriptType(TypeClass::Bool));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//TODO: Log error
|
this -> ScriptData -> Diagnostics->LogError(DiagnosticCode::NoBinaryOperationFound, expression->GetStartPosition(), expression->GetLength());
|
||||||
return new BoundBadExpression(boundLeft->GetStartPosition(), boundRight->GetEndPosition() - boundLeft->GetStartPosition());
|
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
BoundExpression* Binder::BindUnaryOperator(UnaryExpression* expression){
|
||||||
|
auto operand = this -> BindExpression(expression->GetOperand());
|
||||||
|
auto operandType = operand -> GetType();
|
||||||
|
switch (expression->GetOperatorKind()){
|
||||||
|
case UnaryOperatorKind ::Identity:
|
||||||
|
if (operandType->GetClass() == TypeClass::Number){
|
||||||
|
// Identity won't change anything during evaluation, so just return the inner operand.
|
||||||
|
return operand;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UnaryOperatorKind ::Negation:
|
||||||
|
if (operandType->GetClass() == TypeClass::Number){
|
||||||
|
auto innerType = (NumericScriptType*)operandType;
|
||||||
|
return new BoundUnaryExpression(operand, BoundUnaryOperation::Negation, new NumericScriptType(innerType->IsAwareOfFloat(),
|
||||||
|
innerType->IsFloat()), expression->GetStartPosition(), expression->GetLength());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UnaryOperatorKind ::LogicalNegation:
|
||||||
|
if (operandType->GetClass() == TypeClass::Bool){
|
||||||
|
return new BoundUnaryExpression(operand, BoundUnaryOperation::LogicalNegation, new ScriptType(TypeClass::Bool),
|
||||||
|
expression->GetStartPosition(), expression->GetLength());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this -> ScriptData -> Diagnostics->LogError(DiagnosticCode::NoUnaryOperationFound, expression->GetStartPosition(), expression->GetLength());
|
||||||
|
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
||||||
|
|
||||||
}
|
}
|
|
@ -3,18 +3,21 @@
|
||||||
#define PORYGONLANG_BINDER_HPP
|
#define PORYGONLANG_BINDER_HPP
|
||||||
#include "../Parser/ParsedStatements/ParsedStatement.hpp"
|
#include "../Parser/ParsedStatements/ParsedStatement.hpp"
|
||||||
#include "BoundStatements/BoundStatement.hpp"
|
#include "BoundStatements/BoundStatement.hpp"
|
||||||
|
#include "../Script.hpp"
|
||||||
|
|
||||||
|
|
||||||
class Binder {
|
class Binder {
|
||||||
|
Script* ScriptData;
|
||||||
|
|
||||||
BoundStatement *BindStatement(ParsedStatement *statement);
|
BoundStatement *BindStatement(ParsedStatement *statement);
|
||||||
BoundStatement *BindBlockStatement(ParsedStatement *statement);
|
BoundStatement *BindBlockStatement(ParsedStatement *statement);
|
||||||
BoundStatement *BindExpressionStatement(ParsedStatement *statement);
|
BoundStatement *BindExpressionStatement(ParsedStatement *statement);
|
||||||
|
|
||||||
BoundExpression *BindExpression(ParsedExpression *expression);
|
BoundExpression *BindExpression(ParsedExpression *expression);
|
||||||
BoundExpression *BindBinaryOperator(BinaryExpression *expression);
|
BoundExpression *BindBinaryOperator(BinaryExpression *expression);
|
||||||
|
BoundExpression *BindUnaryOperator(UnaryExpression *expression);
|
||||||
public:
|
public:
|
||||||
static BoundScriptStatement* Bind(ParsedScriptStatement* s);
|
static BoundScriptStatement* Bind(Script* script, ParsedScriptStatement* s);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -133,13 +133,13 @@ public:
|
||||||
class BoundBinaryExpression : public BoundExpression {
|
class BoundBinaryExpression : public BoundExpression {
|
||||||
BoundExpression* _left;
|
BoundExpression* _left;
|
||||||
BoundExpression* _right;
|
BoundExpression* _right;
|
||||||
BoundBinaryOperator _operator;
|
BoundBinaryOperation _operation;
|
||||||
public:
|
public:
|
||||||
BoundBinaryExpression(BoundExpression* left, BoundExpression* right, BoundBinaryOperator op, ScriptType* result)
|
BoundBinaryExpression(BoundExpression* left, BoundExpression* right, BoundBinaryOperation op, ScriptType* result)
|
||||||
: BoundExpression(left->GetStartPosition(), right->GetEndPosition() - left->GetStartPosition(), result){
|
: BoundExpression(left->GetStartPosition(), right->GetEndPosition() - left->GetStartPosition(), result){
|
||||||
_left = left;
|
_left = left;
|
||||||
_right = right;
|
_right = right;
|
||||||
_operator = op;
|
_operation = op;
|
||||||
}
|
}
|
||||||
~BoundBinaryExpression() final{
|
~BoundBinaryExpression() final{
|
||||||
delete _left;
|
delete _left;
|
||||||
|
@ -151,7 +151,24 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BoundUnaryExpression : public BoundExpression {
|
||||||
|
BoundExpression* _operand;
|
||||||
|
BoundUnaryOperation _operation;
|
||||||
|
public:
|
||||||
|
BoundUnaryExpression(BoundExpression* operand, BoundUnaryOperation op, ScriptType* result, unsigned int start, unsigned int length)
|
||||||
|
:BoundExpression(start, length, result){
|
||||||
|
_operand = operand;
|
||||||
|
_operation = op;
|
||||||
|
}
|
||||||
|
|
||||||
|
~BoundUnaryExpression() final{
|
||||||
|
delete _operand;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoundExpressionKind GetKind() final{
|
||||||
|
return BoundExpressionKind ::Unary;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#ifndef PORYGONLANG_BOUNDOPERATORS_HPP
|
#ifndef PORYGONLANG_BOUNDOPERATORS_HPP
|
||||||
#define PORYGONLANG_BOUNDOPERATORS_HPP
|
#define PORYGONLANG_BOUNDOPERATORS_HPP
|
||||||
|
|
||||||
enum class BoundBinaryOperator{
|
enum class BoundBinaryOperation{
|
||||||
Addition,
|
Addition,
|
||||||
Subtraction,
|
Subtraction,
|
||||||
Multiplication,
|
Multiplication,
|
||||||
|
@ -13,4 +13,10 @@ enum class BoundBinaryOperator{
|
||||||
Concatenation
|
Concatenation
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class BoundUnaryOperation{
|
||||||
|
Identity,
|
||||||
|
Negation,
|
||||||
|
LogicalNegation,
|
||||||
|
};
|
||||||
|
|
||||||
#endif //PORYGONLANG_BOUNDOPERATORS_HPP
|
#endif //PORYGONLANG_BOUNDOPERATORS_HPP
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
enum class DiagnosticCode{
|
enum class DiagnosticCode{
|
||||||
UnexpectedCharacter,
|
UnexpectedCharacter,
|
||||||
UnexpectedToken,
|
UnexpectedToken,
|
||||||
|
|
||||||
|
NoBinaryOperationFound,
|
||||||
|
NoUnaryOperationFound,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //PORYGONLANG_DIAGNOSTICCODE_HPP
|
#endif //PORYGONLANG_DIAGNOSTICCODE_HPP
|
||||||
|
|
Loading…
Reference in New Issue