From 12931363438ed298d7369b67f771706197532af2 Mon Sep 17 00:00:00 2001 From: Ilusha <63184036+IlyaShurupov@users.noreply.github.com> Date: Thu, 7 Mar 2024 12:33:46 +0300 Subject: [PATCH] Replace object parser with lalr library --- Objects/CMakeLists.txt | 8 +- Objects/private/compiler/function.cpp | 8 +- Objects/private/core/module.cpp | 5 +- Objects/private/parser/oscript.cpp | 332 +++++++ Objects/private/parser/oscript.g | 33 + Objects/private/parser/parser.cpp | 897 ++---------------- Objects/public/compiler/expression.h | 3 +- Objects/public/parser/parser.h | 186 +--- Objects/tests/{core => }/TestCore.cpp | 0 .../{interpreter => }/TestInterpreter.cpp | 0 Objects/tests/TestParser.cpp | 16 + .../tests/{primitives => }/TestPrimitives.cpp | 0 Objects/tests/Tests.cpp | 6 + 13 files changed, 499 insertions(+), 995 deletions(-) create mode 100644 Objects/private/parser/oscript.cpp create mode 100644 Objects/private/parser/oscript.g rename Objects/tests/{core => }/TestCore.cpp (100%) rename Objects/tests/{interpreter => }/TestInterpreter.cpp (100%) create mode 100644 Objects/tests/TestParser.cpp rename Objects/tests/{primitives => }/TestPrimitives.cpp (100%) diff --git a/Objects/CMakeLists.txt b/Objects/CMakeLists.txt index 6c2f4d9..f6a6568 100644 --- a/Objects/CMakeLists.txt +++ b/Objects/CMakeLists.txt @@ -1,13 +1,17 @@ project(Objects) +### ---------------------- Externals --------------------- ### +set(BINDINGS_INCLUDE ../Externals/lalr/src) +# set(BINDINGS_LIBS ) + ### ---------------------- Static Library --------------------- ### file(GLOB SOURCES "./private/*.cpp" "./private/*/*.cpp") file(GLOB HEADERS "./public/*.hpp" "./public/*/*.hpp" "./applications/*.hpp") add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS}) -target_include_directories(${PROJECT_NAME} PUBLIC ./public/) -target_link_libraries(${PROJECT_NAME} PUBLIC Strings Math Tokenizer CommandLine Connection) +target_include_directories(${PROJECT_NAME} PUBLIC ./public/ ${BINDINGS_INCLUDE}) +target_link_libraries(${PROJECT_NAME} PUBLIC Strings Math Connection) ### -------------------------- Applications -------------------------- ### #add_executable(osc ./applications/Compiler.cpp) diff --git a/Objects/private/compiler/function.cpp b/Objects/private/compiler/function.cpp index 9e5a6a6..037345a 100644 --- a/Objects/private/compiler/function.cpp +++ b/Objects/private/compiler/function.cpp @@ -164,7 +164,9 @@ void FunctionDefinition::EvalStatement(Statement* stm) { // compile function for (auto child_stm : stm_class_def->mScope->mStatements) { // check for return statements - ASSERT(child_stm.data()->mType != Statement::Type::RET && "return statements are not allowed in class definition"); + ASSERT( + child_stm.data()->mType != Statement::Type::RET && "return statements are not allowed in class definition" + ); func.EvalStatement(child_stm.data()); } // create one last instruction - constructing class from function execution state @@ -580,8 +582,8 @@ bool obj::BCgen::Compile(obj::MethodObject* method) { if (res.err) { // TODO : print parse error - auto loc = res.err->get_err_location(script.read()); - printf("Parser Error (%i,%i): %s\n", loc.head, loc.tail, res.err->mDescr.read()); + auto loc = res.err->getErrorLocation(script.read()); + printf("Parser Error (%i,%i): %s\n", loc.head, loc.tail, res.err->mDescription.read()); // tp::gLogeer->write(tp::sfmt("Parser Error (%i,%i): \n", loc.head, loc.tail), true, tp::Logger::LogEntry::ERR); // tp::GLog->write(res.err->mDescr, true, tp::Logger::LogEntry::ERR); return false; diff --git a/Objects/private/core/module.cpp b/Objects/private/core/module.cpp index 70d6dc1..464f4c5 100644 --- a/Objects/private/core/module.cpp +++ b/Objects/private/core/module.cpp @@ -1,6 +1,4 @@ -#include "Tokenizer.hpp" - #include "compiler/function.h" #include "primitives/boolobject.h" @@ -81,9 +79,8 @@ static tp::ModuleManifest* sModuleDependencies[] = { // &tp::gModuleCompressor, &tp::gModuleMath, &tp::gModuleStrings, - &tp::gModuleTokenizer, &tp::gModuleConnection, - NULL + nullptr }; tp::ModuleManifest obj::gModuleObjects = tp::ModuleManifest("Objects", init, deinit, sModuleDependencies); diff --git a/Objects/private/parser/oscript.cpp b/Objects/private/parser/oscript.cpp new file mode 100644 index 0000000..47d5af7 --- /dev/null +++ b/Objects/private/parser/oscript.cpp @@ -0,0 +1,332 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + +using namespace lalr; + +extern const LexerAction lexer_actions []; +extern const LexerTransition lexer_transitions []; +extern const LexerState lexer_states []; +extern const LexerAction whitespace_lexer_actions []; +extern const LexerTransition whitespace_lexer_transitions []; +extern const LexerState whitespace_lexer_states []; +extern const ParserAction actions []; +extern const ParserSymbol symbols []; +extern const ParserTransition transitions []; +extern const ParserState states []; + +const ParserAction actions [] = +{ + {0, "scope"}, + {1, "stm_scope_append"}, + {2, "stm_scope_create"}, + {3, "tmp"}, + {4, "stm_defVar"}, + {5, "stm_log"}, + {6, "expr_bool"}, + {7, "expr_int"}, + {8, "expr_float"}, + {9, "expr_string"}, + {-1, nullptr} +}; + +const ParserSymbol symbols [] = +{ + {0, (SymbolType) 2, "dot_start", ".start", "dot_start"}, + {1, (SymbolType) 3, "dot_end", ".end", "dot_end"}, + {2, (SymbolType) 1, "error", "error", "error"}, + {3, (SymbolType) 1, "dot_whitespace", ".whitespace", "dot_whitespace"}, + {4, (SymbolType) 2, "scope", "scope", "scope"}, + {5, (SymbolType) 1, "left_curly_brace_terminal", "{", "{"}, + {6, (SymbolType) 2, "statements", "statements", "statements"}, + {7, (SymbolType) 1, "right_curly_brace_terminal", "}", "}"}, + {8, (SymbolType) 1, "semi_colon_terminal", ";", ";"}, + {9, (SymbolType) 2, "statement", "statement", "statement"}, + {10, (SymbolType) 2, "statementVar", "statementVar", "statementVar"}, + {11, (SymbolType) 2, "statementLog", "statementLog", "statementLog"}, + {12, (SymbolType) 1, "var_terminal", "var", "var"}, + {13, (SymbolType) 1, "print_terminal", "print", "print"}, + {14, (SymbolType) 2, "value", "value", "value"}, + {15, (SymbolType) 1, "id", "[a-z]", "id"}, + {16, (SymbolType) 1, "boolean", "true|false", "boolean"}, + {17, (SymbolType) 1, "integer", "(\\+|\\-)?[0-9]+", "integer"}, + {18, (SymbolType) 1, "real", "(\\+|\\-)?[0-9]+(\\.[0-9]+)?((e|E)(\\+|\\-)?[0-9]+)?", "real"}, + {19, (SymbolType) 1, "string", "[\\\"']:string:", "string"}, + {-1, (SymbolType) 0, nullptr, nullptr, nullptr} +}; + +const ParserTransition transitions [] = +{ + {&symbols[4], &states[1], nullptr, 0, 0, 0, 0}, + {&symbols[5], &states[2], nullptr, 0, 0, 0, 1}, + {&symbols[1], nullptr, &symbols[4], 0, 0, -1, 2}, + {&symbols[1], nullptr, &symbols[0], 1, 0, -1, 3}, + {&symbols[6], &states[3], nullptr, 0, 0, 0, 4}, + {&symbols[9], &states[8], nullptr, 0, 0, 0, 5}, + {&symbols[10], &states[9], nullptr, 0, 0, 0, 6}, + {&symbols[11], &states[10], nullptr, 0, 0, 0, 7}, + {&symbols[12], &states[11], nullptr, 0, 0, 0, 8}, + {&symbols[13], &states[13], nullptr, 0, 0, 0, 9}, + {&symbols[7], nullptr, &symbols[6], 0, 0, -1, 10}, + {&symbols[8], nullptr, &symbols[6], 0, 0, -1, 11}, + {&symbols[7], &states[4], nullptr, 0, 0, 0, 12}, + {&symbols[8], &states[5], nullptr, 0, 0, 0, 13}, + {&symbols[1], nullptr, &symbols[4], 3, 0, 0, 14}, + {&symbols[9], &states[6], nullptr, 0, 0, 0, 15}, + {&symbols[10], &states[9], nullptr, 0, 0, 0, 16}, + {&symbols[11], &states[10], nullptr, 0, 0, 0, 17}, + {&symbols[12], &states[11], nullptr, 0, 0, 0, 18}, + {&symbols[13], &states[13], nullptr, 0, 0, 0, 19}, + {&symbols[8], &states[7], nullptr, 0, 0, 0, 20}, + {&symbols[7], nullptr, &symbols[6], 4, 0, 1, 21}, + {&symbols[8], nullptr, &symbols[6], 4, 0, 1, 22}, + {&symbols[7], nullptr, &symbols[6], 1, 0, 2, 23}, + {&symbols[8], nullptr, &symbols[6], 1, 0, 2, 24}, + {&symbols[7], nullptr, &symbols[9], 1, 0, 3, 25}, + {&symbols[8], nullptr, &symbols[9], 1, 0, 3, 26}, + {&symbols[7], nullptr, &symbols[9], 1, 0, 3, 27}, + {&symbols[8], nullptr, &symbols[9], 1, 0, 3, 28}, + {&symbols[15], &states[12], nullptr, 0, 0, 0, 29}, + {&symbols[7], nullptr, &symbols[10], 2, 0, 4, 30}, + {&symbols[8], nullptr, &symbols[10], 2, 0, 4, 31}, + {&symbols[14], &states[14], nullptr, 0, 0, 0, 32}, + {&symbols[16], &states[15], nullptr, 0, 0, 0, 33}, + {&symbols[17], &states[16], nullptr, 0, 0, 0, 34}, + {&symbols[18], &states[17], nullptr, 0, 0, 0, 35}, + {&symbols[19], &states[18], nullptr, 0, 0, 0, 36}, + {&symbols[7], nullptr, &symbols[14], 0, 0, -1, 37}, + {&symbols[8], nullptr, &symbols[14], 0, 0, -1, 38}, + {&symbols[7], nullptr, &symbols[11], 2, 0, 5, 39}, + {&symbols[8], nullptr, &symbols[11], 2, 0, 5, 40}, + {&symbols[7], nullptr, &symbols[14], 1, 0, 6, 41}, + {&symbols[8], nullptr, &symbols[14], 1, 0, 6, 42}, + {&symbols[7], nullptr, &symbols[14], 1, 0, 7, 43}, + {&symbols[8], nullptr, &symbols[14], 1, 0, 7, 44}, + {&symbols[7], nullptr, &symbols[14], 1, 0, 8, 45}, + {&symbols[8], nullptr, &symbols[14], 1, 0, 8, 46}, + {&symbols[7], nullptr, &symbols[14], 1, 0, 9, 47}, + {&symbols[8], nullptr, &symbols[14], 1, 0, 9, 48}, + {nullptr, nullptr, nullptr, 0, 0, 0, -1} +}; + +const ParserState states [] = +{ + {0, 3, &transitions[0], "(null)"}, + {1, 1, &transitions[3], "(null)"}, + {2, 8, &transitions[4], "(null)"}, + {3, 2, &transitions[12], "(null)"}, + {4, 1, &transitions[14], "(null)"}, + {5, 5, &transitions[15], "(null)"}, + {6, 1, &transitions[20], "(null)"}, + {7, 2, &transitions[21], "(null)"}, + {8, 2, &transitions[23], "(null)"}, + {9, 2, &transitions[25], "(null)"}, + {10, 2, &transitions[27], "(null)"}, + {11, 1, &transitions[29], "(null)"}, + {12, 2, &transitions[30], "(null)"}, + {13, 7, &transitions[32], "(null)"}, + {14, 2, &transitions[39], "(null)"}, + {15, 2, &transitions[41], "(null)"}, + {16, 2, &transitions[43], "(null)"}, + {17, 2, &transitions[45], "(null)"}, + {18, 2, &transitions[47], "(null)"}, + {-1, 0, nullptr} +}; + +const LexerAction lexer_actions [] = +{ + {0, "string"}, + {-1, nullptr} +}; + +const LexerTransition lexer_transitions [] = +{ + {34, 35, &lexer_states[45], nullptr}, + {39, 40, &lexer_states[45], nullptr}, + {43, 44, &lexer_states[38], nullptr}, + {45, 46, &lexer_states[38], nullptr}, + {46, 47, &lexer_states[6], nullptr}, + {48, 58, &lexer_states[37], nullptr}, + {59, 60, &lexer_states[19], nullptr}, + {97, 101, &lexer_states[28], nullptr}, + {101, 102, &lexer_states[1], nullptr}, + {102, 103, &lexer_states[30], nullptr}, + {103, 112, &lexer_states[28], nullptr}, + {112, 113, &lexer_states[23], nullptr}, + {113, 116, &lexer_states[28], nullptr}, + {116, 117, &lexer_states[29], nullptr}, + {117, 118, &lexer_states[28], nullptr}, + {118, 119, &lexer_states[20], nullptr}, + {119, 123, &lexer_states[28], nullptr}, + {123, 124, &lexer_states[17], nullptr}, + {125, 126, &lexer_states[18], nullptr}, + {114, 115, &lexer_states[2], nullptr}, + {114, 115, &lexer_states[3], nullptr}, + {111, 112, &lexer_states[4], nullptr}, + {114, 115, &lexer_states[5], nullptr}, + {119, 120, &lexer_states[7], nullptr}, + {104, 105, &lexer_states[8], nullptr}, + {105, 106, &lexer_states[9], nullptr}, + {116, 117, &lexer_states[10], nullptr}, + {101, 102, &lexer_states[11], nullptr}, + {115, 116, &lexer_states[12], nullptr}, + {112, 113, &lexer_states[13], nullptr}, + {97, 98, &lexer_states[14], nullptr}, + {99, 100, &lexer_states[15], nullptr}, + {101, 102, &lexer_states[16], nullptr}, + {97, 98, &lexer_states[21], nullptr}, + {114, 115, &lexer_states[22], nullptr}, + {114, 115, &lexer_states[24], nullptr}, + {105, 106, &lexer_states[25], nullptr}, + {110, 111, &lexer_states[26], nullptr}, + {116, 117, &lexer_states[27], nullptr}, + {114, 115, &lexer_states[31], nullptr}, + {97, 98, &lexer_states[33], nullptr}, + {117, 118, &lexer_states[32], nullptr}, + {101, 102, &lexer_states[36], nullptr}, + {108, 109, &lexer_states[34], nullptr}, + {115, 116, &lexer_states[35], nullptr}, + {101, 102, &lexer_states[36], nullptr}, + {46, 47, &lexer_states[39], nullptr}, + {48, 58, &lexer_states[37], nullptr}, + {69, 70, &lexer_states[41], nullptr}, + {101, 102, &lexer_states[41], nullptr}, + {48, 58, &lexer_states[37], nullptr}, + {48, 58, &lexer_states[40], nullptr}, + {48, 58, &lexer_states[40], nullptr}, + {69, 70, &lexer_states[41], nullptr}, + {101, 102, &lexer_states[41], nullptr}, + {43, 44, &lexer_states[42], nullptr}, + {45, 46, &lexer_states[42], nullptr}, + {48, 58, &lexer_states[43], nullptr}, + {48, 58, &lexer_states[43], nullptr}, + {48, 58, &lexer_states[43], nullptr}, + {0, 2147483647, &lexer_states[44], &lexer_actions[0]}, + {-1, -1, nullptr, nullptr} +}; + +const LexerState lexer_states [] = +{ + {0, 19, &lexer_transitions[0], nullptr}, + {1, 1, &lexer_transitions[19], &symbols[15]}, + {2, 1, &lexer_transitions[20], nullptr}, + {3, 1, &lexer_transitions[21], nullptr}, + {4, 1, &lexer_transitions[22], nullptr}, + {5, 0, &lexer_transitions[23], &symbols[2]}, + {6, 1, &lexer_transitions[23], nullptr}, + {7, 1, &lexer_transitions[24], nullptr}, + {8, 1, &lexer_transitions[25], nullptr}, + {9, 1, &lexer_transitions[26], nullptr}, + {10, 1, &lexer_transitions[27], nullptr}, + {11, 1, &lexer_transitions[28], nullptr}, + {12, 1, &lexer_transitions[29], nullptr}, + {13, 1, &lexer_transitions[30], nullptr}, + {14, 1, &lexer_transitions[31], nullptr}, + {15, 1, &lexer_transitions[32], nullptr}, + {16, 0, &lexer_transitions[33], &symbols[3]}, + {17, 0, &lexer_transitions[33], &symbols[5]}, + {18, 0, &lexer_transitions[33], &symbols[7]}, + {19, 0, &lexer_transitions[33], &symbols[8]}, + {20, 1, &lexer_transitions[33], &symbols[15]}, + {21, 1, &lexer_transitions[34], nullptr}, + {22, 0, &lexer_transitions[35], &symbols[12]}, + {23, 1, &lexer_transitions[35], &symbols[15]}, + {24, 1, &lexer_transitions[36], nullptr}, + {25, 1, &lexer_transitions[37], nullptr}, + {26, 1, &lexer_transitions[38], nullptr}, + {27, 0, &lexer_transitions[39], &symbols[13]}, + {28, 0, &lexer_transitions[39], &symbols[15]}, + {29, 1, &lexer_transitions[39], &symbols[15]}, + {30, 1, &lexer_transitions[40], &symbols[15]}, + {31, 1, &lexer_transitions[41], nullptr}, + {32, 1, &lexer_transitions[42], nullptr}, + {33, 1, &lexer_transitions[43], nullptr}, + {34, 1, &lexer_transitions[44], nullptr}, + {35, 1, &lexer_transitions[45], nullptr}, + {36, 0, &lexer_transitions[46], &symbols[16]}, + {37, 4, &lexer_transitions[46], &symbols[17]}, + {38, 1, &lexer_transitions[50], nullptr}, + {39, 1, &lexer_transitions[51], nullptr}, + {40, 3, &lexer_transitions[52], &symbols[18]}, + {41, 3, &lexer_transitions[55], nullptr}, + {42, 1, &lexer_transitions[58], nullptr}, + {43, 1, &lexer_transitions[59], &symbols[18]}, + {44, 0, &lexer_transitions[60], &symbols[19]}, + {45, 1, &lexer_transitions[60], nullptr}, + {-1, 0, nullptr, nullptr} +}; + +const LexerStateMachine lexer_state_machine = +{ + 1, // #actions + 61, // #transitions + 46, // #states + lexer_actions, // actions + lexer_transitions, // transitions + lexer_states, // states + &lexer_states[0] // start state +}; + +const LexerAction whitespace_lexer_actions [] = +{ + {-1, nullptr} +}; + +const LexerTransition whitespace_lexer_transitions [] = +{ + {9, 11, &whitespace_lexer_states[0], nullptr}, + {13, 14, &whitespace_lexer_states[0], nullptr}, + {32, 33, &whitespace_lexer_states[0], nullptr}, + {-1, -1, nullptr, nullptr} +}; + +const LexerState whitespace_lexer_states [] = +{ + {0, 3, &whitespace_lexer_transitions[0], &symbols[3]}, + {-1, 0, nullptr, nullptr} +}; + +const LexerStateMachine whitespace_lexer_state_machine = +{ + 0, // #actions + 3, // #transitions + 1, // #states + whitespace_lexer_actions, // actions + whitespace_lexer_transitions, // transitions + whitespace_lexer_states, // states + &whitespace_lexer_states[0] // start state +}; + +const ParserStateMachine parser_state_machine = +{ + "oscript", + 10, // #actions + 20, // #symbols + 49, // #transitions + 19, // #states + actions, + symbols, + transitions, + states, + &symbols[0], // start symbol + &symbols[1], // end symbol + &symbols[2], // error symbol + &symbols[3], // whitespace symbol + &states[0], // start state + &lexer_state_machine, // lexer state machine + &whitespace_lexer_state_machine // whitespace lexer state machine +}; + +} + +const lalr::ParserStateMachine* oscript_parser_state_machine = &parser_state_machine; diff --git a/Objects/private/parser/oscript.g b/Objects/private/parser/oscript.g new file mode 100644 index 0000000..31fcc94 --- /dev/null +++ b/Objects/private/parser/oscript.g @@ -0,0 +1,33 @@ +oscript { + %whitespace "[ \t\r\n]*"; + + scope: + '{' statements '}' [scope] + | ; + + statements: + statements ';' statement ';' [stm_scope_append] + | statement [stm_scope_create] + | ; + + statement: + statementVar [tmp] + | statementLog [tmp]; + + statementVar: 'var' id [stm_defVar]; + statementLog: 'print' value [stm_log]; + + value: + boolean [expr_bool] + | integer [expr_int] + | real [expr_float] + | string [expr_string] + | + ; + + id: "[a-z]"; + boolean: "true|false"; + integer: "(\+|\-)?[0-9]+"; + real: "(\+|\-)?[0-9]+(\.[0-9]+)?((e|E)(\+|\-)?[0-9]+)?"; + string: "[\"']:string:"; +} diff --git a/Objects/private/parser/parser.cpp b/Objects/private/parser/parser.cpp index 3ce2330..6b2c1df 100644 --- a/Objects/private/parser/parser.cpp +++ b/Objects/private/parser/parser.cpp @@ -1,840 +1,105 @@ -#include "List.hpp" -#include "Logging.hpp" -#include "compiler/function.h" -#include "parser/parser.h" +#include -#include +// #include "compiler/function.h" -#define MAX_STREAM_LENGTH 1024 * 8 * 200 +#include +#include -#define REQUIRE(expr, desc, on_catch) \ - DEBUG_BREAK(mRes.err); \ - if (!(expr)) { \ - mRes.err = new Error(desc, mTok.getCursorPrev().mAdvancedOffset); \ - on_catch; \ - return NULL; \ - } -#define CHECK(expr, on_catch) \ - if (!(expr)) { \ - on_catch; \ - return NULL; \ - } -#define CHECK_ERROR(value, on_catch) \ - if (mRes.err || !value) { \ - on_catch; \ - return NULL; \ - } - -using namespace tp; using namespace obj; -using namespace BCgen; -bool Parser::Token::isAriphm() { - switch (type) { - case Token::ADD: - case Token::SUB: - case Token::DIV: - case Token::MUL: return true; - default: return false; +struct ASTNode { + BCgen::Expression* expression = nullptr; + BCgen::Statement* statement = nullptr; +}; + +extern const lalr::ParserStateMachine* oscript_parser_state_machine; +typedef void* UserData; +typedef char SymbolType; + +typedef std::basic_string::iterator IteratorType; + +namespace action { + static UserData expr_bool(const UserData* start, const lalr::ParserNode* nodes, size_t length) { + return new BCgen::ExpressionConst(nodes[0].lexeme() == "true"); + } + + static UserData expr_int(const UserData* start, const lalr::ParserNode* nodes, size_t length) { + return {}; + } + + static UserData expr_float(const UserData* start, const lalr::ParserNode* nodes, size_t length) { + return {}; + } + + static UserData expr_string(const UserData* start, const lalr::ParserNode* nodes, size_t length) { + return {}; + } + + static UserData stm_log(const UserData* start, const lalr::ParserNode* nodes, size_t length) { + auto expr = (BCgen::Expression*) (start[1]); + return new BCgen::StatementPrint(expr); + } + + static UserData stm_defVar(const UserData* start, const lalr::ParserNode* nodes, size_t length) { + return new BCgen::StatementLocalDef(nodes[1].lexeme().c_str(), new BCgen::ExpressionConst(false)); + } + + static UserData stm_scope_append(const UserData* start, const lalr::ParserNode* nodes, size_t length) { + auto scope = (BCgen::StatementScope*) start[0]; + auto stm = (BCgen::Statement*) start[2]; + scope->mStatements.append(stm); + return scope; + } + + static UserData stm_scope_create(const UserData* start, const lalr::ParserNode* nodes, size_t length) { + auto stm = (BCgen::Statement*) start[0]; + return new BCgen::StatementScope({ stm }, true); + } + + static UserData scope(const UserData* start, const lalr::ParserNode* nodes, size_t length) { + return start[1]; + } + + static UserData tmp(const UserData* start, const lalr::ParserNode* nodes, size_t length) { + return *start; } } -bool Parser::Token::isBoolean() { - switch (type) { - case Token::EQUAL: - case Token::NOT_EQUAL: - case Token::BOOL_AND: - case Token::BOOL_OR: - case Token::MORE: - case Token::LESS: - case Token::QE_OR_MORE: - case Token::QE_OR_LESS: return true; - default: return false; - } -} +Parser::Result Parser::parse(const tp::String& stream) { -Parser::Parser() { - mTok.build({ - { "\n|\t| |\r", Token::SPACE }, - { "var", Token::VAR }, - { "class", Token::CLASS_DEF }, - { "self", Token::SELF }, - { "\\{", Token::SCOPE_IN }, - { "\\}", Token::SCOPE_OUT }, - { "=", Token::ASSIGN }, - { "def", Token::DEF_FUNC }, - { "<<", Token::PRINT }, - { "if", Token::IF }, - { "else", Token::ELSE }, - { "while", Token::WHILE }, - { "\\(", Token::BRACKET_IN }, - { "\\)", Token::BRACKET_OUT }, - { ",", Token::COMMA }, - { "new", Token::NEW }, - { "\\.", Token::CHILD }, - { "return", Token::RETURN }, - { "==", Token::EQUAL }, - { "!=", Token::NOT_EQUAL }, - { ">", Token::MORE }, - { "<", Token::LESS }, - { ">=", Token::QE_OR_MORE }, - { "<=", Token::QE_OR_LESS }, - { "!", Token::BOOL_NOT }, - { "&&", Token::BOOL_AND }, - { "\\|\\|", Token::BOOL_OR }, - { "\\+", Token::ADD }, - { "\\*", Token::MUL }, - { "\\-", Token::SUB }, - { "/", Token::DIV }, - { ";", Token::STM_END }, - { "true", Token::CONST_TRUE }, - { "false", Token::CONST_FALSE }, - { "((\\-)|(\\+))?[0-9]+i?", Token::CONST_INT }, - { R"(((\-)|(\+))?([0-9]+)(\.)([0-9]*)?f?)", Token::CONST_FLOAT }, - { R"((/\*){\*-\*}*(\*/))", Token::COMMENT_BLOCK }, - { R"("{"-"}*")", Token::CONST_STRING }, + lalr::ErrorPolicy errorPolicy; - { "([a-z]|[A-Z]|_)+([a-z]|[A-Z]|[0-9]|_)*", Token::ID }, - }); -} + lalr::Parser parser(oscript_parser_state_machine, &errorPolicy); -tp::String to_string(const char* stream, tp::alni len) { - tp::String out; - out.resize(len); - tp::memCopy(out.write(), stream, len); - return out; -} + parser.set_lexer_action_handler("string", &lalr::string_literal); -Parser::Token Parser::tokRead() { - Token out; + parser.set_action_handler("expr_bool", &action::expr_bool); + parser.set_action_handler("expr_int", &action::expr_int); + parser.set_action_handler("expr_float", &action::expr_float); + parser.set_action_handler("expr_string", &action::expr_string); - if (!tokInputLeft()) { - Token out; - out.type = Token::NO_TOKEN; - return out; - } + parser.set_action_handler("stm_defVar", &action::stm_defVar); + parser.set_action_handler("stm_log", &action::stm_log); - auto crs_start = mTok.getCursor(); - out.type = mTok.readTok(); - out.token = to_string(crs_start.str(), mTok.lastTokLEn()); + parser.set_action_handler("stm_scope_create", &action::stm_scope_create); + parser.set_action_handler("stm_scope_append", &action::stm_scope_append); - switch (out.type) { - case Token::CONST_FALSE: out.boolean = false; break; - case Token::CONST_TRUE: out.boolean = true; break; - case Token::CONST_INT: - { - char* p_end; - out.integer = std::strtol(out.token.read(), &p_end, 10); - DEBUG_ASSERT(out.token.read() != p_end); - break; - } - case Token::CONST_FLOAT: - { - char* p_end; - out.floating = std::strtod(out.token.read(), &p_end); - DEBUG_ASSERT(out.token.read() != p_end); - break; - } - case Token::CONST_STRING: - { - out.str = to_string(crs_start.str() + 1, mTok.lastTokLEn() - 2); - break; - } - } + parser.set_action_handler("scope", &action::scope); - return out; -} + parser.set_action_handler("tmp", &action::tmp); -Parser::Token Parser::tokLookup() { - auto crs = mTok.getCursor(); - auto out = tokRead(); - mTok.setCursor(crs); - return out; -} + std::string streamStd(stream.read()); -bool Parser::tokInputLeft() { - auto type = mTok.lookupTok(); + LALR_ASSERT(parser.valid()); - while (mTok.isInputLeft() && type == Token::SPACE || (type >= Token::__END__ && type <= Token::__START__)) { - mTok.skipTok(); - type = mTok.lookupTok(); - } + parser.parse(streamStd.begin(), streamStd.end()); - return type != Token::SOURCE_END_TOKEN; -} + parser.accepted(); + parser.full(); -void Parser::tokSkip() { - if (!tokInputLeft()) { - return; - } - mTok.skipTok(); -} + auto scope = (BCgen::StatementScope*) parser.user_data(); -Parser::Tokenizer::Cursor Parser::tokGetCursor() { return mTok.getCursor(); } -void Parser::tokSetCursor(Tokenizer::Cursor crs) { mTok.setCursor(crs); } - -Expression* Parser::parseExprCompound() { - CHECK(tokRead() == Token::BRACKET_IN, {}); - auto ret = parseExpr(); - CHECK_ERROR(ret, {}); - REQUIRE(tokRead() == Token::BRACKET_OUT, "Expected Closing Bracket", {}); - return ret; -} - -Expression* Parser::parseExprNEW() { - CHECK(tokRead() == Token::NEW, {}); - auto name = tokRead(); - REQUIRE(name == Token::ID, "Expected Identifier", {}); - - REQUIRE(tokRead() == Token::BRACKET_IN, "Expected opening brackets", {}); - REQUIRE(tokRead() == Token::BRACKET_OUT, "Expected closing brackets", {}); - - return ExprNew(name.token); -} - -Expression* Parser::parseExprLOCAL() { - auto local_id_tok = tokRead(); - if (local_id_tok == Token::ID) { - return ExprLocal(local_id_tok.token); - } else if (local_id_tok == Token::SELF) { - return ExprSelf(); - } - return NULL; -} - -Expression* Parser::parseExprCONST() { - auto tok = tokRead(); - switch (tok) { - case Token::CONST_FALSE: return ExprConst(false); - case Token::CONST_TRUE: return ExprConst(true); - case Token::CONST_INT: return ExprConst(tok.integer); - case Token::CONST_FLOAT: return ExprConst(tok.floating); - case Token::CONST_STRING: return ExprConst(tok.str); - default: REQUIRE(0, "not a const Expr", {}); - } -} - -Expression* Parser::parseExprCHILD(Expression* prnt) { - CHECK(tokRead() == Token::CHILD, {}); - auto id = tokRead(); - REQUIRE(id == Token::ID, "Exprected Identifier", {}); - return prnt->ExprChild(id.str); -} - -Expression* Parser::parseExprCALL(Expression* prnt) { - CHECK(tokRead() == Token::BRACKET_IN, {}); - - List args; - -READ_ARG: - Expression* expr = NULL; - auto tok = tokLookup(); - REQUIRE(tok != Token::NO_TOKEN, "Missing Closing Bracket", {}); - - if (tok != Token::BRACKET_OUT) { - - expr = parseExpr(); - CHECK_ERROR(expr, { - for (auto arg : args) { - delete arg.data(); - } - }); - - args.pushBack(expr); - - tok = tokLookup(); - if (tok == Token::COMMA) { - tokSkip(); - goto READ_ARG; - } else if (tok != Token::BRACKET_OUT) { - for (auto arg : args) { - delete arg.data(); - } - REQUIRE(0, "Expected A Closing Bracket", {}); - } - } - tokSkip(); - - auto out = prnt->ExprCall({}); - out->mArgs.reserve(args.length()); - - ualni idx = 0; - for (auto arg : args) { - out->mArgs[idx] = arg.data(); - idx++; - } - - return out; -} - -Expression* Parser::parseExprAriphm() { - - tp::InitialierList expessions = { - ExprType::Compound, - ExprType::NEW, - ExprType::LOCAL, - ExprType::CONST, - }; - - Expression* left = parseExpr(expessions); - CHECK_ERROR(left, {}); - - Expression* ret = NULL; - -PARSE: - - Expression* right = NULL; - - auto tok = tokLookup(); - if (tok.isAriphm()) { - tokSkip(); - - right = parseExpr(expessions); - - if (mRes.err) { - if (ret) { - goto PRECEDENCE; - } - - delete left; - return NULL; - } - - } else { - CHECK(ret, { delete left; }); - goto PRECEDENCE; - } - - switch (tok) { - case Token::ADD: ret = ExprAriphm(left, right, OpCode::OBJ_ADD); break; - case Token::SUB: ret = ExprAriphm(left, right, OpCode::OBJ_SUB); break; - case Token::DIV: ret = ExprAriphm(left, right, OpCode::OBJ_DIV); break; - case Token::MUL: ret = ExprAriphm(left, right, OpCode::OBJ_MUL); - } - - left = ret; - goto PARSE; - -PRECEDENCE: - // FIXME: Not Implemented - - return ret; -} - -Expression* Parser::parseExprBOOLEAN() { - - tp::InitialierList expessions = { - ExprType::Compound, ExprType::NEW, ExprType::LOCAL, ExprType::CONST, ExprType::BOOLEAN_NOT, - }; - - Expression* left = parseExpr(expessions); - CHECK_ERROR(left, {}); - - Expression* ret = NULL; - -PARSE: - - Expression* right = NULL; - - auto tok = tokLookup(); - if (tok.isBoolean()) { - tokSkip(); - - right = parseExpr(expessions); - - if (mRes.err) { - if (ret) { - goto PRECEDENCE; - } - - delete left; - return NULL; - } - - } else { - CHECK(ret, { delete left; }); - goto PRECEDENCE; - } - - switch (tok) { - case Token::EQUAL: ret = ExprBool(left, right, OpCode::EQUAL); break; - case Token::NOT_EQUAL: ret = ExprBool(left, right, OpCode::NOT_EQUAL); break; - case Token::BOOL_AND: ret = ExprBool(left, right, OpCode::AND); break; - case Token::BOOL_OR: ret = ExprBool(left, right, OpCode::OR); break; - case Token::MORE: ret = ExprBool(left, right, OpCode::MORE); break; - case Token::LESS: ret = ExprBool(left, right, OpCode::LESS); break; - case Token::QE_OR_MORE: ret = ExprBool(left, right, OpCode::EQUAL_OR_MORE); break; - case Token::QE_OR_LESS: ret = ExprBool(left, right, OpCode::EQUAL_OR_LESS); - } - - left = ret; - goto PARSE; - -PRECEDENCE: - // FIXME: Not Implemented - - return ret; -} - -Expression* Parser::parseExprBOOLEAN_NOT() { - CHECK(tokRead() == Token::BOOL_NOT, {}); - - tp::InitialierList exprs = { - ExprType::Compound, ExprType::BOOLEAN, ExprType::Ariphm, ExprType::NEW, ExprType::LOCAL, ExprType::CONST, - }; - - auto out = parseExpr(exprs); - CHECK_ERROR(out, {}); - - return ExprBoolNot(out); -} - -Expression* Parser::parseExprFUNC() { - auto op_tok = tokRead(); - CHECK(op_tok == Token::ID, {}); - return ExprFunc(op_tok.token); -} - -// passed prnt isno longer responsability of callee -// suc : returns top level parent -// err : returns NULL -Expression* Parser::parseExprChain(Expression* prnt) { - -PARSE_CHAIN: - auto tok = tokLookup(); - - switch (tok) { - case Token::CHILD: - { - tokRead(); - - auto child_id = tokRead(); - REQUIRE(child_id == Token::ID, "expected an id", { delete prnt; }); - - prnt = prnt->ExprChild(child_id.token); - goto PARSE_CHAIN; - } - - case Token::BRACKET_IN: - { - - auto new_prnt = parseExprCALL(prnt); - CHECK_ERROR(new_prnt, { delete prnt; }); - - if (prnt->mType == Expression::Type::CHILD) { - ((ExpressionChild*) prnt)->mMethod = true; - } - - prnt = new_prnt; - goto PARSE_CHAIN; - } - } - - return prnt; -} - -Expression* Parser::parseExpr(tp::InitialierList expressions) { - - Expression* out = NULL; - - List errors; - - for (auto expr_type : expressions) { - auto crs = tokGetCursor(); - switch (expr_type) { - case Parser::ExprType::BOOLEAN_NOT: out = parseExprBOOLEAN_NOT(); break; - case Parser::ExprType::BOOLEAN: out = parseExprBOOLEAN(); break; - case Parser::ExprType::Ariphm: out = parseExprAriphm(); break; - case Parser::ExprType::NEW: out = parseExprNEW(); break; - case Parser::ExprType::LOCAL: out = parseExprLOCAL(); break; - case Parser::ExprType::CONST: out = parseExprCONST(); break; - case Parser::ExprType::Compound: out = parseExprCompound(); break; - } - - if (out) { - break; - } - - tokSetCursor(crs); - if (mRes.err) { - errors.pushBack(mRes.err); - mRes.err = NULL; - } - } - - if (out) { - // check for child expression and calls - out = parseExprChain(out); - - // check errors - if (mRes.err) { - errors.pushBack(mRes.err); - mRes.err = NULL; - goto ERRORS; - } - - for (auto err : errors) { - delete err.data(); - } - - return out; - } - -ERRORS: - Error* error = NULL; - tp::alni max_advanced = 0; - for (auto err : errors) { - if (err.data()->mAdvanecedIdx && err.data()->mAdvanecedIdx > max_advanced) { - max_advanced = err.data()->mAdvanecedIdx; - error = err.data(); - } - } - - if (error) { - mRes.err = new Error(*error); - - for (auto err : errors) { - delete err.data(); - } - - return NULL; - } - REQUIRE(0, "Expected and expression", {}); -} - -Statement* Parser::parseStmCall() { - - Expression* expr = parseExpr(); - CHECK_ERROR(expr, {}); - - REQUIRE(expr->mType == Expression::Type::CALL, "expression statement can only be function call", { delete expr; }); - - if (tokRead() != Token::STM_END) { - delete expr; - REQUIRE(0, "Expected End Of Statement", {}); - } - - return StmIgnore(expr); -} - -Statement* Parser::parseStmDefFunc() { - CHECK(tokRead() == Token::DEF_FUNC, {}); - List args; - auto name = tokRead(); - REQUIRE(name == Token::ID, "Expected an Identifier", {}); - - REQUIRE(tokRead() == Token::BRACKET_IN, "Expected Opening Bracket", {}); - -READ_ARG: - auto tok = tokLookup(); - - REQUIRE(tok != Token::NO_TOKEN, "Missing Closing Bracket", {}); - - if (tok == Token::ID) { - args.pushBack(tok.token); - tokSkip(); - tok = tokLookup(); - } - - if (tok == Token::COMMA) { - tokSkip(); - goto READ_ARG; - } - - REQUIRE(tok == Token::BRACKET_OUT, "Expected Closing Bracket", {}); - tokSkip(); - - auto func_def = StmDefFunc(name.token, {}, {}); - - func_def->mArgs.reserve(args.length()); - - ualni idx = 0; - for (auto iter : args) { - func_def->mArgs[idx] = iter.data(); - idx++; - } - - StatementScope* scope = parseScope(true); - CHECK_ERROR(scope, { delete func_def; }); - - func_def->mStatements.reserve(scope->mStatements.size()); - - idx = 0; - for (auto stm : scope->mStatements) { - func_def->mStatements[idx] = stm.data(); - idx++; - } - - delete scope; - return func_def; -} - -Statement* Parser::parseStmDefLocal() { - CHECK(tokRead() == Token::VAR, {}); - - auto tok = tokRead(); - REQUIRE(tok == Token::ID, "Expected an Identifier", {}); - REQUIRE(tokRead() == Token::ASSIGN, "Expected an assigment", {}); - - auto expr = parseExpr(); - CHECK_ERROR(expr, {}); - - if (tokRead() != Token::STM_END) { - delete expr; - REQUIRE(0, "Expected End Of Statement", {}); - } - - return StmDefLocal(tok.token, expr); -} - -Statement* Parser::parseStmReturn() { - CHECK(tokRead() == Token::RETURN, {}); - auto crs = tokGetCursor(); - - auto expr = parseExpr(); - if (mRes.err) { - tokSetCursor(crs); - delete mRes.err; - mRes.err = NULL; - } - - if (tokRead() != Token::STM_END) { - if (expr) delete expr; - REQUIRE(0, "Expected End Of Statement", {}); - } - - return expr ? StmReturn(expr) : StmReturn(); -} - -Statement* Parser::parseStmPrint() { - CHECK(tokRead() == Token::PRINT, {}); - auto expr = parseExpr(); - CHECK_ERROR(expr, {}); - - if (tokRead() != Token::STM_END) { - delete expr; - REQUIRE(0, "Expected End Of Statement", {}); - } - return StmPrint(expr); -} - -Statement* Parser::parseStmIf() { - CHECK(tokRead() == Token::IF, {}); - - // single if - REQUIRE(tokRead() == Token::BRACKET_IN, "Expected Opening Bracket", {}); - auto expr = parseExpr(); - CHECK_ERROR(expr, {}); - - if (tokRead() != Token::BRACKET_OUT) { - delete expr; - REQUIRE(0, "Expected Closing Bracket", {}); - } - - auto ontrue = parseScope(false); - CHECK_ERROR(ontrue, {}); - - // if-else - auto crs = tokGetCursor(); - if (tokRead() == Token::ELSE) { - StatementScope* onfalse = parseScope(false); - CHECK_ERROR(onfalse, { - delete ontrue; - delete expr; - }); - - return StmIf(expr, ontrue, onfalse); - } - tokSetCursor(crs); - - return StmIf(expr, ontrue, NULL); -} - -Statement* Parser::parseStmWhile() { - CHECK(tokRead() == Token::WHILE, {}); - - REQUIRE(tokRead() == Token::BRACKET_IN, "Expected Opening Bracket", {}); - auto expr = parseExpr(); - CHECK_ERROR(expr, {}); - - if (tokRead() != Token::BRACKET_OUT) { - delete expr; - REQUIRE(0, "Expected Closing Bracket", {}); - } - - auto scope = parseScope(false); - CHECK_ERROR(scope, {}); - - return StmWhile(expr, scope); -} - -Statement* Parser::parseStmCopy() { - auto left = parseExpr(); - CHECK_ERROR(left, {}); - - CHECK(tokRead() == Token::ASSIGN, {}); - - auto right = parseExpr(); - CHECK_ERROR(right, { delete left; }); - - if (tokRead() != Token::STM_END) { - delete left; - delete right; - REQUIRE(0, "Expected End Of Statement", {}); - } - - return StmCopy(left, right); -} - -Statement* Parser::parseStmClassDef() { - CHECK(tokRead() == Token::CLASS_DEF, {}); - - auto id = tokRead(); - REQUIRE(id == Token::ID, "Expected an Identifier", {}); - - auto scope = parseScope(true); - CHECK_ERROR(scope, {}); - - return StmClassDef(id.token, scope); -} - -Statement* Parser::parseStm(tp::InitialierList stm_types) { - Statement* out = NULL; - - List errors; - - for (auto stm_type : stm_types) { - auto crs = tokGetCursor(); - switch (stm_type) { - case StmType::DefFunc: out = parseStmDefFunc(); break; - case StmType::DefLocal: out = parseStmDefLocal(); break; - case StmType::Return: out = parseStmReturn(); break; - case StmType::Print: out = parseStmPrint(); break; - case StmType::If: out = parseStmIf(); break; - case StmType::While: out = parseStmWhile(); break; - case StmType::Copy: out = parseStmCopy(); break; - case StmType::Call: out = parseStmCall(); break; - case StmType::CLASS_DEF: out = parseStmClassDef(); break; - } - - if (out) { - break; - } - - tokSetCursor(crs); - if (mRes.err) { - errors.pushBack(mRes.err); - mRes.err = NULL; - } - } - - if (out) { - for (auto err : errors) { - delete err.data(); - } - return out; - } - - Error* error = NULL; - tp::alni max_advanced = 0; - for (auto err : errors) { - if (err.data()->mAdvanecedIdx && max_advanced < err.data()->mAdvanecedIdx) { - max_advanced = err.data()->mAdvanecedIdx; - error = err.data(); - } - } - - if (error) { - mRes.err = new Error(*error); - - for (auto err : errors) { - delete err.data(); - } - - return NULL; - } - - REQUIRE(0, "Exprected A Statement", {}); -} - -StatementScope* Parser::parseScope(bool aPushToScopeStack) { - CHECK(tokRead() == Token::SCOPE_IN, {}); - - auto out = new StatementScope({}, aPushToScopeStack); - List stms; - -READ_STM: - auto crs = tokGetCursor(); - auto tok = tokRead(); - - if (tok == Token::NO_TOKEN) { - delete out; - for (auto stm : stms) { - delete stm.data(); - } - REQUIRE(0, "Missing Scope Closing Bracket", {}); - } - - if (tok != Token::SCOPE_OUT) { - tokSetCursor(crs); - - auto stm = parseStm(); - CHECK_ERROR(stm, { - delete out; - for (auto stm : stms) { - delete stm.data(); - } - }); - - stms.pushBack(stm); - - goto READ_STM; - } - - out->mStatements.reserve(stms.length()); - - ualni idx = 0; - for (auto stm : stms) { - out->mStatements[idx] = stm.data(); - idx++; - } - - return out; -} - -Parser::Resault Parser::parse(const tp::String& oscript) { - mTok.bindSource(oscript.read()); - mTok.reset(); - - mRes.scope = new StatementScope({}, true); - - List stms; - do { - auto stm = parseStm(); - - if (mRes.err || !stm) { // catch - delete mRes.scope; - mRes.scope = NULL; - for (auto stm : stms) { - delete stm.data(); - } - - return mRes; - } - - stms.pushBack(stm); - - } while (tokInputLeft()); - - mRes.scope->mStatements.reserve(stms.length()); - - ualni idx = 0; - for (auto stm : stms) { - mRes.scope->mStatements[idx] = stm.data(); - idx++; - } - - return mRes; -} + return { nullptr, scope }; +} \ No newline at end of file diff --git a/Objects/public/compiler/expression.h b/Objects/public/compiler/expression.h index 424a9be..9065cfe 100644 --- a/Objects/public/compiler/expression.h +++ b/Objects/public/compiler/expression.h @@ -13,7 +13,6 @@ namespace obj { struct ExpressionCall; struct Expression { - enum class Type { NONE, NEW, @@ -76,7 +75,7 @@ namespace obj { Expression* mRight = NULL; enum class BoolType : tp::uint1 { - AND = 24U, + AND = 24U, OR, EQUAL, NOT_EQUAL, diff --git a/Objects/public/parser/parser.h b/Objects/public/parser/parser.h index ea55a49..9e8b38d 100644 --- a/Objects/public/parser/parser.h +++ b/Objects/public/parser/parser.h @@ -3,193 +3,43 @@ #include "compiler/statement.h" #include "compiler/expression.h" -#include "Tokenizer.hpp" - namespace obj { class Parser { - - struct Token { - - tp::String token; - - tp::alni integer; - tp::alnf floating; - bool boolean; - tp::String str; - - enum TokType : tp::alni { - __START__ = 0, - ID, - CONST_INT, - CONST_FLOAT, - CONST_STRING, - SCOPE_IN, - SCOPE_OUT, - ASSIGN, - DEF_FUNC, - PRINT, - IF, - ELSE, - WHILE, - BRACKET_IN, - BRACKET_OUT, - COMMA, - NEW, - CHILD, - RETURN, - EQUAL, - NOT_EQUAL, - MORE, - LESS, - QE_OR_MORE, - QE_OR_LESS, - BOOL_NOT, - BOOL_AND, - BOOL_OR, - ADD, - MUL, - SUB, - DIV, - QUOTES, - CONST_TRUE, - CONST_FALSE, - STM_END, - SPACE, - VAR, - CLASS_DEF, - SELF, - COMMENT_BLOCK, - __END__, - NO_TOKEN, - FAILED, - SOURCE_END_TOKEN, - } type; - - operator TokType() { - return type; - } - - bool isAriphm(); - bool isBoolean(); - }; - - typedef tp::SimpleTokenizer Tokenizer; - Tokenizer mTok; - - enum class ExprType { - BOOLEAN_NOT = 0, - BOOLEAN, - Ariphm, - NEW, - LOCAL, - CONST, - Compound - }; - - enum class StmType { - DefFunc = 0, - DefLocal, - Return, - Print, - If, - While, - Copy, - Call, - CLASS_DEF - }; - public: - - Parser(); + Parser() = default; struct Error { - tp::String mDescr = "No Description"; - tp::alni mAdvanecedIdx = 0; + tp::String mDescription = "No Description"; + tp::alni mAdvancedIdx = 0; - Error() {} - Error(tp::String descr, tp::alni idx) { - mDescr = descr; - mAdvanecedIdx = idx; + Error() = default; + Error(const tp::String& description, tp::alni idx) { + mDescription = description; + mAdvancedIdx = idx; } - tp::Pair get_err_location(const char* stream) { + tp::Pair getErrorLocation(const char* stream) const { tp::alni line = 1; - tp::alni colomn = 1; + tp::alni column = 1; - //assert(mAdvanecedIdx); - - for (auto i : tp::Range(mAdvanecedIdx)) { + for (auto i : tp::Range(mAdvancedIdx)) { if (stream[i] == '\n') { - colomn = 0; + column = 0; line++; } - colomn++; + column++; } - return { line, colomn }; + return { line, column }; } }; - struct Resault { - Error* err = NULL; - obj::BCgen::StatementScope* scope = NULL; - } mRes; + struct Result { + Error* err = nullptr; + obj::BCgen::StatementScope* scope = nullptr; + }; - Resault parse(const tp::String& stream); - - private: - - Token tokRead(); - Token tokLookup(); - void tokSkip(); - bool tokInputLeft(); - Tokenizer::Cursor tokGetCursor(); - void tokSetCursor(Tokenizer::Cursor); - - BCgen::Expression* parseExprCompound(); - BCgen::Expression* parseExprNEW(); - BCgen::Expression* parseExprLOCAL(); - BCgen::Expression* parseExprCONST(); - BCgen::Expression* parseExprCHILD(BCgen::Expression* prnt); - BCgen::Expression* parseExprCALL(BCgen::Expression* prnt); - BCgen::Expression* parseExprAriphm(); - BCgen::Expression* parseExprBOOLEAN(); - BCgen::Expression* parseExprBOOLEAN_NOT(); - BCgen::Expression* parseExprFUNC(); - BCgen::Expression* parseExprChain(BCgen::Expression* prnt); - - BCgen::Expression* parseExpr(tp::InitialierList expressions = { - ExprType::BOOLEAN_NOT, - ExprType::BOOLEAN, - ExprType::Ariphm, - ExprType::NEW, - ExprType::LOCAL, - ExprType::CONST, - }); - - BCgen::Statement* parseStmCall(); - BCgen::Statement* parseStmDefFunc(); - BCgen::Statement* parseStmDefLocal(); - BCgen::Statement* parseStmReturn(); - BCgen::Statement* parseStmPrint(); - BCgen::Statement* parseStmIf(); - BCgen::Statement* parseStmWhile(); - BCgen::Statement* parseStmCopy(); - BCgen::Statement* parseStmClassDef(); - - BCgen::Statement* parseStm(tp::InitialierList stm_types = { - StmType::DefFunc, - StmType::DefLocal, - StmType::Return, - StmType::Print, - StmType::If, - StmType::While, - StmType::Copy, - StmType::Call, - StmType::CLASS_DEF - }); - - BCgen::StatementScope* parseScope(bool aPushToScopeStack); + Result parse(const tp::String& stream); }; }; diff --git a/Objects/tests/core/TestCore.cpp b/Objects/tests/TestCore.cpp similarity index 100% rename from Objects/tests/core/TestCore.cpp rename to Objects/tests/TestCore.cpp diff --git a/Objects/tests/interpreter/TestInterpreter.cpp b/Objects/tests/TestInterpreter.cpp similarity index 100% rename from Objects/tests/interpreter/TestInterpreter.cpp rename to Objects/tests/TestInterpreter.cpp diff --git a/Objects/tests/TestParser.cpp b/Objects/tests/TestParser.cpp new file mode 100644 index 0000000..da3f82b --- /dev/null +++ b/Objects/tests/TestParser.cpp @@ -0,0 +1,16 @@ + +#include "Testing.hpp" + +#include "parser/parser.h" + +using namespace tp; +using namespace obj; + +TEST_DEF_STATIC(Basic) { + Parser parser; + + String stream = "{ var i; print false; }"; + auto res = parser.parse(stream); +} + +TEST_DEF(Parser) { testBasic(); } diff --git a/Objects/tests/primitives/TestPrimitives.cpp b/Objects/tests/TestPrimitives.cpp similarity index 100% rename from Objects/tests/primitives/TestPrimitives.cpp rename to Objects/tests/TestPrimitives.cpp diff --git a/Objects/tests/Tests.cpp b/Objects/tests/Tests.cpp index 2b8906c..2d752b2 100644 --- a/Objects/tests/Tests.cpp +++ b/Objects/tests/Tests.cpp @@ -6,6 +6,7 @@ using namespace tp; using namespace obj; +void testParser(); void testCore(); void testPrimitives(); void testInterpreter(); @@ -15,6 +16,11 @@ int main() { tp::ModuleManifest* deps[] = { &gModuleObjects, nullptr }; tp::ModuleManifest module("ObjectsTests", nullptr, nullptr, deps); + if (module.initialize()) { + testParser(); + module.deinitialize(); + } + if (module.initialize()) { testCore(); module.deinitialize();