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:
@@ -4,24 +4,63 @@
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <unordered_map>
|
||||
#include "../../ScriptType.hpp"
|
||||
#include "EvalValue.hpp"
|
||||
#include "../../Binder/BoundStatements/BoundStatement.hpp"
|
||||
#include "../EvaluationScope/EvaluationScope.hpp"
|
||||
#include "../../FunctionScriptType.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Porygon::Evaluation {
|
||||
class GenericFunctionOption{
|
||||
public:
|
||||
virtual ~GenericFunctionOption() = default;
|
||||
};
|
||||
|
||||
class EvaluationScriptFunctionOption : public GenericFunctionOption{
|
||||
const std::shared_ptr<BoundBlockStatement> _innerBlock;
|
||||
const std::shared_ptr<EvaluationScope> _scope;
|
||||
|
||||
public:
|
||||
EvaluationScriptFunctionOption(const shared_ptr<BoundBlockStatement> innerBlock, const shared_ptr<EvaluationScope> scope)
|
||||
: _innerBlock(innerBlock), _scope(scope) {
|
||||
|
||||
}
|
||||
|
||||
const std::shared_ptr<BoundBlockStatement> &GetInnerBlock() const {
|
||||
return _innerBlock;
|
||||
}
|
||||
|
||||
const std::shared_ptr<EvaluationScope> &GetScope() const {
|
||||
return _scope;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
class GenericFunctionEvalValue : public EvalValue{
|
||||
protected:
|
||||
const std::shared_ptr<GenericFunctionScriptType> _type;
|
||||
const std::size_t _hash;
|
||||
|
||||
std::vector<shared_ptr<GenericFunctionOption>> _options;
|
||||
public:
|
||||
GenericFunctionEvalValue(shared_ptr<GenericFunctionScriptType> type, size_t hash)
|
||||
: _type(move(type)),
|
||||
_hash(hash){
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Clone() const final {
|
||||
auto t = make_shared<GenericFunctionEvalValue>(_type, _hash);
|
||||
for (const auto& o: _options){
|
||||
t->_options.push_back(o);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
void RegisterOption(GenericFunctionOption* option){
|
||||
_options.push_back(shared_ptr<GenericFunctionOption>(option));
|
||||
}
|
||||
|
||||
const std::shared_ptr<ScriptType> GetType() const {
|
||||
@@ -41,42 +80,9 @@ namespace Porygon::Evaluation {
|
||||
const std::size_t GetHashCode() const final {
|
||||
return _hash;
|
||||
}
|
||||
};
|
||||
|
||||
class ScriptFunctionEvalValue : public GenericFunctionEvalValue {
|
||||
const std::shared_ptr<BoundBlockStatement> _innerBlock;
|
||||
const std::shared_ptr<EvaluationScope> _scope;
|
||||
|
||||
explicit ScriptFunctionEvalValue(shared_ptr<BoundBlockStatement> innerBlock,
|
||||
shared_ptr<EvaluationScope> scope,
|
||||
shared_ptr<FunctionScriptType> type, size_t hash)
|
||||
: GenericFunctionEvalValue(move(type), hash),
|
||||
_innerBlock(std::move(innerBlock)),
|
||||
_scope(std::move(scope)){
|
||||
}
|
||||
|
||||
public:
|
||||
explicit ScriptFunctionEvalValue(std::shared_ptr<BoundBlockStatement> innerBlock,
|
||||
std::shared_ptr<EvaluationScope> scope,
|
||||
std::shared_ptr<FunctionScriptType> type)
|
||||
: GenericFunctionEvalValue(move(type), rand()),
|
||||
_innerBlock(std::move(innerBlock)),
|
||||
_scope(std::move(scope)){
|
||||
}
|
||||
|
||||
|
||||
const shared_ptr<EvalValue> Clone() const final {
|
||||
// We don't run make_shared here as it can't call private constructors
|
||||
return shared_ptr<ScriptFunctionEvalValue>(new ScriptFunctionEvalValue(_innerBlock, _scope,
|
||||
dynamic_pointer_cast<FunctionScriptType>(_type), _hash));
|
||||
}
|
||||
|
||||
const std::shared_ptr<BoundBlockStatement> &GetInnerBlock() const {
|
||||
return _innerBlock;
|
||||
}
|
||||
|
||||
const std::shared_ptr<EvaluationScope> &GetScope() const {
|
||||
return _scope;
|
||||
const shared_ptr<GenericFunctionOption> GetOption(const size_t id) const{
|
||||
return this->_options.at(id);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,10 +8,12 @@
|
||||
#include "EvalValues/ScriptFunctionEvalValue.hpp"
|
||||
#include "EvalValues/TableEvalValue.hpp"
|
||||
#include "../Binder/BoundExpressions/BoundTableExpression.hpp"
|
||||
#include "../Binder/BoundExpressions/BoundFunctionCallExpression.hpp"
|
||||
#include "../TableScriptType.hpp"
|
||||
#include "../UserData/UserDataFunction.hpp"
|
||||
#include "../Utilities/StringUtils.hpp"
|
||||
#include "EvalValues/NumericalTableEvalValue.hpp"
|
||||
#include "../FunctionScriptType.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Porygon::Binder;
|
||||
@@ -96,11 +98,16 @@ namespace Porygon::Evaluation {
|
||||
auto type = statement->GetType();
|
||||
auto key = statement->GetKey();
|
||||
auto block = statement->GetBlock();
|
||||
auto value = make_shared<ScriptFunctionEvalValue>(block, this->_evaluationScope, type);
|
||||
auto option = new Evaluation::EvaluationScriptFunctionOption(block, this->_evaluationScope);
|
||||
|
||||
if (key->IsCreation()) {
|
||||
auto value = make_shared<GenericFunctionEvalValue>(type, rand());
|
||||
value->RegisterOption(option);
|
||||
this->_evaluationScope->CreateVariable(key, value);
|
||||
} else {
|
||||
this->_evaluationScope->SetVariable(key, value);
|
||||
auto var = dynamic_pointer_cast<GenericFunctionEvalValue>(this -> _evaluationScope ->GetVariable(key));
|
||||
var->RegisterOption(option);
|
||||
this->_evaluationScope->SetVariable(key, var);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -370,20 +377,23 @@ namespace Porygon::Evaluation {
|
||||
}
|
||||
|
||||
auto type = std::dynamic_pointer_cast<GenericFunctionScriptType>(function->GetType());
|
||||
if (type -> IsScriptFunction()){
|
||||
auto parameterTypes = type->GetParameterTypes();
|
||||
auto scriptFunctionType = std::dynamic_pointer_cast<FunctionScriptType>(type);
|
||||
auto func = dynamic_pointer_cast<GenericFunctionEvalValue>(function);
|
||||
auto option = functionCall ->GetFunctionOption();
|
||||
auto opt = func->GetOption(option->GetOptionId());
|
||||
if (option -> IsScriptFunction()){
|
||||
auto parameterTypes = option->GetParameterTypes();
|
||||
auto scriptFunctionType = (ScriptFunctionOption*)option;
|
||||
auto parameterKeys = scriptFunctionType->GetParameterKeys();
|
||||
auto originalScope = this->_evaluationScope;
|
||||
auto scriptFunction = dynamic_pointer_cast<ScriptFunctionEvalValue>(function);
|
||||
this->_evaluationScope = scriptFunction->GetScope();
|
||||
auto scriptOption = dynamic_pointer_cast<EvaluationScriptFunctionOption>(opt);
|
||||
this->_evaluationScope = scriptOption->GetScope();
|
||||
|
||||
for (int i = 0; i < parameterTypes.size() && i < parameterKeys.size() && i < parameters.size(); i++) {
|
||||
auto parameter = parameters[i];
|
||||
auto key = parameterKeys.at(i);
|
||||
this->_evaluationScope->CreateVariable(key.get(), parameter->Clone());
|
||||
}
|
||||
this->EvaluateBlockStatement(scriptFunction->GetInnerBlock().get());
|
||||
this->EvaluateBlockStatement(scriptOption->GetInnerBlock().get());
|
||||
this->_evaluationScope = originalScope;
|
||||
|
||||
this->_hasReturned = false;
|
||||
@@ -391,30 +401,33 @@ namespace Porygon::Evaluation {
|
||||
this->_returnValue = nullptr;
|
||||
return r;
|
||||
} else{
|
||||
auto userDataFunction = dynamic_pointer_cast<UserData::UserDataFunction>(function);
|
||||
auto scriptOption = dynamic_pointer_cast<UserData::UserDataFunction>(opt);
|
||||
EvalValue* arr[parameters.size()];
|
||||
for (int i = 0; i < parameters.size(); i++){
|
||||
arr[i] = parameters[i].get();
|
||||
}
|
||||
return shared_ptr<EvalValue>(userDataFunction -> Call(arr, parameters.size()));
|
||||
return shared_ptr<EvalValue>(scriptOption -> Call(arr, parameters.size()));
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateFunction(const ScriptFunctionEvalValue *function,
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateFunction(const GenericFunctionEvalValue *function,
|
||||
const vector<EvalValue *> ¶meters) {
|
||||
auto type = std::dynamic_pointer_cast<FunctionScriptType>(function->GetType());
|
||||
auto parameterTypes = type->GetParameterTypes();
|
||||
auto parameterKeys = type->GetParameterKeys();
|
||||
auto type = std::dynamic_pointer_cast<GenericFunctionScriptType>(function->GetType());
|
||||
auto option = (ScriptFunctionOption*)type-> GetFirstOption();
|
||||
|
||||
auto parameterTypes = option->GetParameterTypes();
|
||||
auto parameterKeys = option->GetParameterKeys();
|
||||
|
||||
auto originalScope = this->_evaluationScope;
|
||||
this->_evaluationScope = function->GetScope();
|
||||
auto scriptOption = dynamic_pointer_cast<EvaluationScriptFunctionOption>(function->GetOption(0));
|
||||
this->_evaluationScope = scriptOption->GetScope();
|
||||
|
||||
for (int i = 0; i < parameterTypes.size() && i < parameterKeys.size() && i < parameters.size(); i++) {
|
||||
auto parameter = parameters[i];
|
||||
auto key = parameterKeys.at(i);
|
||||
this->_evaluationScope->CreateVariable(key.get(), parameter->Clone());
|
||||
}
|
||||
this->EvaluateBlockStatement(function->GetInnerBlock().get());
|
||||
this->EvaluateBlockStatement(scriptOption->GetInnerBlock().get());
|
||||
this->_evaluationScope = originalScope;
|
||||
this->_hasReturned = false;
|
||||
auto r = this->_returnValue;
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace Porygon::Evaluation{
|
||||
}
|
||||
|
||||
EvalValue* Evaluate(const BoundScriptStatement* statement);
|
||||
const shared_ptr<EvalValue> EvaluateFunction(const ScriptFunctionEvalValue *function,
|
||||
const shared_ptr<EvalValue> EvaluateFunction(const GenericFunctionEvalValue *function,
|
||||
const vector<EvalValue *> ¶meters);
|
||||
|
||||
EvalValue* GetLastValue(){
|
||||
|
||||
Reference in New Issue
Block a user