Support for loading variables from module with require
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
c39f3a0884
commit
641b6784c7
|
@ -630,12 +630,12 @@ namespace Porygon::Binder {
|
|||
exp->GetLength());
|
||||
return new BoundBadExpression(exp->GetStartPosition(), exp ->GetLength());
|
||||
}
|
||||
auto module = opt->ResolveModule(transformedKey);
|
||||
auto module = Script::Clone(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);
|
||||
auto type = module->GetVariableType(v.first);
|
||||
auto result = this -> _scope -> AssignVariable(v.first, type);
|
||||
delete result.GetKey();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -737,7 +737,7 @@ namespace Porygon::Binder {
|
|||
|
||||
BoundExpression *Binder::BindTableExpression(const ParsedTableExpression *expression) {
|
||||
auto tableScope = new map<Utilities::HashedString, BoundVariable *>();
|
||||
auto innerScope = new BoundScope(tableScope);
|
||||
auto innerScope = new BoundScope(tableScope, nullptr);
|
||||
auto currentScope = this->_scope;
|
||||
this->_scope = innerScope;
|
||||
auto block = dynamic_cast<BoundBlockStatement*>(this->BindBlockStatement(expression->GetBlock()));
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
#include "../../StandardLibraries/StaticScope.hpp"
|
||||
|
||||
namespace Porygon::Binder {
|
||||
BoundScope::BoundScope(map<Utilities::HashedString, BoundVariable *> *tableScope) {
|
||||
BoundScope::BoundScope(map<Utilities::HashedString, BoundVariable *> *tableScope,
|
||||
unordered_map<Utilities::HashedString, shared_ptr<const ScriptType>>* tableVariableTypes) {
|
||||
_tableScope = tableScope;
|
||||
_tableVariableTypes = tableVariableTypes;
|
||||
_currentScope = 1;
|
||||
_lastCreatedScope = 1;
|
||||
auto localUpmostScope = new map<Utilities::HashedString, BoundVariable *>();
|
||||
|
@ -92,6 +94,9 @@ namespace Porygon::Binder {
|
|||
if (exists < 0) {
|
||||
// Creation
|
||||
_tableScope->insert({identifier, new BoundVariable(type)});
|
||||
if (_tableVariableTypes != nullptr){
|
||||
_tableVariableTypes->insert({identifier, type});
|
||||
}
|
||||
return VariableAssignment(VariableAssignmentResult::Ok, new BoundVariableKey(identifier, 0, true));
|
||||
} else {
|
||||
// Assigning
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "BoundVariable.hpp"
|
||||
|
@ -16,11 +17,13 @@ using namespace std;
|
|||
namespace Porygon::Binder {
|
||||
class BoundScope {
|
||||
map<Utilities::HashedString, BoundVariable *> *_tableScope;
|
||||
unordered_map<Utilities::HashedString, shared_ptr<const ScriptType>> * _tableVariableTypes;
|
||||
vector<map<Utilities::HashedString, BoundVariable *> *> _localScope;
|
||||
int _currentScope;
|
||||
int _lastCreatedScope;
|
||||
public:
|
||||
explicit BoundScope(map<Utilities::HashedString, BoundVariable *> *tableScope);
|
||||
explicit BoundScope(map<Utilities::HashedString, BoundVariable *> *tableScope,
|
||||
unordered_map<Utilities::HashedString, shared_ptr<const ScriptType>>* tableVariableTypes);
|
||||
|
||||
~BoundScope();
|
||||
|
||||
|
|
|
@ -402,13 +402,14 @@ namespace Porygon::Evaluation {
|
|||
|
||||
EvalValuePointer Evaluator::EvaluateRequireExpression(const BoundExpression* expression) {
|
||||
auto module = dynamic_cast<const BoundRequireExpression*>(expression)->GetModule();
|
||||
auto result = module->Evaluate();
|
||||
if (module ->GetReturnType() == nullptr){
|
||||
for (const auto& v: *module->GetScriptVariables()){
|
||||
this->_scriptVariables->insert({v.first, v.second.Clone()});
|
||||
this->_scriptVariables->at(v.first) = v.second.Clone();
|
||||
}
|
||||
return nullptr;
|
||||
} else{
|
||||
return module -> Evaluate().Take();
|
||||
return result.Take();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
#include "Script.hpp"
|
||||
|
@ -26,6 +25,7 @@ Porygon::Script::Script(const u16string& s)
|
|||
: Diagnostics(make_shared<Diagnostics::DiagnosticsHolder>(s)),
|
||||
_boundScript(nullptr),
|
||||
_scriptVariables(new map<Utilities::HashedString, EvalValuePointer>()),
|
||||
_scriptTypes(new unordered_map<Utilities::HashedString, shared_ptr<ScriptType>>{}),
|
||||
_scriptOptions(nullptr)
|
||||
{
|
||||
_evaluator = new Evaluator(this -> _scriptVariables, this -> GetScriptOptions());
|
||||
|
@ -40,6 +40,8 @@ Porygon::Script::~Script() {
|
|||
delete this -> _evaluator;
|
||||
this->_scriptVariables->clear();
|
||||
delete this->_scriptVariables;
|
||||
this->_scriptTypes->clear();
|
||||
delete this->_scriptTypes;
|
||||
}
|
||||
|
||||
void Porygon::Script::Parse(const u16string& script) {
|
||||
|
@ -53,13 +55,18 @@ void Porygon::Script::Parse(const u16string& script) {
|
|||
lexResult.clear();
|
||||
if (!Diagnostics->HasErrors()){
|
||||
map<Utilities::HashedString, BoundVariable*> scriptScope;
|
||||
auto bindScope = new BoundScope(&scriptScope);
|
||||
unordered_map<Utilities::HashedString, shared_ptr<const ScriptType>> variableTypes;
|
||||
auto bindScope = new BoundScope(&scriptScope, &variableTypes);
|
||||
this->_boundScript = shared_ptr<BoundScriptStatement>(Binder::Binder::Bind(this, parseResult, bindScope));
|
||||
for (const auto& v : scriptScope){
|
||||
this->_scriptVariables -> insert({v.first, nullptr});
|
||||
delete v.second;
|
||||
}
|
||||
for (const auto& v : variableTypes){
|
||||
this->_scriptTypes -> insert({v.first, nullptr});
|
||||
}
|
||||
scriptScope.clear();
|
||||
variableTypes.clear();
|
||||
}
|
||||
delete parseResult;
|
||||
}
|
||||
|
@ -73,10 +80,6 @@ bool Porygon::Script::HasVariable(const u16string &key) {
|
|||
return f != _scriptVariables->end();
|
||||
}
|
||||
|
||||
/*const EvalValue *Porygon::Script::GetLastValue() {
|
||||
return _evaluator->GetLastValue();
|
||||
}*/
|
||||
|
||||
bool Porygon::Script::HasFunction(const u16string &key) {
|
||||
auto f = _scriptVariables->find(HashedString::CreateLookup(key));
|
||||
return f != _scriptVariables->end() && f.operator->()->second->GetTypeClass() == TypeClass ::Function;
|
||||
|
@ -89,9 +92,13 @@ const EvalValue* Porygon::Script::CallFunction(const u16string &key, const vecto
|
|||
|
||||
Porygon::Script *Porygon::Script::Clone(const Porygon::Script *script) {
|
||||
auto s = new Script(script->_boundScript, script->Diagnostics);
|
||||
for (auto v: *script->_scriptVariables){
|
||||
for (const auto& v: *script->_scriptVariables){
|
||||
s->_scriptVariables->insert({v.first, nullptr});
|
||||
}
|
||||
for (const auto& v: *script->_scriptTypes){
|
||||
s->_scriptTypes->insert({v.first, v.second});
|
||||
}
|
||||
|
||||
s->_returnType = script->_returnType;
|
||||
return s;
|
||||
}
|
||||
|
@ -101,6 +108,7 @@ Porygon::Script::Script(shared_ptr<BoundScriptStatement> boundScript,
|
|||
: _boundScript(std::move(boundScript)),
|
||||
Diagnostics(std::move(diagnostics)),
|
||||
_scriptVariables(new map<Utilities::HashedString, EvalValuePointer>()),
|
||||
_scriptTypes(new unordered_map<Utilities::HashedString, shared_ptr<ScriptType>>{}),
|
||||
_scriptOptions(nullptr)
|
||||
{
|
||||
_evaluator = new Evaluator(_scriptVariables, this -> GetScriptOptions());
|
||||
|
|
|
@ -19,6 +19,7 @@ namespace Porygon{
|
|||
class Script {
|
||||
Evaluator* _evaluator;
|
||||
map<Utilities::HashedString, EvalValuePointer>* _scriptVariables;
|
||||
unordered_map<Utilities::HashedString, shared_ptr<ScriptType>>* _scriptTypes;
|
||||
shared_ptr<Binder::BoundScriptStatement> _boundScript;
|
||||
shared_ptr<const ScriptType> _returnType = nullptr;
|
||||
ScriptOptions* _scriptOptions;
|
||||
|
@ -54,6 +55,9 @@ namespace Porygon{
|
|||
|
||||
const EvalValue* GetVariable(const u16string& key);
|
||||
bool HasVariable(const u16string& key);
|
||||
shared_ptr<const ScriptType> GetVariableType(const Utilities::HashedString& key){
|
||||
return _scriptTypes->at(key);
|
||||
}
|
||||
|
||||
const EvalValue* CallFunction(const u16string& key, const vector<EvalValue*>& variables);
|
||||
bool HasFunction(const u16string& key);
|
||||
|
|
|
@ -63,9 +63,20 @@ namespace Porygon::Utilities{
|
|||
inline bool operator>(const HashedString& b) const{
|
||||
return _hash > b._hash;
|
||||
}
|
||||
|
||||
|
||||
std::size_t operator()(const HashedString& k) const {
|
||||
return _hash;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<Porygon::Utilities::HashedString> {
|
||||
std::size_t operator()(const Porygon::Utilities::HashedString& k) const{
|
||||
return k.GetHash();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif //PORYGONLANG_HASHEDSTRING_HPP
|
||||
|
|
|
@ -4,20 +4,32 @@
|
|||
using namespace Porygon;
|
||||
|
||||
class ModuleHandler{
|
||||
static unordered_map<string, Script*> MODULES;
|
||||
class Internal{
|
||||
public:
|
||||
unordered_map<string, Script*> MODULES;
|
||||
|
||||
~ModuleHandler(){
|
||||
for (auto v: MODULES){
|
||||
delete v.second;
|
||||
Internal(){
|
||||
MODULES = {
|
||||
{"simple_return", Script::Create(u"return 500")},
|
||||
{"simple_variables", Script::Create(u"foo = 50\nbar = \'test\'")}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
~Internal(){
|
||||
for (const auto& v: MODULES){
|
||||
delete v.second;
|
||||
}
|
||||
MODULES.clear();
|
||||
}
|
||||
};
|
||||
static Internal _internal;
|
||||
|
||||
inline static bool DoesModuleExist(const string& moduleName){
|
||||
return MODULES.find(moduleName) != MODULES.end();
|
||||
return _internal.MODULES.find(moduleName) != _internal.MODULES.end();
|
||||
}
|
||||
|
||||
inline static Script* ResolveModule(const string& moduleName){
|
||||
return MODULES[moduleName];
|
||||
return _internal.MODULES[moduleName];
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -27,9 +39,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
unordered_map<string, Script*> ModuleHandler::MODULES = unordered_map<string, Script*>{
|
||||
{"simple_return", Script::Create(u"return 500")}
|
||||
};
|
||||
ModuleHandler::Internal ModuleHandler::_internal;
|
||||
|
||||
TEST_CASE( "Require simple return script", "[integration]" ) {
|
||||
ModuleHandler::Initialize();
|
||||
|
@ -42,4 +52,23 @@ return require("simple_return")
|
|||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "Require simple variables script", "[integration]" ) {
|
||||
ModuleHandler::Initialize();
|
||||
auto script = Script::Create(uR"(
|
||||
require("simple_variables")
|
||||
)");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
REQUIRE(script->HasVariable(u"foo"));
|
||||
REQUIRE(script->HasVariable(u"bar"));
|
||||
auto foo = script->GetVariable(u"foo");
|
||||
auto bar = script->GetVariable(u"bar");
|
||||
CHECK(foo->EvaluateInteger() == 50);
|
||||
CHECK(bar->EvaluateString() == u"test");
|
||||
|
||||
delete foo;
|
||||
delete bar;
|
||||
delete script;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue