PorygonLang/src/Binder/Binder.cpp

132 lines
7.2 KiB
C++
Raw Normal View History

2019-05-21 16:09:08 +00:00
#include "Binder.hpp"
BoundScriptStatement *Binder::Bind(ParsedScriptStatement *s) {
auto binder = Binder();
auto statements = s->GetStatements();
vector<BoundStatement*> boundStatements (statements.size());
for (int i = 0; i < statements.size(); i++){
boundStatements[i] = binder.BindStatement(statements[i]);
}
return new BoundScriptStatement(boundStatements);
2019-05-21 16:09:08 +00:00
}
BoundStatement* Binder::BindStatement(ParsedStatement* statement){
switch (statement -> GetKind()) {
case ParsedStatementKind ::Script: throw; // This shouldn't happen.
case ParsedStatementKind ::Block: return this -> BindBlockStatement(statement);
case ParsedStatementKind ::Expression: return this -> BindExpressionStatement(statement);
}
}
BoundStatement *Binder::BindBlockStatement(ParsedStatement *statement) {
auto statements = ((ParsedBlockStatement*)statement)->GetStatements();
vector<BoundStatement*> boundStatements (statements.size());
for (int i = 0; i < statements.size(); i++){
boundStatements[i] = this -> BindStatement(statements[i]);
}
return new BoundBlockStatement(boundStatements);
}
BoundStatement *Binder::BindExpressionStatement(ParsedStatement *statement) {
auto exp = ((ParsedExpressionStatement*)statement)->GetExpression();
return new BoundExpressionStatement(this -> BindExpression(exp));
}
BoundExpression* Binder::BindExpression(ParsedExpression* expression){
switch (expression -> GetKind()){
case ParsedExpressionKind ::LiteralInteger:
return new BoundLiteralIntegerExpression(((LiteralIntegerExpression*)expression)->GetValue(), expression->GetStartPosition(), expression->GetLength());
case ParsedExpressionKind ::LiteralFloat:
return new BoundLiteralFloatExpression(((LiteralFloatExpression*)expression)->GetValue(), expression->GetStartPosition(), expression->GetLength());
case ParsedExpressionKind ::LiteralBool:
return new BoundLiteralBoolExpression(((LiteralBoolExpression*)expression)->GetValue(), expression->GetStartPosition(), expression->GetLength());
2019-05-21 20:15:51 +00:00
case ParsedExpressionKind ::Binary:
return this -> BindBinaryOperator((BinaryExpression*)expression);
case ParsedExpressionKind ::Parenthesized:
return BindExpression(((ParenthesizedExpression*)expression)->GetInnerExpression());
case ParsedExpressionKind ::Bad:
return new BoundBadExpression(expression->GetStartPosition(), expression-> GetLength());
}
}
2019-05-21 20:15:51 +00:00
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());
}