Initial support for require statements
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2019-08-10 16:45:15 +02:00
parent 2f912afe92
commit c39f3a0884
11 changed files with 202 additions and 15 deletions

View File

@@ -4,6 +4,7 @@
#include "../ScriptTypes/TableScriptType.hpp"
#include "BoundExpressions/BoundTableExpression.hpp"
#include "BoundExpressions/BoundFunctionCallExpression.hpp"
#include "BoundExpressions/BoundRequireExpression.hpp"
#include "../UserData/UserDataScriptType.hpp"
using namespace Porygon::Parser;
@@ -16,7 +17,7 @@ namespace Porygon::Binder {
binder._scope = scriptScope;
auto statements = s->GetStatements();
vector<const BoundStatement *> boundStatements(statements->size());
for (int i = 0; i < statements->size(); i++) {
for (size_t i = 0; i < statements->size(); i++) {
boundStatements[i] = binder.BindStatement(statements->at(i));
}
return new BoundScriptStatement(boundStatements, scriptScope->GetLocalVariableCount());
@@ -63,7 +64,7 @@ namespace Porygon::Binder {
auto statements = ((ParsedBlockStatement *) statement)->GetStatements();
vector<const BoundStatement *> boundStatements(statements->size());
this->_scope->GoInnerScope();
for (int i = 0; i < statements->size(); i++) {
for (size_t i = 0; i < statements->size(); i++) {
boundStatements[i] = this->BindStatement(statements->at(i));
}
this->_scope->GoOuterScope();
@@ -137,7 +138,7 @@ namespace Porygon::Binder {
auto parameterKeys = vector<shared_ptr<const BoundVariableKey>>(parameters->size());
this->_scope->GoInnerScope();
for (long i = 0; i < parameters->size(); i++) {
for (size_t i = 0; i < parameters->size(); i++) {
auto var = parameters->at(i);
auto parsedType = ParseTypeIdentifier(var->GetType());
if (parsedType == nullptr) {
@@ -567,7 +568,14 @@ namespace Porygon::Binder {
}
BoundExpression *Binder::BindFunctionCall(const FunctionCallExpression *expression) {
auto functionExpression = BindExpression(expression->GetFunction());
auto func = expression->GetFunction();
if (func->GetKind() == ParsedExpressionKind::Variable){
auto variable = dynamic_cast<const VariableExpression*>(func);
if (variable->GetValue().GetHash() == HashedString::ConstHash("require")){
return this->BindRequire(expression);
}
}
auto functionExpression = BindExpression(func);
auto type = functionExpression->GetType();
if (type->GetClass() != TypeClass::Function) {
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::ExpressionIsNotAFunction,
@@ -579,7 +587,7 @@ namespace Porygon::Binder {
auto givenParameters = expression->GetParameters();
auto givenParameterTypes = vector<shared_ptr<const ScriptType>>(givenParameters->size());
vector<BoundExpression *> boundParameters = vector<BoundExpression *>(givenParameters->size());
for (long i = 0; i < givenParameters->size(); i++){
for (size_t i = 0; i < givenParameters->size(); i++){
boundParameters[i] = this -> BindExpression(givenParameters->at(i));
givenParameterTypes[i] = boundParameters[i]->GetType();
}
@@ -596,6 +604,44 @@ namespace Porygon::Binder {
expression->GetStartPosition(), expression->GetLength());
}
BoundExpression *Binder::BindRequire(const FunctionCallExpression* exp){
auto parameters = exp->GetParameters();
if (parameters->size() != 1){
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidFunctionParameters,
exp->GetStartPosition(),
exp->GetLength());
return new BoundBadExpression(exp->GetStartPosition(), exp ->GetLength());
}
auto parameter = parameters->at(0);
auto boundParameter = this -> BindExpression(parameter);
if (boundParameter->GetKind() != BoundExpressionKind::LiteralString){
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidFunctionParameters,
exp->GetStartPosition(),
exp->GetLength());
return new BoundBadExpression(exp->GetStartPosition(), exp ->GetLength());
}
auto key = *dynamic_cast<BoundLiteralStringExpression*>(boundParameter)->GetValue();
auto opt = this->_scriptData->GetScriptOptions();
auto transformedKey = Utilities::StringUtils::FromUTF8(key);
delete boundParameter;
if (!opt->DoesModuleExist(transformedKey)){
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::ModuleDoesntExist,
exp->GetStartPosition(),
exp->GetLength());
return new BoundBadExpression(exp->GetStartPosition(), exp ->GetLength());
}
auto module = opt->ResolveModule(transformedKey);
if (module -> GetReturnType() == nullptr){
for (const auto& v: *module->GetScriptVariables()){
//TODO: Currently a hack, will always make all variables nil
auto type = make_shared<const ScriptType>(TypeClass::Nil);
this -> _scope -> AssignVariable(v.first, type);
}
}
return new BoundRequireExpression(module, exp->GetStartPosition(), exp ->GetLength());
}
BoundExpression *Binder::BindIndexExpression(const IndexExpression *expression, bool setter) {
auto indexer = this->BindExpression(expression->GetIndexer());
auto index = this->BindExpression(expression->GetIndex());
@@ -672,7 +718,7 @@ namespace Porygon::Binder {
if (!boundExpressions.empty()) {
boundExpressions[0] = this->BindExpression(expressions->at(0));
valueType = boundExpressions[0]->GetType();
for (long i = 1; i < expressions->size(); i++) {
for (size_t i = 1; i < expressions->size(); i++) {
boundExpressions[i] = this->BindExpression(expressions->at(i));
if (boundExpressions[i]->GetType().get()->operator!=(valueType.get())) {
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidTableValueType,