diff --git a/.gitmodules b/.gitmodules index 0fc531f..805e8a7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "Externals/lua"] path = Externals/lua url = https://github.com/lua/lua.git +[submodule "Externals/lalr"] + path = Externals/lalr + url = https://github.com/IlyaShurupov/lalr.git diff --git a/Objects/CMakeLists.txt b/Objects/CMakeLists.txt index f6a6568..c0cbeea 100644 --- a/Objects/CMakeLists.txt +++ b/Objects/CMakeLists.txt @@ -22,8 +22,9 @@ add_executable(osg ./applications/GUI.cpp ./applications/GUIEntry.cpp) #target_link_libraries(osi ${PROJECT_NAME}) target_link_libraries(osg ${PROJECT_NAME} Graphics Imgui) +file(COPY "rsc/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") + ### -------------------------- Tests -------------------------- ### -enable_testing() file(GLOB TEST_SOURCES "./tests/*.cpp" "./tests/*/*.cpp") add_executable(${PROJECT_NAME}Tests ${TEST_SOURCES}) target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Utils) diff --git a/Objects/applications/GUI.cpp b/Objects/applications/GUI.cpp index 1ece18d..ac85365 100644 --- a/Objects/applications/GUI.cpp +++ b/Objects/applications/GUI.cpp @@ -29,7 +29,8 @@ namespace ImGui { void ApplyStyle(tp::halnf dpmm, float font_size_mm = 5, float ui_scale = 1); }; -ImGui::PopupData ImGui::HoverPopupBegin(const char* str_id, tp::Vec2F size, tp::Vec2F pos_p, ImGuiPopupFlags popup_flags) { +ImGui::PopupData +ImGui::HoverPopupBegin(const char* str_id, tp::Vec2F size, tp::Vec2F pos_p, ImGuiPopupFlags popup_flags) { ImGui::PopupData out; out.ishovered = ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup); @@ -69,7 +70,10 @@ void ImGui::HoverPopupEnd(ImGui::PopupData& in) { return; } - in.ishovered |= IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_ChildWindows); + in.ishovered |= IsWindowHovered( + ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | + ImGuiHoveredFlags_ChildWindows + ); tp::Vec2F mousepos = { ImGui::GetMousePos().x, ImGui::GetMousePos().y }; tp::halnf tollerance = 10; @@ -876,7 +880,12 @@ void obj::ObjectsGUI::explorer() { } ImGui::SameLine(); - ImGui::BeginChild("child_path", { 0, 45 }, false, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_HorizontalScrollbar); + ImGui::BeginChild( + "child_path", + { 0, 45 }, + false, + ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_HorizontalScrollbar + ); tp::List rev_path; for (auto childo = mViewStack.last(); childo; childo = childo->prev) { rev_path.pushBack(&childo->data); @@ -994,7 +1003,7 @@ void obj::ObjectsGUI::properties(const obj::ObjectType* type, bool top_of_tree_v assert(type); assert(mActive); - assert(mActive->type == type); + if (mActive->type != type) return; ImGui::Text(" RefCount : %i", obj::NDO->getrefc(mActive)); diff --git a/Objects/private/parser/Bindings.cpp b/Objects/private/parser/Bindings.cpp index 689623d..02c6402 100644 --- a/Objects/private/parser/Bindings.cpp +++ b/Objects/private/parser/Bindings.cpp @@ -1,8 +1,6 @@ #include "Private.hpp" -#include - using namespace obj::BCgen; typedef lalr::ParserNode Node; @@ -12,23 +10,19 @@ static UserData scope(const UserData* start, const Node*, size_t) { return start static UserData scope_empty(const UserData*, const Node*, size_t) { return new StatementScope({}, true); } static UserData stm_list_append(const UserData* start, const Node*, size_t) { - auto scope = (StatementScope*) start[0]; - auto stm = (Statement*) start[1]; - scope->mStatements.append(stm); + auto scope = (StatementScope*) start[0].statement; + scope->mStatements.append(start[1].statement); return scope; } static UserData stm_list_create(const UserData* start, const Node*, size_t) { - return new StatementScope({ (Statement*) start[0] }, true); + return new StatementScope({ start[0].statement }, true); } -static UserData stm_log(const UserData* start, const Node*, size_t) { - auto expr = (Expression*) (start[1]); - return new StatementPrint(expr); -} +static UserData stm_log(const UserData* start, const Node*, size_t) { return new StatementPrint(start[1].expression); } static UserData stm_assign(const UserData* start, const Node*, size_t) { - return new StatementCopy((Expression*) start[0], (Expression*) start[2]); + return new StatementCopy(start[0].expression, start[2].expression); } static UserData stm_var_def_new_type(const UserData*, const Node* nodes, size_t) { @@ -36,51 +30,53 @@ static UserData stm_var_def_new_type(const UserData*, const Node* nodes, size_t) } static UserData stm_var_def_assign(const UserData* start, const Node* nodes, size_t) { - return new StatementLocalDef((char*) nodes[1].lexeme().c_str(), (Expression*) start[3]); + return new StatementLocalDef((char*) nodes[1].lexeme().c_str(), start[3].expression); } static UserData stm_return(const UserData* start, const Node*, size_t length) { if (length == 2) { - return new StatementReturn((Expression*) start[1]); + return new StatementReturn(start[1].expression); } return new StatementReturn(); } static UserData stm_ignore(const UserData* start, const Node*, size_t) { - return new StatementIgnore((Expression*) start[0]); + return new StatementIgnore(start[0].expression); } static UserData stm_def_class(const UserData* start, const Node* nodes, size_t) { - auto newClass = new StatementClassDef((char*) nodes[1].lexeme().c_str(), (StatementScope*) start[2]); + auto newClass = new StatementClassDef((char*) nodes[1].lexeme().c_str(), (StatementScope*) start[2].statement); return newClass; } static UserData stm_def_method(const UserData* start, const Node* nodes, size_t) { auto method = new StatementFuncDef((char*) nodes[1].lexeme().c_str()); - method->mStatements = (StatementScope*) start[5]; - auto args = (tp::Buffer*) start[3]; + method->mStatements = (StatementScope*) start[5].statement; + auto args = start[3].arguments; method->mArgs = *args; delete args; return method; } static UserData stm_if(const UserData* start, const Node*, size_t length) { - if (length == 5) return new StatementIf((Expression*) start[2], (StatementScope*) start[4], nullptr); - return new StatementIf((Expression*) start[2], (StatementScope*) start[4], (StatementScope*) start[6]); + if (length == 5) return new StatementIf(start[2].expression, (StatementScope*) start[4].statement, nullptr); + return new StatementIf( + start[2].expression, (StatementScope*) start[4].statement, (StatementScope*) start[6].statement + ); } static UserData stm_while_loop(const UserData* start, const Node*, size_t) { - return new StatementWhile((Expression*) start[2], (StatementScope*) start[4]); + return new StatementWhile(start[2].expression, (StatementScope*) start[4].statement); } static UserData stm_break(const UserData*, const Node*, size_t) { ASSERT(0); // todo : implement break - return nullptr; + return {}; } static UserData id_list_append(const UserData* start, const Node* nodes, size_t) { - auto list = (tp::Buffer*) start[0]; + auto list = start[0].arguments; list->append((char*) nodes[1].lexeme().c_str()); return list; } @@ -90,82 +86,78 @@ static UserData id_list_create(const UserData*, const Node* nodes, size_t) { } static UserData expr_function(const UserData* start, const Node*, size_t) { - auto expr = (Expression*) (start[0]); - auto args = (ExpressionList*) (start[2]); + auto expr = start[0].expression; + auto args = (ExpressionList*) start[2].expression; return expr->ExprCall(args); } static UserData expr_method(const UserData* start, const Node* nodes, size_t) { - auto expr = (Expression*) (start[0]); - auto args = (ExpressionList*) (start[4]); + auto expr = start[0].expression; + auto args = (ExpressionList*) (start[4].expression); auto childId = nodes[1].lexeme(); auto method = new ExpressionChild(expr, (char*) childId.c_str()); return method->ExprCall(args); } static UserData expr_list_append(const UserData* start, const Node*, size_t) { - auto list = (ExpressionList*) start[0]; - auto expr = (Expression*) start[2]; + auto list = (ExpressionList*) start[0].expression; + auto expr = start[2].expression; list->mItems.append(expr); return list; } static UserData expr_list_create(const UserData* start, const Node*, size_t) { auto exprList = new ExpressionList(); - exprList->mItems.append((Expression*) start[0]); + exprList->mItems.append(start[0].expression); return exprList; } static UserData expr_child(const UserData* start, const Node* nodes, size_t) { - return new ExpressionChild((Expression*) start[0], (char*) nodes[2].lexeme().c_str()); + return new ExpressionChild(start[0].expression, (char*) nodes[2].lexeme().c_str()); } static UserData expr_bool_eq(const UserData* start, const Node*, size_t) { - return new ExpressionBoolean((Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::EQUAL); + return new ExpressionBoolean(start[0].expression, start[2].expression, ExpressionBoolean::BoolType::EQUAL); } static UserData expr_bool_negate(const UserData* start, const Node*, size_t) { - return new ExpressionBoolean((Expression*) start[1]); + return new ExpressionBoolean(start[1].expression); } static UserData expr_bool_neq(const UserData* start, const Node*, size_t) { - return new ExpressionBoolean((Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::NOT_EQUAL); + return new ExpressionBoolean(start[0].expression, start[2].expression, ExpressionBoolean::BoolType::NOT_EQUAL); } static UserData expr_bool_grater(const UserData* start, const Node*, size_t) { - return new ExpressionBoolean((Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::MORE); + return new ExpressionBoolean(start[0].expression, start[2].expression, ExpressionBoolean::BoolType::MORE); } static UserData expr_bool_lesser(const UserData* start, const Node*, size_t) { - return new ExpressionBoolean((Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::LESS); + return new ExpressionBoolean(start[0].expression, start[2].expression, ExpressionBoolean::BoolType::LESS); } static UserData expr_bool_grater_eq(const UserData* start, const Node*, size_t) { - return new ExpressionBoolean( - (Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::EQUAL_OR_MORE - ); + return new ExpressionBoolean(start[0].expression, start[2].expression, ExpressionBoolean::BoolType::EQUAL_OR_MORE); } static UserData expr_bool_lesser_eq(const UserData* start, const Node*, size_t) { - return new ExpressionBoolean( - (Expression*) start[0], (Expression*) start[2], ExpressionBoolean::BoolType::EQUAL_OR_LESS - ); + return new ExpressionBoolean(start[0].expression, start[2].expression, ExpressionBoolean::BoolType::EQUAL_OR_LESS); } static UserData expr_add(const UserData* start, const Node*, size_t) { - return new ExpressionArithmetics((Expression*) start[0], (Expression*) start[2], obj::OpCode::OBJ_ADD); + return new ExpressionArithmetics(start[0].expression, start[2].expression, obj::OpCode::OBJ_ADD); } static UserData expr_subtract(const UserData* start, const Node*, size_t) { - return new ExpressionArithmetics((Expression*) start[0], (Expression*) start[2], obj::OpCode::OBJ_SUB); + return new ExpressionArithmetics(start[0].expression, start[2].expression, obj::OpCode::OBJ_SUB); } static UserData expr_multiply(const UserData* start, const Node*, size_t) { - return new ExpressionArithmetics((Expression*) start[0], (Expression*) start[2], obj::OpCode::OBJ_MUL); + return new ExpressionArithmetics(start[0].expression, start[2].expression, obj::OpCode::OBJ_MUL); } static UserData expr_divide(const UserData* start, const Node*, size_t) { - return new ExpressionArithmetics((Expression*) start[0], (Expression*) start[2], obj::OpCode::OBJ_DIV); + return new ExpressionArithmetics(start[0].expression, start[2].expression, obj::OpCode::OBJ_DIV); } static UserData expr_compound(const UserData* start, const Node*, size_t) { return start[1]; } @@ -246,4 +238,4 @@ void bind(LalrParser& parser) { BIND(tmp); parser.set_lexer_action_handler("string", &lalr::string_literal); -} \ No newline at end of file +} diff --git a/Objects/private/parser/Private.hpp b/Objects/private/parser/Private.hpp index 90a7e7e..d5c3f36 100644 --- a/Objects/private/parser/Private.hpp +++ b/Objects/private/parser/Private.hpp @@ -4,7 +4,41 @@ #include #include -typedef void* UserData; +#include "compiler/statement.h" +#include "compiler/expression.h" + +#include "Tree.hpp" + +struct UserNode { + obj::BCgen::Expression* expression = nullptr; + obj::BCgen::Statement* statement = nullptr; + tp::Buffer* arguments = nullptr; + + UserNode(obj::BCgen::Statement* stm) : + statement(stm) {} + + UserNode(obj::BCgen::Expression* expr) : + expression(expr) {} + + UserNode(tp::Buffer* argList) : + arguments(argList) {} + + UserNode() = default; + + obj::BCgen::Statement* releaseStm() { + auto out = statement; + statement = nullptr; + return out; + } + + void destroy() { + delete statement; + delete arguments; + delete expression; + } +}; + +typedef UserNode UserData; typedef char SymbolType; typedef std::basic_string::iterator IteratorType; @@ -13,4 +47,4 @@ extern const lalr::ParserStateMachine* oscript_parser_state_machine; typedef lalr::Parser LalrParser; -void bind(LalrParser& parser); \ No newline at end of file +void bind(LalrParser& parser); diff --git a/Objects/private/parser/parser.cpp b/Objects/private/parser/parser.cpp index ece8b6a..c0a09c5 100644 --- a/Objects/private/parser/parser.cpp +++ b/Objects/private/parser/parser.cpp @@ -1,5 +1,4 @@ - #include #include "Private.hpp" @@ -36,7 +35,12 @@ Parser::Result Parser::parse(const tp::String& stream) { ASSERT(parser.valid()); parser.parse(streamStd.begin(), streamStd.end()); - auto scope = (BCgen::StatementScope*) parser.user_data(); - return { scope, parser.accepted() && parser.full() }; + BCgen::StatementScope* out = nullptr; + + if (parser.accepted() && parser.full()) { + out = (BCgen::StatementScope*) parser.user_data().statement; + } + + return { out, !(parser.accepted() && parser.full()) }; } \ No newline at end of file diff --git a/Objects/rsc/Font.ttf b/Objects/rsc/Font.ttf new file mode 100644 index 0000000..8a63054 Binary files /dev/null and b/Objects/rsc/Font.ttf differ diff --git a/Objects/tests/TestInterpreter.cpp b/Objects/tests/TestInterpreter.cpp index d96eb64..a218f05 100644 --- a/Objects/tests/TestInterpreter.cpp +++ b/Objects/tests/TestInterpreter.cpp @@ -42,7 +42,7 @@ if (i == 10) { auto script = R"( var i = 10; - print (i + 10) * 5; + print i; )"; TEST_DEF_STATIC(Complex) { diff --git a/Objects/tests/TestParser.cpp b/Objects/tests/TestParser.cpp index aabc5fc..40b35a1 100644 --- a/Objects/tests/TestParser.cpp +++ b/Objects/tests/TestParser.cpp @@ -17,4 +17,18 @@ TEST_DEF_STATIC(Basic) { delete res.scope; } -TEST_DEF(Parser) { testBasic(); } +TEST_DEF_STATIC(ErrorHandling) { + Parser parser; + + String stream = "var i = true; print (i + 1) * 10; invalidCharacter "; + auto res = parser.parse(stream); + + TEST(res.isError); + + delete res.scope; +} + +TEST_DEF(Parser) { + testBasic(); + testErrorHandling(); +} diff --git a/Objects/tests/Tests.cpp b/Objects/tests/Tests.cpp index 2d752b2..80e1230 100644 --- a/Objects/tests/Tests.cpp +++ b/Objects/tests/Tests.cpp @@ -17,22 +17,12 @@ int main() { tp::ModuleManifest module("ObjectsTests", nullptr, nullptr, deps); if (module.initialize()) { + testParser(); - module.deinitialize(); - } + // testCore(); + // testPrimitives(); + // testInterpreter(); - if (module.initialize()) { - testCore(); - module.deinitialize(); - } - - if (module.initialize()) { - testPrimitives(); - module.deinitialize(); - } - - if (module.initialize()) { - testInterpreter(); module.deinitialize(); }