diff --git a/std/n8std/Reflect.cc b/std/n8std/Reflect.cc index 1c73f67..b3bf9c2 100644 --- a/std/n8std/Reflect.cc +++ b/std/n8std/Reflect.cc @@ -18,8 +18,13 @@ #include "n8std/Reflect.hpp" +#include #include +#include +#include +#include #include +#include N8_FUNC(reflect_get) { if(args.size() != 1) @@ -135,3 +140,118 @@ N8_FUNC(reflect_invoke) { *params.getArray() ); } + +N8_FUNC(reflect_exec) { + if(args.size() != 1) + throw TerminativeThrowSignal( + std::move(address), + "Expecting 1 argument, got " + + std::to_string(args.size()) + ); + + DynamicObject source = args.at(0); + try { + Tokenizer tokenizer( + source.getString(), + "toString() + ">" + ); + tokenizer.scan(); + + Parser parser(tokenizer.getTokens()); + parser.parse(); + + DynamicObject value; + for(const auto& statement : parser.getGlobalStatements()) + value = statement->visit(symtab); + + symtab.detachParallelNodes(); + return value; + } + catch(const std::system_error& exc) { + symtab.waitForThreads(); + Runtime::cleanUp(); + + N8Util::printError("[\u001b[1;31mSystem Error\u001b[0m]: \u001b[3;37m"); + N8Util::printError(exc.what()); + N8Util::printError("\u001b[0m\r\n"); + } + catch(const ASTNodeException& nodeExc) { + symtab.waitForThreads(); + Runtime::cleanUp(); + + N8Util::printError("[\u001b[1;31mRuntime Error\u001b[0m]: \u001b[3;37m"); + N8Util::printError(nodeExc.what()); + N8Util::printError("\u001b[0m\r\n "); + N8Util::printError(nodeExc.getAddress()->toString()); + N8Util::printError("\r\n"); + } + catch(const LexicalAnalysisException& lexAnlExc) { + symtab.waitForThreads(); + Runtime::cleanUp(); + + N8Util::printError("[\u001b[1;31mLexical Error\u001b[0m]:\r\n\t"); + N8Util::printError(lexAnlExc.what()); + N8Util::printError("\r\n"); + } + catch(const ParserException& parserExc) { + symtab.waitForThreads(); + Runtime::cleanUp(); + + N8Util::printError("[\u001b[1;31mParser Error\u001b[0m]: \u001b[3;37m"); + N8Util::printError(parserExc.what()); + N8Util::printError("\u001b[0m\r\n "); + N8Util::printError(parserExc.getAddress()->toString()); + N8Util::printError("\r\n"); + } + catch(const TerminativeBreakSignal& breakExc) { + symtab.waitForThreads(); + Runtime::cleanUp(); + + N8Util::printError( + "[\u001b[1;31mRuntime Error\u001b[0m]: " + "\u001b[3;37mInvalid break statement signal caught.\u001b[0m" + "\r\n " + ); + N8Util::printError(breakExc.getAddress().toString()); + N8Util::printError("\r\n"); + } + catch(const TerminativeContinueSignal& continueExc) { + symtab.waitForThreads(); + Runtime::cleanUp(); + + N8Util::printError( + "[\u001b[1;31mRuntime Error\u001b[0m]: " + "\u001b[3;37mInvalid continue statement signal caught.\u001b[0m" + "\r\n " + ); + N8Util::printError(continueExc.getAddress().toString()); + N8Util::printError("\r\n"); + } + catch(const TerminativeReturnSignal& retExc) { + symtab.waitForThreads(); + Runtime::cleanUp(); + + return retExc.getObject(); + } + catch(const TerminativeThrowSignal& throwExc) { + symtab.waitForThreads(); + Runtime::cleanUp(); + + N8Util::printError("[\u001b[1;31mUncaught Error\u001b[0m]: \u001b[3;37m"); + N8Util::printError(throwExc.getObject().toString()); + N8Util::printError("\u001b[0m\r\n "); + N8Util::printError(throwExc.getAddress()->toString()); + N8Util::printError("\r\n"); + } + catch(const std::exception& exc) { + symtab.waitForThreads(); + Runtime::cleanUp(); + + N8Util::printError("[\u001b[1;31mRuntime Error\u001b[0m]: \u001b[3;37m"); + N8Util::printError(exc.what()); + N8Util::printError("\u001b[0m\r\n"); + } + + return DynamicObject(); +} diff --git a/std/n8std/Reflect.hpp b/std/n8std/Reflect.hpp index 1259567..dc2d125 100644 --- a/std/n8std/Reflect.hpp +++ b/std/n8std/Reflect.hpp @@ -36,6 +36,8 @@ N8_FUNC(reflect_declare); N8_FUNC(reflect_delete); N8_FUNC(reflect_invoke); +N8_FUNC(reflect_exec); + N8_LIB_END #ifdef __clang__