#include #include #include #include #include #include "Script.hpp" #include "Parser/Lexer.hpp" #include "Parser/Parser.hpp" #include "Binder/Binder.hpp" #include "EvaluateResult.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); } EvalValuePointer 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; } const EvalValue* Porygon::Script::GetVariable(const u16string &key) { return _scriptVariables -> at(HashedString::CreateLookup(key)).Clone(); } bool Porygon::Script::HasVariable(const u16string &key) { auto f = _scriptVariables->find(HashedString::CreateLookup(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; } const EvalValue* Porygon::Script::CallFunction(const u16string &key, const vector& variables) { auto var = (GenericFunctionEvalValue*)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); } Porygon::EvaluateResult* EvaluateScript(Porygon::Script* script){ try{ auto result = script -> Evaluate(); return new Porygon::EvaluateResult(result.Take()); } catch (const EvaluationException& e){ return new Porygon::EvaluateResult(e.what()); } } bool HasVariable(Porygon::Script* script, const char16_t* key){ return script->HasVariable(key); } const 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); } Porygon::EvaluateResult* CallFunction(Porygon::Script* script, const char16_t* key, EvalValue* parameters[], int parameterCount){ try{ std::vector v(parameters, parameters + parameterCount); auto result = script->CallFunction(key, v); return new Porygon::EvaluateResult(result); } catch (const EvaluationException& e){ return new Porygon::EvaluateResult(e.what()); } } const char * GetResultError(Porygon::EvaluateResult * result){ return result->GetError(); } }