diff --git a/src/EvaluateResult.hpp b/src/EvaluateResult.hpp new file mode 100644 index 0000000..7de7447 --- /dev/null +++ b/src/EvaluateResult.hpp @@ -0,0 +1,51 @@ +#ifndef PORYGONLANG_EVALUATERESULT_HPP +#define PORYGONLANG_EVALUATERESULT_HPP + +#include +#include +#include +#include "Evaluator/EvalValues/EvalValue.hpp" + +namespace Porygon{ + struct EvaluateResult{ + const Evaluation::EvalValue* _value; + const u_int8_t _result; + char * _errorMessage; + const size_t _errorSize; + public: + explicit EvaluateResult(const Evaluation::EvalValue* value) + : _result(0), _value(value), _errorMessage(nullptr), _errorSize(0) + { + } + + ~EvaluateResult(){ + delete _value; + delete _errorMessage; + } + + explicit EvaluateResult(const std::string& error) + : _result(1), _value(nullptr), _errorSize(error.size()) + { + _errorMessage = new char[error.size()](); + std::strcpy(_errorMessage, error.c_str()); + } + + EvaluateResult& operator= (EvaluateResult b) = delete; + EvaluateResult(const EvaluateResult& b) = delete; + + + [[nodiscard]] const Evaluation::EvalValue* GetValue() const{ + return _value; + } + + [[nodiscard]] u_int8_t GetResult() const{ + return _result; + } + + [[nodiscard]] const char * GetError() const{ + return _errorMessage; + } + }; +} + +#endif //PORYGONLANG_EVALUATERESULT_HPP diff --git a/src/Script.cpp b/src/Script.cpp index 3b05707..0a16d56 100644 --- a/src/Script.cpp +++ b/src/Script.cpp @@ -7,6 +7,7 @@ #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); @@ -103,15 +104,19 @@ Porygon::Script::Script(shared_ptr boundScript, _evaluator = new Evaluator(_scriptVariables); } - extern "C" { Porygon::Script* CreateScript(char16_t * s){ return Porygon::Script::Create(s); } - const EvalValue* EvaluateScript(Porygon::Script* script){ - auto result = script -> Evaluate(); - return result.Clone(); + 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){ @@ -126,8 +131,18 @@ extern "C" { return script->HasFunction(key); } - const EvalValue* CallFunction(Porygon::Script* script, const char16_t* key, EvalValue* parameters[], int parameterCount){ - std::vector v(parameters, parameters + parameterCount); - return script->CallFunction(key, v); + 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(); } } \ No newline at end of file