Implements support for functions with the same name, but different parameters
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -3,8 +3,9 @@
|
||||
#include "Binder.hpp"
|
||||
#include "../TableScriptType.hpp"
|
||||
#include "BoundExpressions/BoundTableExpression.hpp"
|
||||
#include "BoundExpressions/BoundFunctionCallExpression.hpp"
|
||||
#include "../UserData/UserDataScriptType.hpp"
|
||||
#include <memory>
|
||||
#include "../FunctionScriptType.hpp"
|
||||
|
||||
using namespace Porygon::Parser;
|
||||
|
||||
@@ -158,19 +159,38 @@ namespace Porygon::Binder {
|
||||
|
||||
auto identifier = functionStatement->GetIdentifier();
|
||||
auto returnType = make_shared<ScriptType>(TypeClass::Nil);
|
||||
auto type = make_shared<FunctionScriptType>(returnType, parameterTypes, parameterKeys, scopeIndex);
|
||||
this->_currentFunction = type;
|
||||
auto option = new ScriptFunctionOption(returnType, parameterTypes, parameterKeys);
|
||||
this->_currentFunction = option;
|
||||
|
||||
auto assignment = this->_scope->AssignVariable(identifier, type);
|
||||
if (assignment.GetResult() != VariableAssignmentResult::Ok) {
|
||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable, statement->GetStartPosition(),
|
||||
statement->GetLength());
|
||||
return new BoundBadStatement();
|
||||
shared_ptr<GenericFunctionScriptType> type;
|
||||
auto scope = this -> _scope -> Exists(identifier);
|
||||
BoundVariableKey* assignmentKey;
|
||||
if (scope >= 0){
|
||||
auto var = this -> _scope -> GetVariable(scope, identifier);
|
||||
auto varType =var->GetType();
|
||||
if (varType->GetClass() != TypeClass::Function){
|
||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable, statement->GetStartPosition(),
|
||||
statement->GetLength());
|
||||
}
|
||||
type = dynamic_pointer_cast<GenericFunctionScriptType>(varType);
|
||||
type->RegisterFunctionOption(option);
|
||||
assignmentKey = new BoundVariableKey(identifier, scope, false);
|
||||
} else{
|
||||
type = make_shared<GenericFunctionScriptType>();
|
||||
type->RegisterFunctionOption(option);
|
||||
auto assignment = this->_scope->AssignVariable(identifier, type);
|
||||
if (assignment.GetResult() != VariableAssignmentResult::Ok) {
|
||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable, statement->GetStartPosition(),
|
||||
statement->GetLength());
|
||||
return new BoundBadStatement();
|
||||
}
|
||||
assignmentKey = assignment.GetKey();
|
||||
}
|
||||
|
||||
auto boundBlock = this->BindBlockStatement(functionStatement->GetBlock());
|
||||
this->_scope->GoOuterScope();
|
||||
this->_currentFunction = nullptr;
|
||||
return new BoundFunctionDeclarationStatement(type, assignment.GetKey(), (BoundBlockStatement *) boundBlock);
|
||||
return new BoundFunctionDeclarationStatement(type, assignmentKey, (BoundBlockStatement *) boundBlock);
|
||||
}
|
||||
|
||||
BoundStatement *Binder::BindReturnStatement(const ParsedStatement *statement) {
|
||||
@@ -558,28 +578,23 @@ namespace Porygon::Binder {
|
||||
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
auto functionType = std::dynamic_pointer_cast<GenericFunctionScriptType>(type);
|
||||
auto parameterTypes = functionType->GetParameterTypes();
|
||||
auto givenParameters = expression->GetParameters();
|
||||
if (parameterTypes.size() != givenParameters->size()) {
|
||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::ParameterCountMismatch,
|
||||
auto givenParameterTypes = vector<shared_ptr<ScriptType>>(givenParameters->size());
|
||||
vector<BoundExpression *> boundParameters = vector<BoundExpression *>(givenParameters->size());
|
||||
for (int i = 0; i < givenParameters->size(); i++){
|
||||
boundParameters[i] = this -> BindExpression(givenParameters->at(i));
|
||||
givenParameterTypes[i] = boundParameters[i]->GetType();
|
||||
}
|
||||
|
||||
auto functionOption = functionType->GetFunctionOption(givenParameterTypes);
|
||||
if (functionOption == nullptr){
|
||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidFunctionParameters,
|
||||
expression->GetStartPosition(),
|
||||
expression->GetLength());
|
||||
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
vector<BoundExpression *> boundParameters = vector<BoundExpression *>(givenParameters->size());
|
||||
for (int i = 0; i < givenParameters->size(); i++) {
|
||||
auto parameter = givenParameters->at(i);
|
||||
auto boundParameter = this->BindExpression(parameter);
|
||||
if (boundParameter->GetType().get()->operator!=(parameterTypes.at(i).get())) {
|
||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::ParameterTypeMismatch,
|
||||
parameter->GetStartPosition(),
|
||||
parameter->GetLength());
|
||||
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
boundParameters[i] = boundParameter;
|
||||
}
|
||||
|
||||
return new BoundFunctionCallExpression(functionExpression, boundParameters, functionType.get()->GetReturnType(),
|
||||
return new BoundFunctionCallExpression(functionExpression, boundParameters, functionOption, functionOption->GetReturnType(),
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "../Script.hpp"
|
||||
#include "BoundVariables/BoundScope.hpp"
|
||||
#include "../Parser/ParsedExpressions/ParsedTableExpression.hpp"
|
||||
#include "../FunctionScriptType.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Porygon::Parser;
|
||||
@@ -14,7 +15,7 @@ namespace Porygon::Binder {
|
||||
class Binder {
|
||||
Porygon::Script *_scriptData;
|
||||
BoundScope *_scope;
|
||||
shared_ptr<FunctionScriptType> _currentFunction;
|
||||
GenericFunctionOption* _currentFunction;
|
||||
|
||||
~Binder();
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "../../ScriptType.hpp"
|
||||
#include "../BoundOperators.hpp"
|
||||
#include "../BoundVariables/BoundVariableKey.hpp"
|
||||
#include "../../FunctionScriptType.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -227,36 +228,6 @@ namespace Porygon::Binder {
|
||||
}
|
||||
};
|
||||
|
||||
class BoundFunctionCallExpression : public BoundExpression {
|
||||
const BoundExpression *_functionExpression;
|
||||
const vector<BoundExpression *> _parameters;
|
||||
public:
|
||||
BoundFunctionCallExpression(BoundExpression *functionExpression, vector<BoundExpression *> parameters,
|
||||
shared_ptr<ScriptType> result,
|
||||
unsigned int start, unsigned int length)
|
||||
: BoundExpression(start, length, std::move(result)), _functionExpression(functionExpression),
|
||||
_parameters(std::move(parameters)) {}
|
||||
|
||||
~BoundFunctionCallExpression() final {
|
||||
delete _functionExpression;
|
||||
for (auto p : _parameters) {
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
|
||||
const BoundExpressionKind GetKind() const final {
|
||||
return BoundExpressionKind::FunctionCall;
|
||||
}
|
||||
|
||||
const BoundExpression *GetFunctionExpression() const {
|
||||
return _functionExpression;
|
||||
}
|
||||
|
||||
const vector<BoundExpression *> *GetParameters() const {
|
||||
return &_parameters;
|
||||
}
|
||||
};
|
||||
|
||||
class BoundIndexExpression : public BoundExpression {
|
||||
const BoundExpression *_indexableExpression;
|
||||
const BoundExpression *_indexExpression;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#include "BoundFunctionCallExpression.hpp"
|
||||
45
src/Binder/BoundExpressions/BoundFunctionCallExpression.hpp
Normal file
45
src/Binder/BoundExpressions/BoundFunctionCallExpression.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef PORYGONLANG_BOUNDFUNCTIONCALLEXPRESSION_HPP
|
||||
#define PORYGONLANG_BOUNDFUNCTIONCALLEXPRESSION_HPP
|
||||
|
||||
#include "BoundExpression.hpp"
|
||||
|
||||
namespace Porygon::Binder {
|
||||
class BoundFunctionCallExpression : public Porygon::Binder::BoundExpression {
|
||||
const BoundExpression *_functionExpression;
|
||||
const vector<BoundExpression *> _parameters;
|
||||
const Porygon::GenericFunctionOption *_option;
|
||||
public:
|
||||
BoundFunctionCallExpression(BoundExpression *functionExpression, vector<BoundExpression *> parameters,
|
||||
Porygon::GenericFunctionOption *option, shared_ptr<Porygon::ScriptType> result,
|
||||
unsigned int start, unsigned int length)
|
||||
: BoundExpression(start, length, move(result)), _functionExpression(functionExpression),
|
||||
_parameters(move(parameters)), _option(option) {}
|
||||
|
||||
~BoundFunctionCallExpression() final {
|
||||
delete _functionExpression;
|
||||
for (auto p : _parameters) {
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
|
||||
const Porygon::Binder::BoundExpressionKind GetKind() const final {
|
||||
return Porygon::Binder::BoundExpressionKind::FunctionCall;
|
||||
}
|
||||
|
||||
const BoundExpression *GetFunctionExpression() const {
|
||||
return _functionExpression;
|
||||
}
|
||||
|
||||
const vector<BoundExpression *> *GetParameters() const {
|
||||
return &_parameters;
|
||||
}
|
||||
|
||||
const Porygon::GenericFunctionOption *GetFunctionOption() const {
|
||||
return _option;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#include "BoundExpression.hpp"
|
||||
|
||||
#endif //PORYGONLANG_BOUNDFUNCTIONCALLEXPRESSION_HPP
|
||||
@@ -1,19 +1,18 @@
|
||||
#include <utility>
|
||||
|
||||
|
||||
#ifndef PORYGONLANG_BOUNDFUNCTIONDECLARATIONSTATEMENT_HPP
|
||||
#define PORYGONLANG_BOUNDFUNCTIONDECLARATIONSTATEMENT_HPP
|
||||
|
||||
#include <memory>
|
||||
#include "BoundStatement.hpp"
|
||||
#include "../../FunctionScriptType.hpp"
|
||||
|
||||
namespace Porygon::Binder {
|
||||
class BoundFunctionDeclarationStatement : public BoundStatement {
|
||||
const BoundVariableKey *_key;
|
||||
const std::shared_ptr<BoundBlockStatement> _block;
|
||||
const std::shared_ptr<FunctionScriptType> _type;
|
||||
const std::shared_ptr<GenericFunctionScriptType> _type;
|
||||
public:
|
||||
BoundFunctionDeclarationStatement(std::shared_ptr<FunctionScriptType> type, BoundVariableKey *key,
|
||||
BoundFunctionDeclarationStatement(std::shared_ptr<GenericFunctionScriptType> type, BoundVariableKey *key,
|
||||
BoundBlockStatement *block)
|
||||
: _key(key), _block(block), _type(std::move(type)) {
|
||||
}
|
||||
@@ -34,12 +33,10 @@ namespace Porygon::Binder {
|
||||
return _block;
|
||||
}
|
||||
|
||||
const std::shared_ptr<FunctionScriptType> GetType() const {
|
||||
const std::shared_ptr<GenericFunctionScriptType> GetType() const {
|
||||
return _type;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#include "BoundStatement.hpp"
|
||||
|
||||
#endif //PORYGONLANG_BOUNDFUNCTIONDECLARATIONSTATEMENT_HPP
|
||||
|
||||
Reference in New Issue
Block a user