#include #include #include #include #include #include #include #include "Script.hpp" #include "Parser/Lexer.hpp" #include "Parser/Parser.hpp" #include "Binder/Binder.hpp" Porygon::Script* Porygon::Script::Create(const u16string& script) { return new Script(script); } std::u16string To_UTF16(const string &s) { std::wstring_convert, char16_t> conv; return conv.from_bytes(s); } Porygon::Script *Porygon::Script::Create(const string &script) { return Script::Create(To_UTF16(script)); } Porygon::Script::Script(const u16string& s) { Diagnostics = make_shared(s); _boundScript = nullptr; _scriptVariables = new map>(); _evaluator = new Evaluator(this -> _scriptVariables); this -> Parse(s); } EvalValue* Porygon::Script::Evaluate() { return _evaluator->Evaluate(_boundScript.get()); } Porygon::Script::~Script() { delete this -> _evaluator; this->_scriptVariables->clear(); delete this->_scriptVariables; } void Porygon::Script::Parse(const u16string& script) { auto lexer = Lexer(script, this); auto lexResult = lexer.Lex(); auto parser = Parser::Parser(lexResult, this); auto parseResult = parser.Parse(); for (auto token : lexResult){ delete token; } lexResult.clear(); if (!Diagnostics->HasErrors()){ map scriptScope; auto bindScope = new BoundScope(&scriptScope); this->_boundScript = shared_ptr(Binder::Binder::Bind(this, parseResult, bindScope)); for (const auto& v : scriptScope){ this->_scriptVariables -> insert({v.first, nullptr}); delete v.second; } scriptScope.clear(); } delete parseResult; } EvalValue *Porygon::Script::GetVariable(const u16string &key) { return _scriptVariables -> at(HashedString::CreateLookup(key)).get(); } bool Porygon::Script::HasVariable(const u16string &key) { auto f = _scriptVariables->find(HashedString::CreateLookup(key)); return f != _scriptVariables->end(); } 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; } shared_ptr Porygon::Script::CallFunction(const u16string &key, const vector& variables) { auto var = (ScriptFunctionEvalValue*)GetVariable(key); return this->_evaluator->EvaluateFunction(var, variables); } Porygon::Script *Porygon::Script::Clone(const Porygon::Script *script) { auto s = new Script(script->_boundScript, script->Diagnostics); for (auto v: *script->_scriptVariables){ s->_scriptVariables->insert({v.first, nullptr}); } s->_returnType = script->_returnType; return s; } Porygon::Script::Script(shared_ptr boundScript, shared_ptr diagnostics) { _boundScript = std::move(boundScript); Diagnostics = std::move(diagnostics); _scriptVariables = new map>(); _evaluator = new Evaluator(_scriptVariables); } extern "C" { Porygon::Script* CreateScript(char16_t * s){ return Porygon::Script::Create(s); } void EvaluateScript(Porygon::Script* script){ script->Evaluate(); } EvalValue* GetLastValue(Porygon::Script* script){ return script->GetLastValue(); } bool HasVariable(Porygon::Script* script, const char16_t* key){ return script->HasVariable(key); } EvalValue* GetVariable(Porygon::Script* script, const char16_t* key){ return script->GetVariable(key); } bool HasFunction(Porygon::Script* script, const char16_t* key){ return script->HasFunction(key); } EvalValue* CallFunction(Porygon::Script* script, const char16_t* key, EvalValue* parameters[], int parameterCount){ std::vector v(parameters, parameters + parameterCount); return script->CallFunction(key, v).get(); } }