From 1b9b281dec6690dac03adb5049c162cc9c8f7223 Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 28 Oct 2021 22:18:01 +0200 Subject: [PATCH 001/254] Heavily modify Target.hpp, add a pointerAs function, and add an overload to Yerbacon::exit --- src/headers/Yerbacon.hpp | 5 ++ src/headers/parsing/ParseComponents.hpp | 1 + src/headers/transpiler/Target.hpp | 48 ++++++++++--------- src/headers/transpiler/implementations/Js.hpp | 13 +++-- .../transpiler/implementations/Lua.hpp | 19 ++++---- src/headers/transpiler/implementations/Py.hpp | 11 +++-- src/main.cpp | 7 +-- 7 files changed, 60 insertions(+), 44 deletions(-) diff --git a/src/headers/Yerbacon.hpp b/src/headers/Yerbacon.hpp index 3c5ad2d..ae98e42 100644 --- a/src/headers/Yerbacon.hpp +++ b/src/headers/Yerbacon.hpp @@ -47,6 +47,7 @@ namespace Yerbacon { std::cout << std::endl; std::exit(EXIT_FAILURE); } + inline void exit(const char* reason) { exit({reason}); } class Exception: public std::exception { std::string exceptionCause; public: @@ -60,6 +61,10 @@ namespace Yerbacon { }; } +#include +template +constexpr T& pointerAs(const std::unique_ptr& ptr) { return reinterpret_cast(*ptr); } + #undef YBCON_VERSION #undef YBCON_FLAGS #undef YBCON_COMPILER diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index 2a43270..33c8426 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -89,6 +89,7 @@ public: } return optional>(); }; + inline decltype(*subComponents.data()) operator[](const unsigned int& index) const { return subComponents[index]; } IS(StandardComponents::NamedIdentifier) inline auto operator[](const string& key) const { return findReferenceByName(key); } inline size_t getCompCount() const { return subComponents.size(); } diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index dee17a4..877a869 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -7,18 +7,18 @@ #include #include #include +#include +#include +#include #include "../parsing/ParseComponents.hpp" -#define INCLUDECOMPONENT(X) virtual void on(const X& parseComponent) {} class Target { constexpr static const char* const interpolationString = "${"; constexpr static const char* const interpolationCloseString = "}"; protected: virtual constexpr bool supportsOneLine() { return true; }; std::stringstream output; - INCLUDECOMPONENT(StandardComponents::Define); - INCLUDECOMPONENT(StandardComponents::types::String); inline void stringInterpolation(const char* multiline, const string& view) { stringInterpolation(view, multiline, multiline); } void stringInterpolation(string view, const char* openMultiline = "", const char* closeMultiline = "", const char* concatenationCharacters = "+") { typedef string::size_type strSize; @@ -62,33 +62,38 @@ protected: } } else output << openCharacters << view << closeCharacters << '\n'; } - INCLUDECOMPONENT(StandardComponents::Reference); - INCLUDECOMPONENT(StandardComponents::Class); + typedef function task; + #define make_task(X, L) make_pair(type_index(typeid(X)), [this](const ParseTree& parsedTree, unsigned int& index) { const X& parseComponent = pointerAs(parsedTree[index]); L }) + typedef unordered_map> unordered_task_map; + virtual unordered_task_map getTaskMap() = 0; public: + unordered_task_map& getTaskMapInstance() { + static unordered_task_map staticMap = getTaskMap(); + return staticMap; + }; static shared_ptr forName(string_view name, bool newLines); - - #define with(X) if (id == typeid(X)) { this->on(reinterpret_cast(*component)); continue; } + const bool newLines; string transpileWithTree(const ParseTree& tree) { + const unordered_task_map& taskMap = getTaskMapInstance(); + if (not newLines && !supportsOneLine()) { + throw Yerbacon::Exception("--newlines=off is not supported by the current target"); + } output.str(string()); - for (const unique_ptr& component: tree) { + for (unsigned int i = 0; i < tree.getCompCount(); ++i) { + const unique_ptr& component = tree[i]; const type_info& id = component->getId(); - with(StandardComponents::Define); - with(StandardComponents::types::String); - with(StandardComponents::Reference); - with(StandardComponents::Class); + try { + const optional& currentTask = taskMap.at(id); + if (currentTask.has_value()) currentTask.value()(tree, i); + } catch (const out_of_range&) { + throw Yerbacon::Exception(string(id.name()) += " is not supported by the current target"); + } } return output.str(); }; - #undef with - const bool newLines; explicit Target(const bool newLines): newLines(newLines) {}; virtual ~Target() = default; }; -#undef INCLUDECOMPONENT - -inline string transpile(const ParseTree& tree, const string_view& language, const bool newLines) { - return Target::forName(language, newLines)->transpileWithTree(tree); -} #include "implementations/Lua.hpp" #include "implementations/Js.hpp" @@ -121,10 +126,7 @@ shared_ptr Target::forName(string_view name, const bool newLines = true) default: Yerbacon::exit({"\"", string(1, (char) toupper(name.at(1))).data(), name.substr(2).data(), "\" is not a valid target."}); } #undef ADDTARGET - if (not newLines and not target->supportsOneLine()) { - name.remove_prefix(1); - throw Yerbacon::Exception(string("--newlinesoff cannot be used with --target=") += name); - } + #undef make_task return target; }; diff --git a/src/headers/transpiler/implementations/Js.hpp b/src/headers/transpiler/implementations/Js.hpp index a697b18..0ace39f 100644 --- a/src/headers/transpiler/implementations/Js.hpp +++ b/src/headers/transpiler/implementations/Js.hpp @@ -1,12 +1,15 @@ #ifndef JS_HPP #define JS_HPP JsTarget +using namespace StandardComponents; struct JsTarget: Target { - void on(const StandardComponents::Define& parseComponent) override { - output << (parseComponent.final ? "const " : "let ") << parseComponent.name << " = "; - } - void on(const StandardComponents::types::String& parseComponent) override { - stringInterpolation(parseComponent.content); + unordered_task_map getTaskMap() final { + return { + make_task(Define, + output << (parseComponent.final ? "const " : "let ") << parseComponent.name << " = "; + ), + make_task(types::String, stringInterpolation(parseComponent.content);) + }; } using Target::Target; }; diff --git a/src/headers/transpiler/implementations/Lua.hpp b/src/headers/transpiler/implementations/Lua.hpp index 0dcf2be..556c95b 100644 --- a/src/headers/transpiler/implementations/Lua.hpp +++ b/src/headers/transpiler/implementations/Lua.hpp @@ -1,15 +1,18 @@ #ifndef LUA_HPP #define LUA_HPP LuaTarget +using namespace StandardComponents; struct LuaTarget: Target { - void on(const StandardComponents::Define& parseComponent) override { - if (parseComponent.final) output << "local "; - output << parseComponent.name; - if (parseComponent.final) output << " "; // TODO Find an alternative to for lua <5.4 - output << " = "; - } - void on(const StandardComponents::types::String& parseComponent) override { - stringInterpolation(parseComponent.content, "[[", "]]", ".."); + unordered_task_map getTaskMap() final { + return { + make_task(Define, + if (parseComponent.final) output << "local "; + output << parseComponent.name; + if (parseComponent.final) output << " "; // TODO Find an alternative to for lua <5.4 + output << " = "; + ), + make_task(types::String, stringInterpolation(parseComponent.content, "[[", "]]", "..");) + }; } using Target::Target; }; diff --git a/src/headers/transpiler/implementations/Py.hpp b/src/headers/transpiler/implementations/Py.hpp index aab2640..dc2bf5d 100644 --- a/src/headers/transpiler/implementations/Py.hpp +++ b/src/headers/transpiler/implementations/Py.hpp @@ -1,13 +1,14 @@ #ifndef PY_HPP #define PY_HPP PyTarget +using namespace StandardComponents; struct PyTarget: Target { bool supportsOneLine() final { return false; } - void on(const StandardComponents::Define& parseComponent) override { - output << parseComponent.name << " = "; - } - void on(const StandardComponents::types::String& parseComponent) override { - stringInterpolation(R"(""")", parseComponent.content); + unordered_task_map getTaskMap() final { + return { + make_task(Define, output << parseComponent.name << " = ";), + make_task(types::String, stringInterpolation(R"(""")", parseComponent.content);) + }; } using Target::Target; }; diff --git a/src/main.cpp b/src/main.cpp index 54ff8e1..5d7ad8a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,7 +22,7 @@ int main(int argc, char* argv[]) { else if (currentArg == ArgumentAssignable("target")) { const string_view value = ArgumentAssignable::getValueFor(currentArg); if (not value.empty()) (target = '.') += value; - else Yerbacon::exit({"No target was provided."}); + else Yerbacon::exit("No target was provided."); } else if (currentArg == Argument("parallel")) parallel = true; else if (currentArg == ArgumentAssignable("newlines")) { @@ -45,8 +45,9 @@ int main(int argc, char* argv[]) { } else invalid_argument: Yerbacon::exit({"\"", currentArg.data(), "\" is not a valid argument."}); } } - const auto compile = [&target, &newLines](string_view name) -> string { - string transpiledString = transpile(parseString(getFileContent(name.data())), target, newLines); + const auto currentTarget = Target::forName(target, newLines); + const auto compile = [&target, ¤tTarget](string_view name) -> string { + string transpiledString = currentTarget->transpileWithTree(parseString(getFileContent(name.data()))); name.remove_suffix(6); string outputFile; (outputFile = name).append(target); From 70466cdb8020da3562b4e615753a6f24bb0d1343 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 29 Oct 2021 00:10:49 +0200 Subject: [PATCH 002/254] Demangle the name of components when a GNU/Clang compiler is being used --- src/headers/transpiler/Target.hpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 877a869..5c0693d 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -10,6 +10,9 @@ #include #include #include +#ifdef __GNUC__ +#include +#endif #include "../parsing/ParseComponents.hpp" @@ -86,7 +89,13 @@ public: const optional& currentTask = taskMap.at(id); if (currentTask.has_value()) currentTask.value()(tree, i); } catch (const out_of_range&) { - throw Yerbacon::Exception(string(id.name()) += " is not supported by the current target"); + throw Yerbacon::Exception(string( + #ifndef __GNUC__ + id.name() + #else + abi::__cxa_demangle(id.name(), nullptr, nullptr, nullptr) + #endif + ) += " is not supported by the current target"); } } return output.str(); From 99898da83a770b78189205e93c1ad605a302bc98 Mon Sep 17 00:00:00 2001 From: Username404-59 Date: Sun, 7 Nov 2021 23:44:42 +0100 Subject: [PATCH 003/254] Make the variables in the Jenkinsfile final --- Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 7e2b134..0a2a602 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,5 +1,5 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch', boolean isPackageArchDeb = true, String suffix = '') { - String packageArch = isPackageArchDeb ? debArch : rpmArch; + final String packageArch = isPackageArchDeb ? debArch : rpmArch; // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: "cmake-build-${packageArch}${suffix}", buildType: 'release', cleanBuild: true, installation: 'Latest', cmakeArgs: "--no-warn-unused-cli -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=/usr/bin/${path}-ld.gold -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS_PRIVATE_DIRS=/usr/${path}/lib/ -DNO_CCACHE=ON", @@ -9,7 +9,7 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch cpack installation: 'Latest', workingDir: "cmake-build-${packageArch}${suffix}" } -String windowsSuffix = '-windows' +final String windowsSuffix = '-windows' /* Required Plugins: - CMake From 08661d83a3d3042a63d7cf33005c94bba7aa2750 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 31 Oct 2021 17:02:44 +0100 Subject: [PATCH 004/254] Add an explicit return type to the nextAre function --- src/headers/parsing/Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index a42a2ff..fb9bc0a 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -13,7 +13,7 @@ namespace Parser { using namespace StandardComponents; using enum tok::type; unsigned int i = 0; - const auto nextAre = [&i, &lexed] T>(const initializer_list& nextValues) { + const auto nextAre = [&i, &lexed] T>(const initializer_list& nextValues) -> bool { unsigned int j = 1; for (const T& nextValue: nextValues) { if (!cmp_greater(lexed.size() - i, nextValues.size()) || lexed[i + j].toktype != nextValue) { From c2f70924efabf177425ce92492ee1134fcde44bd Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 9 Nov 2021 20:27:59 +0100 Subject: [PATCH 005/254] Make the check_cxx_compiler_flag invocation lowercase --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7230770..5cc8687 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,7 +56,7 @@ if (${IS_GNU} OR ${IS_CLANG}) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections -fmerge-all-constants -ftree-vectorize") include(CheckCXXCompilerFlag) set(CF_PROTECTION "-fcf-protection") - CHECK_CXX_COMPILER_FLAG("${CF_PROTECTION}" CF_PROTECTION_SUPPORTED) + check_cxx_compiler_flag("${CF_PROTECTION}" CF_PROTECTION_SUPPORTED) if (CF_PROTECTION_SUPPORTED) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CF_PROTECTION}") endif() From d68754451984421fb8b5c355ff60369c7455c235 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 12 Nov 2021 21:18:11 +0100 Subject: [PATCH 006/254] Add interprocedural optimization flags only when they are supported if clang is in use --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5cc8687..bdfbae5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,7 +77,10 @@ elseif(${IS_CLANG}) if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_CLANG}) message(FATAL_ERROR "Clang ${MINIMAL_CLANG} or higher is required.") endif() - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto=full -fwhole-program-vtables -fstrict-vtable-pointers") + if (${CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE} OR MINGW) # CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE is false on llvm-mingw toolchains even though it is supported + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto=full -fwhole-program-vtables") + endif() + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fstrict-vtable-pointers") endif() string(TOUPPER ${CMAKE_BUILD_TYPE} UPPERCASE_BUILD_TYPE) if (UPPERCASE_BUILD_TYPE STREQUAL RELEASE) From fd7ae6197ccfc59edbcc6d39cf9af9e86b9e3cb4 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 12 Nov 2021 21:24:43 +0100 Subject: [PATCH 007/254] Improve the message shown when position-independent code is not supported --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bdfbae5..44e5de4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,11 +22,11 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) include(CheckPIESupported) -check_pie_supported(OUTPUT_VARIABLE pie_output LANGUAGES CXX) -if (NOT CMAKE_CXX_LINK_PIE_SUPPORTED) - message(WARNING "Link-time PIE not supported\n${pie_output}") -else() +check_pie_supported(LANGUAGES CXX) +if (CMAKE_CXX_LINK_PIE_SUPPORTED) set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) +else() + message(NOTICE "Position-Independent Code (PIC) is not supported by the current toolchain") endif() set(CMAKE_CXX_FLAGS "-Wall") set(CMAKE_CXX_FLAGS_RELEASE "-Os") From 30ae9d73699e8c5f95260ee23d33679e8b155837 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 12 Nov 2021 22:20:09 +0100 Subject: [PATCH 008/254] Remove a useless space in main.cpp --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 5d7ad8a..ed11743 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,7 +39,7 @@ int main(int argc, char* argv[]) { if (currentArg == Argument("version")) { cout << Yerbacon::getVersion(); } else if (currentArg == Argument("buildInfo")) { - cout << Yerbacon::getBuildInfo() ; + cout << Yerbacon::getBuildInfo(); } else goto invalid_argument; cout << endl; exit(EXIT_SUCCESS); } else invalid_argument: Yerbacon::exit({"\"", currentArg.data(), "\" is not a valid argument."}); From 458d272088776946b270cebb552f095669ea97f1 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 12 Nov 2021 22:29:46 +0100 Subject: [PATCH 009/254] Only reassign exit_code when it is meant to be EXIT_FAILURE --- src/main.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ed11743..799707d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -80,7 +80,7 @@ int main(int argc, char* argv[]) { }); }); if (printResult) cout << "~~~~[Yerbacon compilation result]~~~~\n\n"; - exit_code = none_of(Units.rbegin(), Units.rend(), [&printResult](future>>& currentFuture) -> bool { + if (any_of(Units.rbegin(), Units.rend(), [&printResult](future>>& currentFuture) -> bool { const auto&& result = currentFuture.get(); const bool is_exception = result.second.has_value(); if (not is_exception) { @@ -93,7 +93,9 @@ int main(int argc, char* argv[]) { cout << "Compilation of " << result.first << " has failed with the following error:\n" << result.second.value().what() << '\n'; } return is_exception; - }) ? EXIT_SUCCESS : EXIT_FAILURE; + })) { + exit_code = EXIT_FAILURE; + } } else cout << "No valid file provided.\n"; return exit_code; } \ No newline at end of file From 37b7cbb16d24f42583b6f33e0ab532cb48d8b4dd Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 21 Nov 2021 13:24:55 +0100 Subject: [PATCH 010/254] Include CMAKE_VERSION in the CPack 3.21.1 warning, just in case the condition needs to be changed in a future version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 44e5de4..696c1ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,7 +139,7 @@ if (UNIX AND NOT MINGW) set(CPACK_RPM_PACKAGE_LICENSE "MPL-2.0") set(CPACK_RPM_CHANGELOG_FILE "${CMAKE_CURRENT_SOURCE_DIR}/changelog") if (CMAKE_VERSION STREQUAL "3.21.1") - message(WARNING "CPack 3.21.1 has a bug that causes rpm scripts to be unusable; please update or downgrade") + message(WARNING "CPack ${CMAKE_VERSION} has a bug which causes rpm scripts to be unusable; please update or downgrade") endif() if (NOT APPLE) set(GZNAME "changelog.Debian.gz") From 3c4586cc7024595344c50cb54e19e8c97f385260 Mon Sep 17 00:00:00 2001 From: Username404-59 Date: Wed, 24 Nov 2021 17:44:44 +0100 Subject: [PATCH 011/254] Add "ASTERISK" and "DIVIDE" token types to lex.hpp, and implement comments --- src/etc/lexer.cpp | 32 ++++++++++++++++++++++++++++---- src/headers/lex.hpp | 8 ++++---- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/etc/lexer.cpp b/src/etc/lexer.cpp index 27a7261..4f92e63 100644 --- a/src/etc/lexer.cpp +++ b/src/etc/lexer.cpp @@ -17,12 +17,37 @@ vector lex(const string& in) const char& current = in[i]; switch (current) { + case DIVIDE: if (in[i + 1] == current) i += 2; else goto insertToken; + case TAG: { + if ((current == TAG && in[i + 1] == DEFINE)) { // See the IDENTIFIER case in Parser.hpp + goto insertToken; + } else { + while (not (in[i + 1] == EOF_ || in[i + 1] == '\n')) { + ++i; + } + break; + } + } + case ASTERISK: { + if ((in.size() - i) > 2 && in[i + 1] == ASTERISK) { + i += 2; + try { + while (not (in.at(i) == ASTERISK && in.at(i + 1) == ASTERISK)) { + lineNumber += (in[i] == '\n'); ++i; + } + ++i; + } catch (const out_of_range&) { + throw tok::LexerException("A never ending comment was found", --lineNumber); + } + break; + } else goto insertToken; + } [[unlikely]] case EOF_: --lineNumber; - case TAG: case DEFINE: case LPAR: case RPAR: + case DEFINE: case LPAR: case RPAR: case LBRACE: case RBRACE: case LBRACKET: case RBRACKET: case PLUS: case HYPHEN: case LCOMP: case RCOMP: case DOT: case DOLLAR_SIGN: case SQUOTE: - resVal.emplace_back(static_cast(current), lineNumber); + insertToken: resVal.emplace_back(static_cast(current), lineNumber); [[likely]] case ' ': case '\t': case '\r': break; [[likely]] case '\n': ++lineNumber; break; default: { @@ -45,8 +70,7 @@ vector lex(const string& in) } } } - case UNEXPECTED: break; - default: resVal.emplace_back(type, string(1, current), lineNumber); + default: break; } break; } diff --git a/src/headers/lex.hpp b/src/headers/lex.hpp index 03767c8..5279a74 100644 --- a/src/headers/lex.hpp +++ b/src/headers/lex.hpp @@ -11,11 +11,11 @@ struct tok { enum type: const unsigned short { UNEXPECTED = std::numeric_limits::max() + 1, IDENTIFIER, NUMBER, ALPHACHAR, EOF_ = '\0', DEFINE = '=', TAG = '#', DOLLAR_SIGN = '$', DOT = '.', - PLUS = '+', LPAR = '(', LBRACE = '{', LBRACKET = '[', RPAR = ')', + LPAR = '(', LBRACE = '{', LBRACKET = '[', RPAR = ')', RBRACE = '}', RBRACKET = ']', - HYPHEN = '-', LCOMP = '>', RCOMP = '<', - SQUOTE = '\'', - STRING = '"', + PLUS = '+', HYPHEN = '-', DIVIDE = '/', + LCOMP = '>', RCOMP = '<', + SQUOTE = '\'', ASTERISK = '*', STRING = '"', }; const type toktype; const std::string toktext; From c9a6a6c918902ea75e42db1badcd9f29df278eb1 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 24 Nov 2021 18:35:54 +0100 Subject: [PATCH 012/254] Remove a useless condition and two unnecessary parentheses in lexer.cpp --- CMakeLists.txt | 3 +++ src/etc/lexer.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 696c1ca..eaa5e97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,9 @@ endif() if (${IS_GNU} OR ${IS_CLANG}) if (NOT MINGW) + if (CMAKE_VERSION STREQUAL "3.22.0") + message(WARNING "CMake ${CMAKE_VERSION} does not support mingw cross-compilers") + endif() include(FindOpenMP) if (OpenMP_CXX_FOUND) set(CMAKE_CXX_FLAGS "${OpenMP_CXX_FLAGS} ${CMAKE_CXX_FLAGS}") diff --git a/src/etc/lexer.cpp b/src/etc/lexer.cpp index 4f92e63..4f01473 100644 --- a/src/etc/lexer.cpp +++ b/src/etc/lexer.cpp @@ -19,7 +19,7 @@ vector lex(const string& in) switch (current) { case DIVIDE: if (in[i + 1] == current) i += 2; else goto insertToken; case TAG: { - if ((current == TAG && in[i + 1] == DEFINE)) { // See the IDENTIFIER case in Parser.hpp + if (current == TAG && in[i + 1] == DEFINE) { // See the IDENTIFIER case in Parser.hpp goto insertToken; } else { while (not (in[i + 1] == EOF_ || in[i + 1] == '\n')) { @@ -29,7 +29,7 @@ vector lex(const string& in) } } case ASTERISK: { - if ((in.size() - i) > 2 && in[i + 1] == ASTERISK) { + if (in[i + 1] == ASTERISK) { i += 2; try { while (not (in.at(i) == ASTERISK && in.at(i + 1) == ASTERISK)) { From a0989730230a8704c6058bdecb87fb3974b123e7 Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 25 Nov 2021 21:38:49 +0100 Subject: [PATCH 013/254] Throw an exception when a final variable is being redefined, and use types instead of auto in the ParseTree::findReferenceByName() method and when calling it in Parser.hpp --- src/headers/parsing/ParseComponents.hpp | 4 ++-- src/headers/parsing/Parser.hpp | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index 33c8426..9d708c0 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -81,8 +81,8 @@ public: } IS(StandardComponents::NamedIdentifier) optional> findReferenceByName(const string& name) const { - auto identifiers = findById(); - for (const auto& identifier: identifiers) { + const vector identifiers = findById(); + for (T* identifier: identifiers) { if (identifier->getId() == typeid(T) && identifier->name == name) { return make_optional(ref(static_cast(*identifier))); } diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index fb9bc0a..f93551d 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -36,6 +36,10 @@ namespace Parser { } else { bool isFinalDefine = nextAre({TAG, DEFINE}); if (isFinalDefine || next.toktype == DEFINE) { + const optional previousDefinition = parseTree.findReferenceByName(current.toktext); + if (previousDefinition.has_value() && previousDefinition.value().get().final) { + throw ParsingException(current.toktext + " cannot be redefined as it is final", current.line); + } parseTree << Define(isFinalDefine, current.toktext); i += 1 + isFinalDefine; } else { From 173ed5d6c33e2bb7e1dd43af8374345b9188b0aa Mon Sep 17 00:00:00 2001 From: Username404-59 Date: Fri, 26 Nov 2021 16:53:14 +0100 Subject: [PATCH 014/254] Add a parsingError() function to Parser.hpp --- src/headers/parsing/Parser.hpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index f93551d..5c331ce 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -8,6 +8,13 @@ namespace Parser { typedef Yerbacon::Exception ParsingException; + void error(const tok& token, const string& text, unsigned long line, const bool& quoteTokenText = false) { + throw ParsingException(quoteTokenText ? "\"" + token.toktext + "\"" + text : text, line); + } + inline void parsingError( + const tok& token, const string& text, + const bool& quoteTokenText = false + ) { error(token, text, token.line, quoteTokenText); } ParseTree parseVector(const vector& lexed) { ParseTree parseTree; using namespace StandardComponents; @@ -32,13 +39,19 @@ namespace Parser { if (current.toktext == "class" || current.toktext == "structure") { if (next.toktype == IDENTIFIER) { parseTree << Class(next.toktext); ++i; - } else throw ParsingException((not (next.toktext.empty() or next.toktype == tok::EOF_)) ? '"' + next.toktext + "\" is not a valid class identifier" : "A class identifier is required", next.line); + } else { + const bool isNotBlank = (not (next.toktext.empty() or next.toktype == tok::EOF_)); + parsingError(next, isNotBlank ? " is not a valid class identifier" + : "A class identifier is required", isNotBlank); + } } else { bool isFinalDefine = nextAre({TAG, DEFINE}); if (isFinalDefine || next.toktype == DEFINE) { const optional previousDefinition = parseTree.findReferenceByName(current.toktext); - if (previousDefinition.has_value() && previousDefinition.value().get().final) { - throw ParsingException(current.toktext + " cannot be redefined as it is final", current.line); + if (previousDefinition.has_value()) { + if (previousDefinition.value().get().final || isFinalDefine) { + parsingError(current, previousDefinition->get().final ? " cannot be redefined as it is final" : " cannot be made final after it has been declared", true); + } } parseTree << Define(isFinalDefine, current.toktext); i += 1 + isFinalDefine; From 158021cf6814f2285e7e118994a17485754443c5 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 26 Nov 2021 21:57:31 +0100 Subject: [PATCH 015/254] Fix the indentation of a line modified by the previous commit --- src/headers/parsing/Parser.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 5c331ce..99875f2 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -41,8 +41,7 @@ namespace Parser { parseTree << Class(next.toktext); ++i; } else { const bool isNotBlank = (not (next.toktext.empty() or next.toktype == tok::EOF_)); - parsingError(next, isNotBlank ? " is not a valid class identifier" - : "A class identifier is required", isNotBlank); + parsingError(next, isNotBlank ? " is not a valid class identifier" : "A class identifier is required", isNotBlank); } } else { bool isFinalDefine = nextAre({TAG, DEFINE}); From 7aae0556518e5ab94f9322c5846f26f201488f66 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 3 Dec 2021 16:14:23 +0100 Subject: [PATCH 016/254] Fix the Jenkinsfile and remove the useless CMake 3.22.0 warning --- CMakeLists.txt | 3 --- Jenkinsfile | 3 ++- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eaa5e97..696c1ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,9 +46,6 @@ endif() if (${IS_GNU} OR ${IS_CLANG}) if (NOT MINGW) - if (CMAKE_VERSION STREQUAL "3.22.0") - message(WARNING "CMake ${CMAKE_VERSION} does not support mingw cross-compilers") - endif() include(FindOpenMP) if (OpenMP_CXX_FOUND) set(CMAKE_CXX_FLAGS "${OpenMP_CXX_FLAGS} ${CMAKE_CXX_FLAGS}") diff --git a/Jenkinsfile b/Jenkinsfile index 0a2a602..01879d2 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,8 +1,9 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch', boolean isPackageArchDeb = true, String suffix = '') { final String packageArch = isPackageArchDeb ? debArch : rpmArch; + final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: "cmake-build-${packageArch}${suffix}", buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=/usr/bin/${path}-ld.gold -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS_PRIVATE_DIRS=/usr/${path}/lib/ -DNO_CCACHE=ON", + cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=/usr/bin/${path}-ld.gold -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS_PRIVATE_DIRS=/usr/${path}/lib/ -DNO_CCACHE=ON", generator: fileExists('/usr/bin/ninja') ? 'Ninja' : 'Unix Makefiles' cmake arguments: "--build ./cmake-build-${packageArch}${suffix} --target ybcon", installation: 'Latest' sh "/usr/bin/${path}-strip -s ./cmake-build-${packageArch}${suffix}/ybcon*" From 0f87742ea8a528395110cf98e94ae538c0900cfa Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 3 Dec 2021 16:54:23 +0100 Subject: [PATCH 017/254] Use the CMAKE_HOST_WIN32 variable instead of win32 to fix building with a reassigned CMAKE_SYSTEM_NAME --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 696c1ca..81bdbcc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -200,7 +200,7 @@ elseif(MINGW OR MSVC) set(CPACK_TOPLEVEL_TAG "Win32") set(CPACK_NSIS_MODIFY_PATH ON) set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON) - if (WIN32) + if (CMAKE_HOST_WIN32) # The two following variables require CMake 3.20 or higher set(CPACK_NSIS_BRANDING_TEXT "NSIS Installer for the yerbacon compiler") set(CPACK_NSIS_BRANDING_TEXT_TRIM_POSITION CENTER) From e679f0bd429692e690d2a44ea40777a8d7c52109 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 3 Dec 2021 20:12:34 +0100 Subject: [PATCH 018/254] Use Yerbacon.svg instead of Yerbacon.png in the README.md file --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f11a1b..138723a 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://ci.username404.fr/buildStatus/icon?style=plastic)](https://ci.username404.fr/job/Yerbacon/job/stable/) -Yerbacon logo +Yerbacon logo Aka Yer Bacon, - #### A language that transpiles into lua, javascript (ES6) or python code. From 2e14746ada93a5946ba64bda74be517c741a7c7a Mon Sep 17 00:00:00 2001 From: Username404-59 Date: Tue, 14 Dec 2021 13:31:24 +0100 Subject: [PATCH 019/254] Fix a condition used to determine if windows/mingw is in use --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 81bdbcc..0c1813e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,7 +123,7 @@ target_precompile_headers(${EXENAME} PRIVATE src/headers/Yerbacon.hpp) # lpkg = linux package, wpkg = windows package set(PNAME ${PROJECT_NAME}-${CODENAME}-${TIME}) -if (UNIX AND NOT MINGW) +if (UNIX AND NOT (MINGW OR CMAKE_HOST_WIN32)) include(GNUInstallDirs) set(CMAKE_INSTALL_PREFIX "/usr") set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") From 9a763b38cf052dddc8edc52c68d51da8376ea61b Mon Sep 17 00:00:00 2001 From: Username404-59 Date: Wed, 15 Dec 2021 13:20:46 +0100 Subject: [PATCH 020/254] Fix the UPPERCASE_BUILD_TYPE variable to make the CMakeLists.txt file compatible with multi-config generators --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c1813e..018fdd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,7 +82,7 @@ elseif(${IS_CLANG}) endif() set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fstrict-vtable-pointers") endif() -string(TOUPPER ${CMAKE_BUILD_TYPE} UPPERCASE_BUILD_TYPE) +string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPERCASE_BUILD_TYPE) if (UPPERCASE_BUILD_TYPE STREQUAL RELEASE) add_definitions(-DYBCON_FLAGS="${CMAKE_CXX_FLAGS_RELEASE}") endif() From f266c35954c1e78d782fd39ac2d0e6df0bc46270 Mon Sep 17 00:00:00 2001 From: Username404-59 Date: Wed, 15 Dec 2021 13:31:39 +0100 Subject: [PATCH 021/254] Use the size_t type instead of "unsigned long" for variables that hold the result of a find() call --- src/headers/arguments.hpp | 2 +- src/main.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/headers/arguments.hpp b/src/headers/arguments.hpp index 096928d..bbcd4c9 100644 --- a/src/headers/arguments.hpp +++ b/src/headers/arguments.hpp @@ -26,7 +26,7 @@ class ArgumentAssignable: public Argument { vector values; public: static string_view getValueFor(const string_view& str) { - unsigned long definePos = str.find_last_of('=') + 1; + const size_t definePos = str.find_last_of('=') + 1; return str.size() > definePos ? str.substr(definePos) : string_view(); } ArgumentAssignable(string name, const span& possibleValues): Argument(move(name)), values() { diff --git a/src/main.cpp b/src/main.cpp index 799707d..2d44c21 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -64,11 +64,11 @@ int main(int argc, char* argv[]) { try { resultingPair.first = compile(fileName); } catch (const Yerbacon::Exception& error) { - unsigned long lastSlash = 0; - const unsigned long position1 = fileName.find_last_of('/'); + size_t lastSlash = 0; + const size_t position1 = fileName.find_last_of('/'); if (cmp_not_equal(position1, string_view::npos)) lastSlash = position1; if constexpr(filesystem::path::preferred_separator != '/') { - const unsigned long position2 = fileName.find_last_of(filesystem::path::preferred_separator); + const size_t position2 = fileName.find_last_of(filesystem::path::preferred_separator); if (cmp_not_equal(position2, string_view::npos)) { lastSlash = max(lastSlash, position2); } From d2c0ef185fb008f41ab7be673ff0fd54700fd0da Mon Sep 17 00:00:00 2001 From: Username404-59 Date: Wed, 15 Dec 2021 14:34:41 +0100 Subject: [PATCH 022/254] Add the C++ standard to the getBuildInfo() function by adding two new macros: "token_expansion" and "make_string" --- src/headers/Yerbacon.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/headers/Yerbacon.hpp b/src/headers/Yerbacon.hpp index ae98e42..adb5abd 100644 --- a/src/headers/Yerbacon.hpp +++ b/src/headers/Yerbacon.hpp @@ -26,6 +26,9 @@ #error "The "using enum" syntax is not supported by this compiler" #endif +#define token_expansion(X) #X +#define make_string(X) token_expansion(X) + #include #include #include @@ -38,7 +41,8 @@ namespace Yerbacon { consteval const char* getBuildInfo() noexcept { return "Build info:\n" " Optimization flags: " YBCON_FLAGS "\n" - " Compiler: " YBCON_COMPILER; + " Compiler: " YBCON_COMPILER "\n" + " C++ standard: " make_string(__cplusplus); } static void exit(const std::initializer_list reason) { std::for_each(reason.begin(), reason.end(), [](const char* current_string){ From 4365da0daf8a1241ec750887f40332d3680f3e6a Mon Sep 17 00:00:00 2001 From: Username404-59 Date: Wed, 15 Dec 2021 16:29:52 +0100 Subject: [PATCH 023/254] Add MSVC specific flags --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 018fdd1..65fa0a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,6 +81,8 @@ elseif(${IS_CLANG}) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto=full -fwhole-program-vtables") endif() set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fstrict-vtable-pointers") +elseif(MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /Zc:__cplusplus") endif() string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPERCASE_BUILD_TYPE) if (UPPERCASE_BUILD_TYPE STREQUAL RELEASE) From e720ff0f2dac04a55d52e8894cfaaa34d8249cb1 Mon Sep 17 00:00:00 2001 From: Username404-59 Date: Wed, 15 Dec 2021 17:25:39 +0100 Subject: [PATCH 024/254] Add an error message when an exception is thrown from the getFileContent() function & --parallel is not in use, and support MSVC --- src/etc/filefuncs.cpp | 5 +++-- src/headers/Yerbacon.hpp | 5 +++++ src/headers/misc.hpp | 2 +- src/headers/parsing/ParseComponents.hpp | 2 +- src/main.cpp | 4 ++-- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/etc/filefuncs.cpp b/src/etc/filefuncs.cpp index 227662b..2e81c9d 100644 --- a/src/etc/filefuncs.cpp +++ b/src/etc/filefuncs.cpp @@ -1,14 +1,15 @@ #include #include +#include using namespace std; -string getFileContent(const string& file) +string getFileContent(const string& file, const bool& parallel) { ifstream fileStream(file, ios::in); string lineinput, fullinput; if (fileStream.is_open()) while (getline(fileStream, lineinput)) { fullinput.append(lineinput += '\n'); - } else throw Yerbacon::Exception("Could not open \"" + file + "\"."); + } else throw Yerbacon::Exception("Could not open \"" + file + "\"" + ((not parallel) ? string(" : ").append(strerror(errno)) : ".")); // TODO: Use a thread-safe function when the parallel mode is in use fileStream.close(); return fullinput; } diff --git a/src/headers/Yerbacon.hpp b/src/headers/Yerbacon.hpp index adb5abd..b1c09f2 100644 --- a/src/headers/Yerbacon.hpp +++ b/src/headers/Yerbacon.hpp @@ -18,6 +18,11 @@ #error "A valid std::threads implementation is required" #endif +#ifdef _MSC_VER +// #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 +#define _CRT_SECURE_NO_WARNINGS 1 +#endif + #include #if not defined(__cpp_lib_concepts) || not defined(__cpp_lib_integer_comparison_functions) #error "The current standard library is incomplete" diff --git a/src/headers/misc.hpp b/src/headers/misc.hpp index 0962dee..75ab17b 100644 --- a/src/headers/misc.hpp +++ b/src/headers/misc.hpp @@ -1,7 +1,7 @@ #ifndef YERBACON_MISC_HPP #define YERBACON_MISC_HPP -string getFileContent(const string& file); +string getFileContent(const string& file, const bool& parallel); void outputFileContent(const string& file, string_view content); #include "lex.hpp" diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index 9d708c0..71c168a 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -16,7 +16,7 @@ using namespace std; #include #define IS(X) template T = X> struct ParseComponent { - [[nodiscard]] constexpr const type_info& getId() const { return typeid(*this); } + [[nodiscard]] inline const type_info& getId() const { return typeid(*this); } virtual ~ParseComponent() = default; }; diff --git a/src/main.cpp b/src/main.cpp index 2d44c21..2fb3f81 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,8 +46,8 @@ int main(int argc, char* argv[]) { } } const auto currentTarget = Target::forName(target, newLines); - const auto compile = [&target, ¤tTarget](string_view name) -> string { - string transpiledString = currentTarget->transpileWithTree(parseString(getFileContent(name.data()))); + const auto compile = [&target, ¤tTarget, ¶llel](string_view name) -> string { + string transpiledString = currentTarget->transpileWithTree(parseString(getFileContent(name.data(), parallel))); name.remove_suffix(6); string outputFile; (outputFile = name).append(target); From 5f2c83c99729430198691f5410c2a055b042434a Mon Sep 17 00:00:00 2001 From: Username404-59 Date: Thu, 16 Dec 2021 13:06:01 +0100 Subject: [PATCH 025/254] Don't generate a new manifest file on MSVC compilers --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 65fa0a5..ab75387 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,6 +83,7 @@ elseif(${IS_CLANG}) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fstrict-vtable-pointers") elseif(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /Zc:__cplusplus") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") endif() string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPERCASE_BUILD_TYPE) if (UPPERCASE_BUILD_TYPE STREQUAL RELEASE) From eb586a28994fc61ff416c44d0e15f1129e2056cb Mon Sep 17 00:00:00 2001 From: Username404 Date: Mon, 20 Dec 2021 19:18:07 +0100 Subject: [PATCH 026/254] Use generic_category::message() instead of strerror() in filefuncs.cpp --- src/etc/filefuncs.cpp | 16 +++++++++------- src/headers/Yerbacon.hpp | 5 ----- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/etc/filefuncs.cpp b/src/etc/filefuncs.cpp index 2e81c9d..c556747 100644 --- a/src/etc/filefuncs.cpp +++ b/src/etc/filefuncs.cpp @@ -1,17 +1,19 @@ #include #include -#include +#include using namespace std; string getFileContent(const string& file, const bool& parallel) { ifstream fileStream(file, ios::in); - string lineinput, fullinput; - if (fileStream.is_open()) while (getline(fileStream, lineinput)) { - fullinput.append(lineinput += '\n'); - } else throw Yerbacon::Exception("Could not open \"" + file + "\"" + ((not parallel) ? string(" : ").append(strerror(errno)) : ".")); // TODO: Use a thread-safe function when the parallel mode is in use - fileStream.close(); - return fullinput; + if (not fileStream.fail()) { + string lineinput, fullinput; + while (getline(fileStream, lineinput)) { + fullinput.append(lineinput += '\n'); + } + fileStream.close(); + return fullinput; + } else throw Yerbacon::Exception("Could not open \"" + file + "\" : " + generic_category().message(errno)); } void outputFileContent(const string& file, const string_view content) { diff --git a/src/headers/Yerbacon.hpp b/src/headers/Yerbacon.hpp index b1c09f2..adb5abd 100644 --- a/src/headers/Yerbacon.hpp +++ b/src/headers/Yerbacon.hpp @@ -18,11 +18,6 @@ #error "A valid std::threads implementation is required" #endif -#ifdef _MSC_VER -// #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 -#define _CRT_SECURE_NO_WARNINGS 1 -#endif - #include #if not defined(__cpp_lib_concepts) || not defined(__cpp_lib_integer_comparison_functions) #error "The current standard library is incomplete" From b16f974eacc22f27880d4ad74d6c909c5d0e19c7 Mon Sep 17 00:00:00 2001 From: Username404 Date: Mon, 20 Dec 2021 19:39:44 +0100 Subject: [PATCH 027/254] Use the system-wide locale --- src/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.cpp b/src/main.cpp index 2fb3f81..34a81b4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,7 @@ using namespace std; #include "headers/transpiler/Target.hpp" int main(int argc, char* argv[]) { + setlocale(LC_ALL, ""); string target = ".lua"; bool printResult = false, parallel = false, From 609567cfd1db97f5361744764f805a70be9c6aad Mon Sep 17 00:00:00 2001 From: Username404 Date: Mon, 20 Dec 2021 20:31:54 +0100 Subject: [PATCH 028/254] Add a "unit" alias to main.cpp --- src/main.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 34a81b4..0663e37 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -57,7 +57,8 @@ int main(int argc, char* argv[]) { }; int8_t exit_code = EXIT_SUCCESS; if (!files.empty()) { - vector>>> Units(files.size()); + using unit = future>>; + vector Units(files.size()); const launch& Policy = not parallel ? launch::deferred : launch::async; transform(files.cbegin(), files.cend(), Units.begin(), [&Policy, &compile](const string_view& fileName){ return async(Policy, [&fileName, &compile]() { @@ -81,8 +82,8 @@ int main(int argc, char* argv[]) { }); }); if (printResult) cout << "~~~~[Yerbacon compilation result]~~~~\n\n"; - if (any_of(Units.rbegin(), Units.rend(), [&printResult](future>>& currentFuture) -> bool { - const auto&& result = currentFuture.get(); + if (any_of(Units.rbegin(), Units.rend(), [&printResult](unit& currentFuture) -> bool { + const pair result = currentFuture.get(); const bool is_exception = result.second.has_value(); if (not is_exception) { if (printResult && !(result.first.empty() || all_of(result.first.begin(), result.first.end(), [](const char& character){ From cb8e81895643a5073a146bdfd1824b254133271e Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 21 Dec 2021 17:06:29 +0100 Subject: [PATCH 029/254] Add shared tasks to Target.hpp --- src/headers/transpiler/Target.hpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 5c0693d..cac1243 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -66,12 +66,19 @@ protected: } else output << openCharacters << view << closeCharacters << '\n'; } typedef function task; - #define make_task(X, L) make_pair(type_index(typeid(X)), [this](const ParseTree& parsedTree, unsigned int& index) { const X& parseComponent = pointerAs(parsedTree[index]); L }) + #define make_task_base(type, captures, function_body) make_pair(type_index(typeid(type)), [captures](const ParseTree& parsedTree, unsigned int& index) { const type& parseComponent = pointerAs(parsedTree[index]); function_body }) + #define make_task(T, F) make_task_base(T, this, F) typedef unordered_map> unordered_task_map; virtual unordered_task_map getTaskMap() = 0; public: - unordered_task_map& getTaskMapInstance() { + const unordered_task_map& getTaskMapInstance() { static unordered_task_map staticMap = getTaskMap(); + // Default / Shared tasks: + staticMap.merge(unordered_task_map({ + make_task(StandardComponents::Reference, + output << parseComponent.name; + ) + })); return staticMap; }; static shared_ptr forName(string_view name, bool newLines); From 106a2f0be9274130cf2a1a5b30ee30f974d7aa12 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 21 Dec 2021 19:47:31 +0100 Subject: [PATCH 030/254] Remove a useless semicolon in Target.hpp --- src/headers/transpiler/Target.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index cac1243..907e629 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -144,6 +144,6 @@ shared_ptr Target::forName(string_view name, const bool newLines = true) #undef ADDTARGET #undef make_task return target; -}; +} #endif //YERBACON_TARGET_HPP \ No newline at end of file From 96efa6b0fb74b3613161358426a6465916f5c6da Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 21 Dec 2021 19:47:53 +0100 Subject: [PATCH 031/254] Enable threads only when they are available, and replace "ybcon" occurrences with "${EXENAME}" in the CMakeLists.txt file --- CMakeLists.txt | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ab75387..7a2bd15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,15 +44,17 @@ if (NOT NO_CCACHE) endif() endif() +find_package(Threads) if (${IS_GNU} OR ${IS_CLANG}) - if (NOT MINGW) + set(THREADS_PREFER_PTHREAD_FLAG TRUE) + if (Threads_FOUND AND NOT MINGW) include(FindOpenMP) if (OpenMP_CXX_FOUND) set(CMAKE_CXX_FLAGS "${OpenMP_CXX_FLAGS} ${CMAKE_CXX_FLAGS}") add_definitions(-D_GLIBCXX_PARALLEL) endif() endif() - set(CMAKE_CXX_FLAGS "-pthread ${CMAKE_CXX_FLAGS} -fstrict-enums -pipe -fstack-protector-strong -fstack-clash-protection -funwind-tables -fasynchronous-unwind-tables -frtti -fexceptions") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstrict-enums -pipe -fstack-protector-strong -fstack-clash-protection -funwind-tables -fasynchronous-unwind-tables -frtti -fexceptions") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections -fmerge-all-constants -ftree-vectorize") include(CheckCXXCompilerFlag) set(CF_PROTECTION "-fcf-protection") @@ -69,7 +71,10 @@ if (${IS_GNU}) if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_GNU}) message(FATAL_ERROR "G++ ${MINIMAL_GNU} or higher is required.") endif() - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvect-cost-model=unlimited -foptimize-strlen -fsched-pressure -flive-range-shrinkage -fpredictive-commoning -ftree-partial-pre -fzero-call-used-regs=used-gpr-arg -ftree-parallelize-loops=2 -fira-loop-pressure -ftree-loop-distribution -floop-interchange -fsplit-paths -fgcse-las -fgcse-sm -fipa-pta -fstdarg-opt -fivopts") + if (Threads_FOUND) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ftree-parallelize-loops=2") + endif() + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvect-cost-model=unlimited -foptimize-strlen -fsched-pressure -flive-range-shrinkage -fpredictive-commoning -ftree-partial-pre -fzero-call-used-regs=used-gpr-arg -fira-loop-pressure -ftree-loop-distribution -floop-interchange -fsplit-paths -fgcse-las -fgcse-sm -fipa-pta -fstdarg-opt -fivopts") if (${CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE}) set(CMAKE_CXX_FLAGS_RELEASE "-fwhole-program ${CMAKE_CXX_FLAGS_RELEASE}") endif() @@ -121,8 +126,11 @@ set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${CMAKE_PROJECT_VERSION}-${TIME}") include_directories(${CMAKE_CURRENT_LIST_DIR}) add_executable(${EXENAME} src/main.cpp ${CMAKE_CURRENT_BINARY_DIR}/processed/${PROJECT_NAME}.rc src/etc/filefuncs.cpp src/etc/lexer.cpp src/headers/lex.hpp src/headers/misc.hpp src/headers/parsing/ParseComponents.hpp src/headers/transpiler/Target.hpp src/headers/transpiler/implementations/Lua.hpp src/headers/transpiler/implementations/Js.hpp src/headers/transpiler/implementations/Py.hpp src/headers/parsing/Parser.hpp src/headers/arguments.hpp) -target_compile_definitions(ybcon PRIVATE YBCON_VERSION="${CODENAME} ${PROJECT_VERSION}") +target_compile_definitions(${EXENAME} PRIVATE YBCON_VERSION="${CODENAME} ${PROJECT_VERSION}") target_precompile_headers(${EXENAME} PRIVATE src/headers/Yerbacon.hpp) +if (Threads_FOUND) + target_link_libraries(${EXENAME} PRIVATE Threads::Threads) +endif() # lpkg = linux package, wpkg = windows package set(PNAME ${PROJECT_NAME}-${CODENAME}-${TIME}) @@ -154,7 +162,7 @@ if (UNIX AND NOT (MINGW OR CMAKE_HOST_WIN32)) COMMENT "Compressing the changelog file" ) add_custom_target(changelog ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${GZNAME}") - add_dependencies(ybcon changelog) + add_dependencies(${EXENAME} changelog) string(TOLOWER "${CMAKE_INSTALL_DOCDIR}" DEB_CHANGELOG_DEST_DIR) # Lowercase characters are needed because GNUInstallDirs uses the PROJECT_NAME variable. install( FILES "${CMAKE_CURRENT_BINARY_DIR}/${GZNAME}" @@ -177,10 +185,10 @@ if (UNIX AND NOT (MINGW OR CMAKE_HOST_WIN32)) set(CPACK_GENERATOR TGZ;STGZ;RPM;DEB) endif() install(PROGRAMS - ${CMAKE_CURRENT_BINARY_DIR}/ybcon + ${CMAKE_CURRENT_BINARY_DIR}/${EXENAME} DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}) - install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/scripts/completions DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/ybcon.d) - install(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/ybcon + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/scripts/completions DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${EXENAME}.d) + install(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/${EXENAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() elseif(MINGW OR MSVC) @@ -211,7 +219,7 @@ elseif(MINGW OR MSVC) # CMake 3.22+ is required to ignore the NSIS license page set(CPACK_NSIS_IGNORE_LICENSE_PAGE TRUE) set(CPACK_GENERATOR ZIP;NSIS) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ybcon.exe DESTINATION bin) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${EXENAME}.exe DESTINATION bin) endif() if (NOT DEFINED CXX_TARGET) set(CXX_TARGET ${CMAKE_HOST_SYSTEM_PROCESSOR}) From f44cceb11a4fe361339f48c6d2f1bdc1dac65793 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 22 Dec 2021 20:37:55 +0100 Subject: [PATCH 032/254] Ignore ';' characters --- src/etc/lexer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/lexer.cpp b/src/etc/lexer.cpp index 4f01473..6026624 100644 --- a/src/etc/lexer.cpp +++ b/src/etc/lexer.cpp @@ -48,7 +48,7 @@ vector lex(const string& in) case PLUS: case HYPHEN: case LCOMP: case RCOMP: case DOT: case DOLLAR_SIGN: case SQUOTE: insertToken: resVal.emplace_back(static_cast(current), lineNumber); - [[likely]] case ' ': case '\t': case '\r': break; + [[likely]] case ' ': case '\t': case '\r': case ';': break; [[likely]] case '\n': ++lineNumber; break; default: { const tok::type type = getIdentifierCharType(current); From 1082bcf58f9608a22f6f1ff5085574009a148ad8 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 22 Dec 2021 20:38:08 +0100 Subject: [PATCH 033/254] Allow "_" characters in identifiers --- src/etc/lexer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/lexer.cpp b/src/etc/lexer.cpp index 6026624..09024da 100644 --- a/src/etc/lexer.cpp +++ b/src/etc/lexer.cpp @@ -3,7 +3,7 @@ using namespace std; using enum tok::type; tok::type getIdentifierCharType(const char& Char) { - if (isalpha(Char)) return IDENTIFIER; + if (isalpha(Char) || Char == '_') return IDENTIFIER; else if (isdigit(Char)) return NUMBER; else if (Char == STRING) return STRING; else return UNEXPECTED; From 5580b8f2045baf74151bad0f3ef06d75375f6709 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 22 Dec 2021 20:38:36 +0100 Subject: [PATCH 034/254] Remove redundant optional usage in Target.hpp --- src/headers/transpiler/Target.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 907e629..8d3f6b2 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -68,7 +68,7 @@ protected: typedef function task; #define make_task_base(type, captures, function_body) make_pair(type_index(typeid(type)), [captures](const ParseTree& parsedTree, unsigned int& index) { const type& parseComponent = pointerAs(parsedTree[index]); function_body }) #define make_task(T, F) make_task_base(T, this, F) - typedef unordered_map> unordered_task_map; + typedef unordered_map unordered_task_map; virtual unordered_task_map getTaskMap() = 0; public: const unordered_task_map& getTaskMapInstance() { @@ -93,8 +93,8 @@ public: const unique_ptr& component = tree[i]; const type_info& id = component->getId(); try { - const optional& currentTask = taskMap.at(id); - if (currentTask.has_value()) currentTask.value()(tree, i); + const task& currentTask = taskMap.at(id); + currentTask(tree, i); } catch (const out_of_range&) { throw Yerbacon::Exception(string( #ifndef __GNUC__ From c25748cf8791bc010828310177bf75f942d36c2b Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 22 Dec 2021 20:53:35 +0100 Subject: [PATCH 035/254] Rename the "println" function to "print_line" and fix HelloWorld.ybcon --- docs/gettingstarted.md | 8 ++++---- examples/HelloWorld.ybcon | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/gettingstarted.md b/docs/gettingstarted.md index 614d0cf..42fdc0e 100644 --- a/docs/gettingstarted.md +++ b/docs/gettingstarted.md @@ -34,14 +34,14 @@ as_main helloWorld >> {} Parameters can be added to an anonymous function by specifying the types as follows: ``` addIntToString (int, String) => { a, b; - println(b + a) + print_line(b + a) } ``` Named functions can have parameters **(with mandatory names)** like in this example: ``` addIntToString(a: Int, b: String) => { - println(b + a) + print_line(b + a) } ``` @@ -53,14 +53,14 @@ helloWorld() If a function does have parameters, you can call it with arguments in the right order; if the function is not anonymous, it's also possible to call it by using the names of the corresponding parameters: ``` addNumbers(int a, int b, int c, int d) >> { - println(a + b + c + d) + print_line(a + b + c + d) } addNumbers(1, 2, 3, 4) # Call without names addNumbers(a = 1, b = 2, c = 3, d = 4) # Call with names addNumbers(1, c = 3, b = 2, d = 4) ``` -Note that print and println are the functions that will get transpiled to their equivalents. +Note that print and print_line are the only functions that will get transpiled to their equivalents. ## 3 - Types Types are *inferred*, which means that specifying types of variables or returned values is optional. diff --git a/examples/HelloWorld.ybcon b/examples/HelloWorld.ybcon index e951080..17413c2 100644 --- a/examples/HelloWorld.ybcon +++ b/examples/HelloWorld.ybcon @@ -1,3 +1,3 @@ main #= [] -> { - println "Hello, World!" + print_line("Hello, World!") } From f90514ba4bc7995594a4c505c1999e2d3c5a3bb8 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 22 Dec 2021 21:01:14 +0100 Subject: [PATCH 036/254] Remove the include directive in Target.hpp since it is now useless --- src/headers/transpiler/Target.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 8d3f6b2..82c685a 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -9,7 +9,6 @@ #include #include #include -#include #ifdef __GNUC__ #include #endif From a078fcd07bc3c10ac7341c133a58dfe6c72d5b8a Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 24 Dec 2021 15:53:51 +0100 Subject: [PATCH 037/254] Output errors to clog instead of cout --- src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 0663e37..edaf6b7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -92,7 +92,8 @@ int main(int argc, char* argv[]) { cout << result.first << '\n'; } } else { - cout << "Compilation of " << result.first << " has failed with the following error:\n" << result.second.value().what() << '\n'; + cout << "Compilation of " << result.first << " has failed with the following error:\n"; + clog << result.second.value().what() << '\n'; } return is_exception; })) { From 18daa6495c5bb85c8df7ab9dc9cf1cf5c0c8ef29 Mon Sep 17 00:00:00 2001 From: Username404-59 Date: Sat, 25 Dec 2021 18:34:39 +0100 Subject: [PATCH 038/254] Use cerr instead of clog to make sure cout has been flushed before errors get displayed --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index edaf6b7..e25f8d6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -93,7 +93,7 @@ int main(int argc, char* argv[]) { } } else { cout << "Compilation of " << result.first << " has failed with the following error:\n"; - clog << result.second.value().what() << '\n'; + cerr << result.second.value().what() << '\n'; } return is_exception; })) { From 4253d5b922f43397efcb0672af0196e7a2f38d7f Mon Sep 17 00:00:00 2001 From: Username404-59 Date: Sat, 25 Dec 2021 18:38:16 +0100 Subject: [PATCH 039/254] Remove redundant usage of endl in main.cpp --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index e25f8d6..cb3e783 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -42,7 +42,7 @@ int main(int argc, char* argv[]) { } else if (currentArg == Argument("buildInfo")) { cout << Yerbacon::getBuildInfo(); } else goto invalid_argument; - cout << endl; exit(EXIT_SUCCESS); + cout << '\n'; exit(EXIT_SUCCESS); } else invalid_argument: Yerbacon::exit({"\"", currentArg.data(), "\" is not a valid argument."}); } } From 19f76c405c3b51b8d9d8625ffd7701ec4c12ef7e Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 26 Dec 2021 14:53:37 +0100 Subject: [PATCH 040/254] Remove a useless constructor in lex.hpp --- src/headers/lex.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/headers/lex.hpp b/src/headers/lex.hpp index 5279a74..c2eb211 100644 --- a/src/headers/lex.hpp +++ b/src/headers/lex.hpp @@ -21,8 +21,7 @@ struct tok { const std::string toktext; const unsigned long line = 0; tok(type Type, std::string_view Text, decltype(line) line): toktype(Type), toktext(Text), line(line) {} - explicit tok(type Type, const char& character, decltype(line) line): tok(Type, std::string(1, character), line) {}; - inline tok(type Type, decltype(line) line): tok(Type, Type, line) {}; + explicit tok(type Type, decltype(line) line): tok(Type, std::string(1, Type), line) {}; friend std::ostream& operator<<(std::ostream& output, const tok& it) { return output << it.toktext; } }; std::vector lex(const std::string& in); From b185a7e0cf83de163d4b0687482ee1153c6cf00a Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 26 Dec 2021 14:56:06 +0100 Subject: [PATCH 041/254] Fix the case of int in the 2.2 section of docs/gettingstarted.md --- docs/gettingstarted.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/gettingstarted.md b/docs/gettingstarted.md index 42fdc0e..6fb4a38 100644 --- a/docs/gettingstarted.md +++ b/docs/gettingstarted.md @@ -40,7 +40,7 @@ addIntToString (int, String) => { a, b; Named functions can have parameters **(with mandatory names)** like in this example: ``` -addIntToString(a: Int, b: String) => { +addIntToString(a: int, b: String) => { print_line(b + a) } ``` From cf4ea8a1f8ae02578a69e92d5cf304ad79ce99a2 Mon Sep 17 00:00:00 2001 From: Username404 Date: Mon, 27 Dec 2021 21:46:25 +0100 Subject: [PATCH 042/254] Improve the tok constructors --- src/headers/lex.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/headers/lex.hpp b/src/headers/lex.hpp index c2eb211..fcb73fe 100644 --- a/src/headers/lex.hpp +++ b/src/headers/lex.hpp @@ -19,9 +19,9 @@ struct tok { }; const type toktype; const std::string toktext; - const unsigned long line = 0; - tok(type Type, std::string_view Text, decltype(line) line): toktype(Type), toktext(Text), line(line) {} - explicit tok(type Type, decltype(line) line): tok(Type, std::string(1, Type), line) {}; + const unsigned long line; + tok(const type& Type, std::string_view Text, const decltype(line)& line = 0): toktype(Type), toktext(Text), line(line) {} + explicit tok(const type& Type, const decltype(line)& line = 0): tok(Type, std::string(1, Type), line) {}; friend std::ostream& operator<<(std::ostream& output, const tok& it) { return output << it.toktext; } }; std::vector lex(const std::string& in); From 96dd67b69a5fc22f434e62918635919c85d86522 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 28 Dec 2021 09:39:46 +0100 Subject: [PATCH 043/254] Remove a useless #include directive in lex.hpp --- src/headers/lex.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/headers/lex.hpp b/src/headers/lex.hpp index fcb73fe..e00b19d 100644 --- a/src/headers/lex.hpp +++ b/src/headers/lex.hpp @@ -1,7 +1,6 @@ #ifndef YERBACON_LEX_H #define YERBACON_LEX_H -#include #include "Yerbacon.hpp" #include #include From eb709e60b0aff3e2109bf9b2cab95799c16dd41d Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 28 Dec 2021 10:20:25 +0100 Subject: [PATCH 044/254] Remove the (now useless) parallel parameter in the getFileContent() function from filefuncs.cpp --- src/etc/filefuncs.cpp | 2 +- src/headers/misc.hpp | 2 +- src/main.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/etc/filefuncs.cpp b/src/etc/filefuncs.cpp index c556747..c33cba1 100644 --- a/src/etc/filefuncs.cpp +++ b/src/etc/filefuncs.cpp @@ -3,7 +3,7 @@ #include using namespace std; -string getFileContent(const string& file, const bool& parallel) +string getFileContent(const string& file) { ifstream fileStream(file, ios::in); if (not fileStream.fail()) { diff --git a/src/headers/misc.hpp b/src/headers/misc.hpp index 75ab17b..0962dee 100644 --- a/src/headers/misc.hpp +++ b/src/headers/misc.hpp @@ -1,7 +1,7 @@ #ifndef YERBACON_MISC_HPP #define YERBACON_MISC_HPP -string getFileContent(const string& file, const bool& parallel); +string getFileContent(const string& file); void outputFileContent(const string& file, string_view content); #include "lex.hpp" diff --git a/src/main.cpp b/src/main.cpp index cb3e783..e70da8c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,8 +47,8 @@ int main(int argc, char* argv[]) { } } const auto currentTarget = Target::forName(target, newLines); - const auto compile = [&target, ¤tTarget, ¶llel](string_view name) -> string { - string transpiledString = currentTarget->transpileWithTree(parseString(getFileContent(name.data(), parallel))); + const auto compile = [&target, ¤tTarget](string_view name) -> string { + string transpiledString = currentTarget->transpileWithTree(parseString(getFileContent(name.data()))); name.remove_suffix(6); string outputFile; (outputFile = name).append(target); From afeeaa260f7c43d88f2fabd479e7a1987a96c8a9 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 29 Dec 2021 19:11:43 +0100 Subject: [PATCH 045/254] Actually flush cout before displaying errors --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index e70da8c..0b249ba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -92,7 +92,7 @@ int main(int argc, char* argv[]) { cout << result.first << '\n'; } } else { - cout << "Compilation of " << result.first << " has failed with the following error:\n"; + cout << "Compilation of " << result.first << " has failed with the following error:" << endl; cerr << result.second.value().what() << '\n'; } return is_exception; From 070189e4a0e84ebbfc40c6ae477b9a25a9f1f12c Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 29 Dec 2021 19:19:23 +0100 Subject: [PATCH 046/254] Check whether failbit or badbit are set in filefuncs.cpp --- src/etc/filefuncs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/filefuncs.cpp b/src/etc/filefuncs.cpp index c33cba1..b7f44f7 100644 --- a/src/etc/filefuncs.cpp +++ b/src/etc/filefuncs.cpp @@ -6,7 +6,7 @@ using namespace std; string getFileContent(const string& file) { ifstream fileStream(file, ios::in); - if (not fileStream.fail()) { + if (fileStream) { string lineinput, fullinput; while (getline(fileStream, lineinput)) { fullinput.append(lineinput += '\n'); From 4f40fdaed7fdf644b54808527c0ac803c1d11174 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 29 Dec 2021 19:20:12 +0100 Subject: [PATCH 047/254] Add a "=" operator and a default constructor to tok --- src/headers/lex.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/headers/lex.hpp b/src/headers/lex.hpp index e00b19d..baed249 100644 --- a/src/headers/lex.hpp +++ b/src/headers/lex.hpp @@ -19,6 +19,15 @@ struct tok { const type toktype; const std::string toktext; const unsigned long line; + tok& operator=(const tok& other) { + if (this != &other) { + const_cast(toktype) = other.toktype; + const_cast(toktext) = other.toktext; + const_cast(line) = other.line; + } + return *this; + } + tok(): toktype(UNEXPECTED), toktext(), line(0) {}; tok(const type& Type, std::string_view Text, const decltype(line)& line = 0): toktype(Type), toktext(Text), line(line) {} explicit tok(const type& Type, const decltype(line)& line = 0): tok(Type, std::string(1, Type), line) {}; friend std::ostream& operator<<(std::ostream& output, const tok& it) { return output << it.toktext; } From 04923f03a50d7959be79ce0fa9e5ec17e8c095e5 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 29 Dec 2021 23:25:58 +0100 Subject: [PATCH 048/254] Revert "Remove a useless #include directive in lex.hpp" This reverts commit 41e33e30ba5faef9bd841777eae8701718bf8f69. --- src/headers/lex.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/headers/lex.hpp b/src/headers/lex.hpp index baed249..6f97672 100644 --- a/src/headers/lex.hpp +++ b/src/headers/lex.hpp @@ -1,6 +1,7 @@ #ifndef YERBACON_LEX_H #define YERBACON_LEX_H +#include #include "Yerbacon.hpp" #include #include From 905222f61d3047242f2d22198d5d09489456faf2 Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 30 Dec 2021 16:45:58 +0100 Subject: [PATCH 049/254] Don't output an extra new line in the stringInterpolation() function --- src/headers/transpiler/Target.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 82c685a..9a03117 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -62,7 +62,7 @@ protected: output << view.substr(occurrence + strlen(interpolationString), (closingBrace - occurrence) - strlen(interpolationString)); } } - } else output << openCharacters << view << closeCharacters << '\n'; + } else output << openCharacters << view << closeCharacters; } typedef function task; #define make_task_base(type, captures, function_body) make_pair(type_index(typeid(type)), [captures](const ParseTree& parsedTree, unsigned int& index) { const type& parseComponent = pointerAs(parsedTree[index]); function_body }) From a59629bf941e3c4188b924e7a0b2e9ec45270133 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 31 Dec 2021 12:51:13 +0100 Subject: [PATCH 050/254] Update the description of the "--buildInfo" argument Signed-off-by: Username404 --- scripts/completions/fish-completion.fish | 2 +- scripts/completions/zsh-completion.zsh | 2 +- scripts/ybcon | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/completions/fish-completion.fish b/scripts/completions/fish-completion.fish index 453d265..9977067 100644 --- a/scripts/completions/fish-completion.fish +++ b/scripts/completions/fish-completion.fish @@ -3,7 +3,7 @@ set -l commands --version -h --help --target= -p --printresult complete -c ybcon -f -a "(__fish_complete_suffix .ybcon)" complete -c ybcon -x -s h -l help -d "Print the help screen" complete -c ybcon -x -l version -d "Print the version" -complete -c ybcon -x -l buildInfo -d "Print the compiler name and the optimization flags used to build the ybcon executable" +complete -c ybcon -x -l buildInfo -d "Print informations about how the ybcon executable was built" complete -c ybcon -l parallel -k -d "Transpile files in parallel mode" complete -c ybcon -l target -k -f -a 'lua js py' -d "Set the transpilation target" complete -c ybcon -l newlines -k -f -a 'on off' -d "Enable or disable new lines" diff --git a/scripts/completions/zsh-completion.zsh b/scripts/completions/zsh-completion.zsh index 9c05154..ea58753 100644 --- a/scripts/completions/zsh-completion.zsh +++ b/scripts/completions/zsh-completion.zsh @@ -4,7 +4,7 @@ _ybcon() { _arguments \ '( - 0)'{-h,--help}'[Print the help screen]' \ '( - 0)'--version'[Print the version]' \ - '( - 0)'--buildInfo'[Print the compiler name and the optimization flags used to build the ybcon executable]' \ + '( - 0)'--buildInfo'[Print informations about how the ybcon executable was built]' \ --parallel'[Transpile files in parallel mode]' \ --target='[Set the transpilation target]:language:(lua js py)' \ --newlines='[Enable or disable new lines]:state:(on off)' \ diff --git a/scripts/ybcon b/scripts/ybcon index e1f4309..f086ed0 100755 --- a/scripts/ybcon +++ b/scripts/ybcon @@ -14,7 +14,7 @@ usage() { echo "$EXENAME [--version] [--buildInfo] [-h|--help] [--parallel] [--target=] [--newlines=on/off] [-p|--printresult] " if [ "$1" = true ]; then echo " --version Print the version" - echo " --buildInfo Print the compiler name and the optimization flags used to build the ybcon executable" + echo " --buildInfo Print informations about how the ybcon executable was built" echo " -h or --help What you're seeing right now" echo " --parallel Transpile files in parallel mode" echo " --target= Set the transpilation target" From 17ea99118c14775d057add42eef2bb154f08f7d8 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 31 Dec 2021 13:04:57 +0100 Subject: [PATCH 051/254] Add "-fno-math-errno" to the release flags for GNU and Clang compilers Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a2bd15..a65d968 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,7 +55,7 @@ if (${IS_GNU} OR ${IS_CLANG}) endif() endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstrict-enums -pipe -fstack-protector-strong -fstack-clash-protection -funwind-tables -fasynchronous-unwind-tables -frtti -fexceptions") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections -fmerge-all-constants -ftree-vectorize") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections -fmerge-all-constants -ftree-vectorize -fno-math-errno") include(CheckCXXCompilerFlag) set(CF_PROTECTION "-fcf-protection") check_cxx_compiler_flag("${CF_PROTECTION}" CF_PROTECTION_SUPPORTED) From ae2a661427bf3846747b67e782cea0a1f6cc7e57 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 31 Dec 2021 23:46:08 +0100 Subject: [PATCH 052/254] Remove the useless nested structure in StandardComponents::Class --- src/headers/parsing/ParseComponents.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index 71c168a..218b7e4 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -35,8 +35,6 @@ namespace StandardComponents { }; struct Class: NamedIdentifier { - struct Constructor {}; - Constructor constructor; using NamedIdentifier::NamedIdentifier; }; namespace types { From 63b3d727a64e5582b43b4228e8d8e9afccc7e4fa Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 1 Jan 2022 00:36:28 +0100 Subject: [PATCH 053/254] Add a newline to the output in Target.hpp Signed-off-by: Username404 --- src/headers/transpiler/Target.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 9a03117..cb26d57 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -104,7 +104,7 @@ public: ) += " is not supported by the current target"); } } - return output.str(); + return output.str() + '\n'; }; explicit Target(const bool newLines): newLines(newLines) {}; virtual ~Target() = default; From b5ff43e10925e1856df6455dc5c98dc0f276ee18 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 1 Jan 2022 10:56:18 +0100 Subject: [PATCH 054/254] Remove a useless constructor in the ParseTree class Signed-off-by: Username404 --- src/headers/parsing/ParseComponents.hpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index 218b7e4..225839e 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -97,11 +97,6 @@ public: ParseTree(): subComponents() {}; IS_PARSECOMPONENT constexpr explicit ParseTree(const T& element): ParseTree() { addComponent(element); } IS_PARSECOMPONENT constexpr ParseTree(const initializer_list& elements): ParseTree() { addAllComponents(elements); } - ParseTree(const initializer_list& elements): ParseTree() { - for_each(elements.begin(), elements.end(), [&](ParseComponent* component){ - subComponents.emplace_back(component); - }); - } }; #undef IS_PARSECOMPONENT From 4082523be187f729c344dcd286c1431c74a7c35c Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 5 Jan 2022 22:09:41 +0100 Subject: [PATCH 055/254] Enable the new preprocessor conformance mode on MSVC Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a65d968..58c3446 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,7 +87,7 @@ elseif(${IS_CLANG}) endif() set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fstrict-vtable-pointers") elseif(MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /Zc:__cplusplus") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /Zc:__cplusplus /Zc:preprocessor") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") endif() string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPERCASE_BUILD_TYPE) From f2645744eea29128f8652b9998e4e1ab4c0332c3 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 8 Jan 2022 10:58:41 +0100 Subject: [PATCH 056/254] Add "/Zc:throwingNew" to the MSVC flags Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 58c3446..2bd719e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,7 +87,7 @@ elseif(${IS_CLANG}) endif() set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fstrict-vtable-pointers") elseif(MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /Zc:__cplusplus /Zc:preprocessor") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /Zc:__cplusplus /Zc:preprocessor /Zc:throwingNew") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") endif() string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPERCASE_BUILD_TYPE) From c7903678a0b639d01bbdd05c1d7bae5860f0545d Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 8 Jan 2022 12:38:16 +0100 Subject: [PATCH 057/254] Add "/Zc:inline" to the MSVC compiler flags Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bd719e..63bdbd2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,7 +87,7 @@ elseif(${IS_CLANG}) endif() set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fstrict-vtable-pointers") elseif(MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /Zc:__cplusplus /Zc:preprocessor /Zc:throwingNew") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /Zc:__cplusplus /Zc:preprocessor /Zc:throwingNew /Zc:inline") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") endif() string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPERCASE_BUILD_TYPE) From 6f1407ff529f105dcd7b0b84179710f87a5aa2de Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 8 Jan 2022 13:14:33 +0100 Subject: [PATCH 058/254] Add a minimal MSVC version Signed-off-by: Username404 --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 63bdbd2..c5eb4f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ set(CMAKE_CXX_FLAGS "-Wall") set(CMAKE_CXX_FLAGS_RELEASE "-Os") set(MINIMAL_GNU "11.0") set(MINIMAL_CLANG "13.0") +set(MINIMAL_MSVC "19.25") set(IS_GNU (${CMAKE_CXX_COMPILER_ID} STREQUAL GNU)) set(IS_CLANG (${CMAKE_CXX_COMPILER_ID} STREQUAL Clang)) @@ -87,6 +88,9 @@ elseif(${IS_CLANG}) endif() set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fstrict-vtable-pointers") elseif(MSVC) + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_MSVC}) + message(FATAL_ERROR "MSVC ${MINIMAL_MSVC} or higher is required") + endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /Zc:__cplusplus /Zc:preprocessor /Zc:throwingNew /Zc:inline") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") endif() From 3bd631d70c70b8a463de0078128981561774f7e3 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 8 Jan 2022 23:20:16 +0100 Subject: [PATCH 059/254] Make sure run-time type information is enabled on MSVC Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c5eb4f8..d0d9b58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,7 +91,7 @@ elseif(MSVC) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_MSVC}) message(FATAL_ERROR "MSVC ${MINIMAL_MSVC} or higher is required") endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /Zc:__cplusplus /Zc:preprocessor /Zc:throwingNew /Zc:inline") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR /W3 /Zc:__cplusplus /Zc:preprocessor /Zc:throwingNew /Zc:inline") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") endif() string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPERCASE_BUILD_TYPE) From 3f75c5cfc8ea104575e6db93ec7ea075814129e8 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 9 Jan 2022 14:44:48 +0100 Subject: [PATCH 060/254] Fix the "Hello, World!" example in the README.md file Signed-off-by: Username404 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 138723a..1a76cfa 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Aka Yer Bacon, - #### A language that transpiles into lua, javascript (ES6) or python code. ``` main #=> { - println "Hello, World!" + print_line("Hello, World!") } ``` From f33aec687aacfea7943456294a30a0eb983e2b64 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 29 Jan 2022 12:20:42 +0100 Subject: [PATCH 061/254] Parse Calls/ParseTrees Signed-off-by: Username404 --- src/etc/lexer.cpp | 2 +- src/headers/lex.hpp | 2 +- src/headers/parsing/ParseComponents.hpp | 70 +++++++++++-------- src/headers/parsing/Parser.hpp | 31 ++++++++ src/headers/transpiler/Target.hpp | 29 ++++++-- src/headers/transpiler/implementations/Js.hpp | 1 + .../transpiler/implementations/Lua.hpp | 1 + src/headers/transpiler/implementations/Py.hpp | 1 + 8 files changed, 100 insertions(+), 37 deletions(-) diff --git a/src/etc/lexer.cpp b/src/etc/lexer.cpp index 09024da..bc88f68 100644 --- a/src/etc/lexer.cpp +++ b/src/etc/lexer.cpp @@ -43,7 +43,7 @@ vector lex(const string& in) } else goto insertToken; } [[unlikely]] case EOF_: --lineNumber; - case DEFINE: case LPAR: case RPAR: + case DEFINE: case LPAR: case RPAR: case COMMA: case LBRACE: case RBRACE: case LBRACKET: case RBRACKET: case PLUS: case HYPHEN: case LCOMP: case RCOMP: case DOT: case DOLLAR_SIGN: case SQUOTE: diff --git a/src/headers/lex.hpp b/src/headers/lex.hpp index 6f97672..9487289 100644 --- a/src/headers/lex.hpp +++ b/src/headers/lex.hpp @@ -10,7 +10,7 @@ struct tok { typedef Yerbacon::Exception LexerException; enum type: const unsigned short { UNEXPECTED = std::numeric_limits::max() + 1, IDENTIFIER, NUMBER, ALPHACHAR, - EOF_ = '\0', DEFINE = '=', TAG = '#', DOLLAR_SIGN = '$', DOT = '.', + EOF_ = '\0', DEFINE = '=', TAG = '#', DOLLAR_SIGN = '$', DOT = '.', COMMA = ',', LPAR = '(', LBRACE = '{', LBRACKET = '[', RPAR = ')', RBRACE = '}', RBRACKET = ']', PLUS = '+', HYPHEN = '-', DIVIDE = '/', diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index 225839e..e204435 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -20,41 +20,27 @@ struct ParseComponent { virtual ~ParseComponent() = default; }; -namespace StandardComponents { - struct NamedIdentifier: ParseComponent { - const string name; - explicit NamedIdentifier(string_view nameText): name(nameText) {} - }; - struct Define: NamedIdentifier { - const bool final; - explicit Define(const bool& isFinal, string_view nameText): NamedIdentifier(nameText), final(isFinal) {} - explicit Define(string_view nameText): Define(false, nameText) {} - }; - struct Reference: NamedIdentifier { - using NamedIdentifier::NamedIdentifier; - }; - - struct Class: NamedIdentifier { - using NamedIdentifier::NamedIdentifier; - }; - namespace types { - struct String: ParseComponent { - const string content; - explicit String(const char* string): content(string) {} - }; - } -} +struct NamedIdentifier: ParseComponent { + const string name; + explicit NamedIdentifier(string_view nameText): name(nameText) {} +}; #define IS_PARSECOMPONENT IS(ParseComponent) -class ParseTree { +class ParseTree: public ParseComponent { mutable vector> subComponents; using array_type = decltype(subComponents); using iterator = array_type::iterator; using constant_iterator = array_type::const_iterator; protected: IS_PARSECOMPONENT - void addComponent(const T& component) const - { subComponents.emplace_back(new T(component)); }; + void addComponent(const T& component) const { + if constexpr(is_copy_constructible_v) { + subComponents.emplace_back(new T(component)); + } else { + static_assert(is_move_constructible_v, "T is not copy-constructible or move-constructible"); + subComponents.emplace_back(new T(move(const_cast(component)))); + } + }; IS_PARSECOMPONENT void addAllComponents( const initializer_list& components @@ -63,6 +49,7 @@ protected: for (const T& current: components) addComponent(current); } public: + inline size_t size() const { return subComponents.size(); } inline iterator begin() const noexcept { return subComponents.begin(); } inline constant_iterator cbegin() const noexcept { return subComponents.cbegin(); } inline iterator end() const noexcept { return subComponents.end(); } @@ -77,7 +64,7 @@ public: }); return filteredComponents; } - IS(StandardComponents::NamedIdentifier) + IS(NamedIdentifier) optional> findReferenceByName(const string& name) const { const vector identifiers = findById(); for (T* identifier: identifiers) { @@ -88,16 +75,39 @@ public: return optional>(); }; inline decltype(*subComponents.data()) operator[](const unsigned int& index) const { return subComponents[index]; } - IS(StandardComponents::NamedIdentifier) + IS(NamedIdentifier) inline auto operator[](const string& key) const { return findReferenceByName(key); } - inline size_t getCompCount() const { return subComponents.size(); } IS_PARSECOMPONENT inline void add(const T& component) { addComponent(component); } IS_PARSECOMPONENT inline void addAll(const initializer_list& components) { addAllComponents(components); } IS_PARSECOMPONENT inline ParseTree& operator<<(const T& component) { add(component); return *this; } ParseTree(): subComponents() {}; IS_PARSECOMPONENT constexpr explicit ParseTree(const T& element): ParseTree() { addComponent(element); } IS_PARSECOMPONENT constexpr ParseTree(const initializer_list& elements): ParseTree() { addAllComponents(elements); } + ParseTree(ParseTree&& parseTree) noexcept: subComponents(move(parseTree.subComponents)) {} + ParseTree(const ParseTree& parseTree) = delete; }; #undef IS_PARSECOMPONENT +namespace StandardComponents { + struct Define: NamedIdentifier { + const bool final; + explicit Define(const bool& isFinal, string_view nameText): NamedIdentifier(nameText), final(isFinal) {} + explicit Define(string_view nameText): Define(false, nameText) {} + }; + struct Reference: NamedIdentifier { + using NamedIdentifier::NamedIdentifier; + }; + namespace types { + struct String: ParseComponent { + const string content; + explicit String(const char* string): content(string) {} + }; + } + struct Call: ParseTree { inline explicit Call(ParseTree&& tree) noexcept: ParseTree(move(tree)) {} }; + + struct Class: NamedIdentifier { + using NamedIdentifier::NamedIdentifier; + }; +} + #endif //YERBACON_PARSECOMPONENTS_HPP \ No newline at end of file diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 99875f2..bc3db9a 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -58,7 +58,38 @@ namespace Parser { parseTree << Reference(current.toktext); } } + break; } + case LPAR: case LBRACE: case LBRACKET: { + const auto inverseCharacter = static_cast((current.toktype + 2) - (current.toktype == LPAR)); + const auto closingCharacter = find_if(lexed.cbegin(), lexed.cend(), [&inverseCharacter](const tok& it){ + return it.toktype == inverseCharacter; + }); + if (closingCharacter != lexed.cend()) { + vector subTokens; + subTokens.reserve(distance(lexed.cbegin() + i, closingCharacter)); + subTokens.assign(lexed.cbegin() + i + 1, closingCharacter); + if (current.toktype == LPAR || current.toktype == LBRACKET) { + if (subTokens.size() >= 2 && subTokens[1].toktype != RPAR) { + for (auto iterator = subTokens.cbegin(); iterator < (subTokens.cend() - 1); ++iterator) { + const auto nextIterator = iterator + 1; + if (nextIterator->toktype == COMMA) { + subTokens.erase(nextIterator); + } else throw ParsingException("Missing comma after \"" + iterator->toktext + '"'); + } + } + } + switch (current.toktype) { + case LPAR: parseTree << Call(parseVector(subTokens)); break; + case LBRACE: // TODO Add structures for class/function bodies + case LBRACKET: + default: parseTree << parseVector(subTokens); break; + } + i = distance(lexed.cbegin(), closingCharacter); + } else parsingError(current, string(" is missing a closing \"").append(1, inverseCharacter) + '"', true); + break; + } + case RPAR: case RBRACE: case RBRACKET: parsingError(current, " \u27F5 Unexpected character", true); default: break; } } diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index cb26d57..842ca68 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -67,15 +67,33 @@ protected: typedef function task; #define make_task_base(type, captures, function_body) make_pair(type_index(typeid(type)), [captures](const ParseTree& parsedTree, unsigned int& index) { const type& parseComponent = pointerAs(parsedTree[index]); function_body }) #define make_task(T, F) make_task_base(T, this, F) + #define make_nonlocal_task(T, F) make_task_base(T, , F) typedef unordered_map unordered_task_map; + typedef pair print_functions_pair; virtual unordered_task_map getTaskMap() = 0; + virtual print_functions_pair printFunctions() = 0; public: const unordered_task_map& getTaskMapInstance() { static unordered_task_map staticMap = getTaskMap(); // Default / Shared tasks: staticMap.merge(unordered_task_map({ - make_task(StandardComponents::Reference, - output << parseComponent.name; + make_task(ParseTree, + unsigned int subIndex = 0; + for (auto pointer_iterator = parseComponent.cbegin(); pointer_iterator < parseComponent.cend(); ++pointer_iterator) { + staticMap[pointer_iterator->get()->getId()](parseComponent, subIndex); ++subIndex; + if ((pointer_iterator + 1) != parseComponent.cend() && parseComponent.getId() == typeid(StandardComponents::Call)) { + output << ", "; + } + } + ), + make_task_base(StandardComponents::Reference, &, + const auto print_functions = printFunctions(); + output << ((parseComponent.name == "print") ? print_functions.first : (parseComponent.name == "print_line") ? print_functions.second : parseComponent.name); + ), + make_task(StandardComponents::Call, + output << '('; + staticMap[typeid(ParseTree)](parsedTree, index); + output << ')'; ) })); return staticMap; @@ -88,12 +106,11 @@ public: throw Yerbacon::Exception("--newlines=off is not supported by the current target"); } output.str(string()); - for (unsigned int i = 0; i < tree.getCompCount(); ++i) { + for (unsigned int i = 0; i < tree.size(); ++i) { const unique_ptr& component = tree[i]; const type_info& id = component->getId(); try { - const task& currentTask = taskMap.at(id); - currentTask(tree, i); + taskMap.at(id)(tree, i); } catch (const out_of_range&) { throw Yerbacon::Exception(string( #ifndef __GNUC__ @@ -141,7 +158,9 @@ shared_ptr Target::forName(string_view name, const bool newLines = true) default: Yerbacon::exit({"\"", string(1, (char) toupper(name.at(1))).data(), name.substr(2).data(), "\" is not a valid target."}); } #undef ADDTARGET + #undef make_nonlocal_task #undef make_task + #undef make_task_base return target; } diff --git a/src/headers/transpiler/implementations/Js.hpp b/src/headers/transpiler/implementations/Js.hpp index 0ace39f..60c476f 100644 --- a/src/headers/transpiler/implementations/Js.hpp +++ b/src/headers/transpiler/implementations/Js.hpp @@ -3,6 +3,7 @@ using namespace StandardComponents; struct JsTarget: Target { + print_functions_pair printFunctions() final { return make_pair("util.write", "console.log"); } unordered_task_map getTaskMap() final { return { make_task(Define, diff --git a/src/headers/transpiler/implementations/Lua.hpp b/src/headers/transpiler/implementations/Lua.hpp index 556c95b..57ef702 100644 --- a/src/headers/transpiler/implementations/Lua.hpp +++ b/src/headers/transpiler/implementations/Lua.hpp @@ -3,6 +3,7 @@ using namespace StandardComponents; struct LuaTarget: Target { + print_functions_pair printFunctions() final { return make_pair("io.write", "print"); } unordered_task_map getTaskMap() final { return { make_task(Define, diff --git a/src/headers/transpiler/implementations/Py.hpp b/src/headers/transpiler/implementations/Py.hpp index dc2bf5d..c9dde6a 100644 --- a/src/headers/transpiler/implementations/Py.hpp +++ b/src/headers/transpiler/implementations/Py.hpp @@ -4,6 +4,7 @@ using namespace StandardComponents; struct PyTarget: Target { bool supportsOneLine() final { return false; } + print_functions_pair printFunctions() final { return make_pair("sys.stdout.write", "print"); } unordered_task_map getTaskMap() final { return { make_task(Define, output << parseComponent.name << " = ";), From ca4e773fca55026043d3975aba667edf8df7c3f9 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 29 Jan 2022 12:48:35 +0100 Subject: [PATCH 062/254] Add an alternative "make_task_noR" macro to avoid making unused references in Target.hpp Signed-off-by: Username404 --- src/headers/transpiler/Target.hpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 842ca68..4ea5b9e 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -65,9 +65,11 @@ protected: } else output << openCharacters << view << closeCharacters; } typedef function task; - #define make_task_base(type, captures, function_body) make_pair(type_index(typeid(type)), [captures](const ParseTree& parsedTree, unsigned int& index) { const type& parseComponent = pointerAs(parsedTree[index]); function_body }) - #define make_task(T, F) make_task_base(T, this, F) - #define make_nonlocal_task(T, F) make_task_base(T, , F) + #define make_task_base(start, type, captures, function_body) make_pair(type_index(typeid(type)), [captures](const ParseTree& parsedTree, unsigned int& index) { start; function_body }) + #define make_task_base_R(T, C, F) make_task_base(const T& parseComponent = pointerAs(parsedTree[index]), T, C, F) + #define make_task(T, F) make_task_base_R(T, this, F) + #define make_task_noR(T, F) make_task_base(,T, this, F) + #define make_nonlocal_task(T, F) make_task_base_R(T, , F) typedef unordered_map unordered_task_map; typedef pair print_functions_pair; virtual unordered_task_map getTaskMap() = 0; @@ -86,11 +88,11 @@ public: } } ), - make_task_base(StandardComponents::Reference, &, + make_task(StandardComponents::Reference, const auto print_functions = printFunctions(); output << ((parseComponent.name == "print") ? print_functions.first : (parseComponent.name == "print_line") ? print_functions.second : parseComponent.name); ), - make_task(StandardComponents::Call, + make_task_noR(StandardComponents::Call, output << '('; staticMap[typeid(ParseTree)](parsedTree, index); output << ')'; @@ -159,7 +161,9 @@ shared_ptr Target::forName(string_view name, const bool newLines = true) } #undef ADDTARGET #undef make_nonlocal_task + #undef make_task_noR #undef make_task + #undef make_task_base_R #undef make_task_base return target; } From 1a37e3522823ac658c3215f47fdb695e729432e4 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 6 Feb 2022 19:40:34 +0100 Subject: [PATCH 063/254] Add a component_ptr type definition to ParseComponents.hpp Signed-off-by: Username404 --- src/headers/parsing/ParseComponents.hpp | 8 +++++--- src/headers/transpiler/Target.hpp | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index e204435..f191182 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -25,9 +25,11 @@ struct NamedIdentifier: ParseComponent { explicit NamedIdentifier(string_view nameText): name(nameText) {} }; +typedef unique_ptr component_ptr; + #define IS_PARSECOMPONENT IS(ParseComponent) class ParseTree: public ParseComponent { - mutable vector> subComponents; + mutable vector subComponents; using array_type = decltype(subComponents); using iterator = array_type::iterator; using constant_iterator = array_type::const_iterator; @@ -57,7 +59,7 @@ public: IS_PARSECOMPONENT vector findById() const { vector filteredComponents; - for_each(cbegin(), cend(), [&filteredComponents](const unique_ptr& it) { + for_each(cbegin(), cend(), [&filteredComponents](const component_ptr& it) { if (it->getId() == typeid(T)) { filteredComponents.push_back(reinterpret_cast(it.get())); } @@ -74,7 +76,7 @@ public: } return optional>(); }; - inline decltype(*subComponents.data()) operator[](const unsigned int& index) const { return subComponents[index]; } + inline component_ptr& operator[](const unsigned int& index) const { return subComponents[index]; } IS(NamedIdentifier) inline auto operator[](const string& key) const { return findReferenceByName(key); } IS_PARSECOMPONENT inline void add(const T& component) { addComponent(component); } diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 4ea5b9e..bc39d17 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -109,7 +109,7 @@ public: } output.str(string()); for (unsigned int i = 0; i < tree.size(); ++i) { - const unique_ptr& component = tree[i]; + const component_ptr& component = tree[i]; const type_info& id = component->getId(); try { taskMap.at(id)(tree, i); From a45902c9b252f863795505ebd48f13c765231efa Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 6 Feb 2022 19:50:37 +0100 Subject: [PATCH 064/254] Add an "at" function to ParseTree Signed-off-by: Username404 --- src/headers/parsing/ParseComponents.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index f191182..6727ba0 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -77,6 +77,7 @@ public: return optional>(); }; inline component_ptr& operator[](const unsigned int& index) const { return subComponents[index]; } + inline component_ptr& at(const unsigned int& index) const { return subComponents.at(index); } IS(NamedIdentifier) inline auto operator[](const string& key) const { return findReferenceByName(key); } IS_PARSECOMPONENT inline void add(const T& component) { addComponent(component); } From 0b3109c989358d36acb4c4e78ab8234162d64d6d Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 6 Feb 2022 19:51:23 +0100 Subject: [PATCH 065/254] Add a move assignment operator to ParseTree Signed-off-by: Username404 --- src/headers/parsing/ParseComponents.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index 6727ba0..8cc04f9 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -86,6 +86,7 @@ public: ParseTree(): subComponents() {}; IS_PARSECOMPONENT constexpr explicit ParseTree(const T& element): ParseTree() { addComponent(element); } IS_PARSECOMPONENT constexpr ParseTree(const initializer_list& elements): ParseTree() { addAllComponents(elements); } + ParseTree& operator=(ParseTree&& parseTree) noexcept { subComponents = move(parseTree.subComponents); return *this; } ParseTree(ParseTree&& parseTree) noexcept: subComponents(move(parseTree.subComponents)) {} ParseTree(const ParseTree& parseTree) = delete; }; From 644d8d26a2f47d15b4d37397ec682b51ff44692e Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 8 Feb 2022 18:05:21 +0100 Subject: [PATCH 066/254] Use named functions in HelloWorld.ybcon and README.md Signed-off-by: Username404 --- README.md | 2 +- examples/HelloWorld.ybcon | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1a76cfa..aea8514 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Aka Yer Bacon, - #### A language that transpiles into lua, javascript (ES6) or python code. ``` -main #=> { +main >> { print_line("Hello, World!") } ``` diff --git a/examples/HelloWorld.ybcon b/examples/HelloWorld.ybcon index 17413c2..5cd203f 100644 --- a/examples/HelloWorld.ybcon +++ b/examples/HelloWorld.ybcon @@ -1,3 +1,3 @@ -main #= [] -> { +main >> { print_line("Hello, World!") } From c4f75a3b042868631dc07859bb7aa0e47f2caa82 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 8 Feb 2022 18:07:20 +0100 Subject: [PATCH 067/254] Make the constexpr ParseTree constructors inline instead Signed-off-by: Username404 --- src/headers/parsing/ParseComponents.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index 8cc04f9..08ba9b0 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -84,8 +84,8 @@ public: IS_PARSECOMPONENT inline void addAll(const initializer_list& components) { addAllComponents(components); } IS_PARSECOMPONENT inline ParseTree& operator<<(const T& component) { add(component); return *this; } ParseTree(): subComponents() {}; - IS_PARSECOMPONENT constexpr explicit ParseTree(const T& element): ParseTree() { addComponent(element); } - IS_PARSECOMPONENT constexpr ParseTree(const initializer_list& elements): ParseTree() { addAllComponents(elements); } + IS_PARSECOMPONENT inline explicit ParseTree(const T& element): ParseTree() { addComponent(element); } + IS_PARSECOMPONENT inline ParseTree(const initializer_list& elements): ParseTree() { addAllComponents(elements); } ParseTree& operator=(ParseTree&& parseTree) noexcept { subComponents = move(parseTree.subComponents); return *this; } ParseTree(ParseTree&& parseTree) noexcept: subComponents(move(parseTree.subComponents)) {} ParseTree(const ParseTree& parseTree) = delete; From 68dc7ea1a1c18fb879b63313f8a4baa417e8d29d Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 8 Feb 2022 18:14:40 +0100 Subject: [PATCH 068/254] Make Parser::parseVector a function template Signed-off-by: Username404 --- src/headers/parsing/ParseComponents.hpp | 2 +- src/headers/parsing/Parser.hpp | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index 08ba9b0..76950f7 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -107,7 +107,7 @@ namespace StandardComponents { explicit String(const char* string): content(string) {} }; } - struct Call: ParseTree { inline explicit Call(ParseTree&& tree) noexcept: ParseTree(move(tree)) {} }; + struct Call: ParseTree {}; struct Class: NamedIdentifier { using NamedIdentifier::NamedIdentifier; diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index bc3db9a..957d955 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -15,14 +15,15 @@ namespace Parser { const tok& token, const string& text, const bool& quoteTokenText = false ) { error(token, text, token.line, quoteTokenText); } - ParseTree parseVector(const vector& lexed) { - ParseTree parseTree; + IS(ParseTree) + T parseVector(const vector& lexed) { + T parseTree; using namespace StandardComponents; using enum tok::type; unsigned int i = 0; - const auto nextAre = [&i, &lexed] T>(const initializer_list& nextValues) -> bool { + const auto nextAre = [&i, &lexed] Y>(const initializer_list& nextValues) -> bool { unsigned int j = 1; - for (const T& nextValue: nextValues) { + for (const Y& nextValue: nextValues) { if (!cmp_greater(lexed.size() - i, nextValues.size()) || lexed[i + j].toktype != nextValue) { return false; } @@ -46,7 +47,7 @@ namespace Parser { } else { bool isFinalDefine = nextAre({TAG, DEFINE}); if (isFinalDefine || next.toktype == DEFINE) { - const optional previousDefinition = parseTree.findReferenceByName(current.toktext); + const optional previousDefinition = parseTree.template findReferenceByName(current.toktext); if (previousDefinition.has_value()) { if (previousDefinition.value().get().final || isFinalDefine) { parsingError(current, previousDefinition->get().final ? " cannot be redefined as it is final" : " cannot be made final after it has been declared", true); @@ -80,7 +81,7 @@ namespace Parser { } } switch (current.toktype) { - case LPAR: parseTree << Call(parseVector(subTokens)); break; + case LPAR: parseTree << parseVector(subTokens); break; case LBRACE: // TODO Add structures for class/function bodies case LBRACKET: default: parseTree << parseVector(subTokens); break; From de2d936e19a1adeb2e0590083cef80b0653918c7 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 8 Feb 2022 18:18:34 +0100 Subject: [PATCH 069/254] Use dynamic_cast instead of reinterpret_cast in Target.hpp and ParseComponents.hpp, and extend the ParseComponent class virtually in the ParseTree and NamedIdentifier classes Signed-off-by: Username404 --- src/headers/Yerbacon.hpp | 4 ---- src/headers/parsing/ParseComponents.hpp | 6 +++--- src/headers/transpiler/Target.hpp | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/headers/Yerbacon.hpp b/src/headers/Yerbacon.hpp index adb5abd..524ad74 100644 --- a/src/headers/Yerbacon.hpp +++ b/src/headers/Yerbacon.hpp @@ -65,10 +65,6 @@ namespace Yerbacon { }; } -#include -template -constexpr T& pointerAs(const std::unique_ptr& ptr) { return reinterpret_cast(*ptr); } - #undef YBCON_VERSION #undef YBCON_FLAGS #undef YBCON_COMPILER diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index 76950f7..f4e5877 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -20,7 +20,7 @@ struct ParseComponent { virtual ~ParseComponent() = default; }; -struct NamedIdentifier: ParseComponent { +struct NamedIdentifier: virtual ParseComponent { const string name; explicit NamedIdentifier(string_view nameText): name(nameText) {} }; @@ -28,7 +28,7 @@ struct NamedIdentifier: ParseComponent { typedef unique_ptr component_ptr; #define IS_PARSECOMPONENT IS(ParseComponent) -class ParseTree: public ParseComponent { +class ParseTree: public virtual ParseComponent { mutable vector subComponents; using array_type = decltype(subComponents); using iterator = array_type::iterator; @@ -61,7 +61,7 @@ public: vector filteredComponents; for_each(cbegin(), cend(), [&filteredComponents](const component_ptr& it) { if (it->getId() == typeid(T)) { - filteredComponents.push_back(reinterpret_cast(it.get())); + filteredComponents.push_back(dynamic_cast(it.get())); } }); return filteredComponents; diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index bc39d17..a3f65dd 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -66,7 +66,7 @@ protected: } typedef function task; #define make_task_base(start, type, captures, function_body) make_pair(type_index(typeid(type)), [captures](const ParseTree& parsedTree, unsigned int& index) { start; function_body }) - #define make_task_base_R(T, C, F) make_task_base(const T& parseComponent = pointerAs(parsedTree[index]), T, C, F) + #define make_task_base_R(T, C, F) make_task_base(const T& parseComponent = dynamic_cast(*parsedTree[index]), T, C, F) #define make_task(T, F) make_task_base_R(T, this, F) #define make_task_noR(T, F) make_task_base(,T, this, F) #define make_nonlocal_task(T, F) make_task_base_R(T, , F) From 7cbb4244166351ff15c5b997b94f18759a6ebad0 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 8 Feb 2022 18:21:42 +0100 Subject: [PATCH 070/254] Add a "unit_result" type alias to main.cpp Signed-off-by: Username404 --- src/main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 0b249ba..e3b3638 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -57,12 +57,13 @@ int main(int argc, char* argv[]) { }; int8_t exit_code = EXIT_SUCCESS; if (!files.empty()) { - using unit = future>>; + using unit_result = pair>; + using unit = future; vector Units(files.size()); const launch& Policy = not parallel ? launch::deferred : launch::async; transform(files.cbegin(), files.cend(), Units.begin(), [&Policy, &compile](const string_view& fileName){ return async(Policy, [&fileName, &compile]() { - pair> resultingPair; + unit_result resultingPair; try { resultingPair.first = compile(fileName); } catch (const Yerbacon::Exception& error) { From de2259b6ed8d226659093f3c2a8514530dc0b06a Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 8 Feb 2022 18:31:00 +0100 Subject: [PATCH 071/254] Add a "inverseLCharacter" static function to tok Signed-off-by: Username404 --- src/headers/lex.hpp | 3 +++ src/headers/parsing/Parser.hpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/headers/lex.hpp b/src/headers/lex.hpp index 9487289..635b4be 100644 --- a/src/headers/lex.hpp +++ b/src/headers/lex.hpp @@ -17,6 +17,9 @@ struct tok { LCOMP = '>', RCOMP = '<', SQUOTE = '\'', ASTERISK = '*', STRING = '"', }; + static auto inverseLCharacter(const unsigned char& character) { + return static_cast(((character + 2) - (character == tok::LPAR))); + }; const type toktype; const std::string toktext; const unsigned long line; diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 957d955..f3b09ee 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -62,7 +62,7 @@ namespace Parser { break; } case LPAR: case LBRACE: case LBRACKET: { - const auto inverseCharacter = static_cast((current.toktype + 2) - (current.toktype == LPAR)); + const auto inverseCharacter = tok::inverseLCharacter(current.toktype); const auto closingCharacter = find_if(lexed.cbegin(), lexed.cend(), [&inverseCharacter](const tok& it){ return it.toktype == inverseCharacter; }); From beb28ef4adb28f52024a53d3bcdd0cc8cf115865 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 8 Feb 2022 19:26:57 +0100 Subject: [PATCH 072/254] Rename the Yerbacon::exit function to Yerbacon::fail Signed-off-by: Username404 --- src/headers/Yerbacon.hpp | 4 ++-- src/headers/transpiler/Target.hpp | 2 +- src/main.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/headers/Yerbacon.hpp b/src/headers/Yerbacon.hpp index 524ad74..4f19f1b 100644 --- a/src/headers/Yerbacon.hpp +++ b/src/headers/Yerbacon.hpp @@ -44,14 +44,14 @@ namespace Yerbacon { " Compiler: " YBCON_COMPILER "\n" " C++ standard: " make_string(__cplusplus); } - static void exit(const std::initializer_list reason) { + static void fail(const std::initializer_list reason) { std::for_each(reason.begin(), reason.end(), [](const char* current_string){ std::cout << current_string; }); std::cout << std::endl; std::exit(EXIT_FAILURE); } - inline void exit(const char* reason) { exit({reason}); } + inline void fail(const char* reason) { fail({reason}); } class Exception: public std::exception { std::string exceptionCause; public: diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index a3f65dd..a987a3a 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -157,7 +157,7 @@ shared_ptr Target::forName(string_view name, const bool newLines = true) case PY: ADDTARGET(PY_HPP); break; #endif case NONE: - default: Yerbacon::exit({"\"", string(1, (char) toupper(name.at(1))).data(), name.substr(2).data(), "\" is not a valid target."}); + default: Yerbacon::fail({"\"", string(1, (char) toupper(name.at(1))).data(), name.substr(2).data(), "\" is not a valid target."}); } #undef ADDTARGET #undef make_nonlocal_task diff --git a/src/main.cpp b/src/main.cpp index e3b3638..45a9656 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,7 +23,7 @@ int main(int argc, char* argv[]) { else if (currentArg == ArgumentAssignable("target")) { const string_view value = ArgumentAssignable::getValueFor(currentArg); if (not value.empty()) (target = '.') += value; - else Yerbacon::exit("No target was provided."); + else Yerbacon::fail("No target was provided."); } else if (currentArg == Argument("parallel")) parallel = true; else if (currentArg == ArgumentAssignable("newlines")) { @@ -43,7 +43,7 @@ int main(int argc, char* argv[]) { cout << Yerbacon::getBuildInfo(); } else goto invalid_argument; cout << '\n'; exit(EXIT_SUCCESS); - } else invalid_argument: Yerbacon::exit({"\"", currentArg.data(), "\" is not a valid argument."}); + } else invalid_argument: Yerbacon::fail({"\"", currentArg.data(), "\" is not a valid argument."}); } } const auto currentTarget = Target::forName(target, newLines); From 63b24752d67184be9505d4a91203b79fdb0fb141 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 12 Feb 2022 20:35:06 +0100 Subject: [PATCH 073/254] Make the members of the tok structure non-const to avoid undefined behaviour when the "=" operator is called Signed-off-by: Username404 --- src/headers/lex.hpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/headers/lex.hpp b/src/headers/lex.hpp index 635b4be..4a8903d 100644 --- a/src/headers/lex.hpp +++ b/src/headers/lex.hpp @@ -20,17 +20,9 @@ struct tok { static auto inverseLCharacter(const unsigned char& character) { return static_cast(((character + 2) - (character == tok::LPAR))); }; - const type toktype; - const std::string toktext; - const unsigned long line; - tok& operator=(const tok& other) { - if (this != &other) { - const_cast(toktype) = other.toktype; - const_cast(toktext) = other.toktext; - const_cast(line) = other.line; - } - return *this; - } + type toktype; + std::string toktext; + unsigned long line; tok(): toktype(UNEXPECTED), toktext(), line(0) {}; tok(const type& Type, std::string_view Text, const decltype(line)& line = 0): toktype(Type), toktext(Text), line(line) {} explicit tok(const type& Type, const decltype(line)& line = 0): tok(Type, std::string(1, Type), line) {}; From 3c130529a4e7980983681ef5e2d6695662a4ccd4 Mon Sep 17 00:00:00 2001 From: Username404 Date: Mon, 14 Feb 2022 12:11:03 +0100 Subject: [PATCH 074/254] Make the newLine constructor parameter a reference & add a "separator" member and a "uniqueLineSeparator" virtual method to Target.hpp Signed-off-by: Username404 --- src/headers/transpiler/Target.hpp | 13 +++++++------ src/headers/transpiler/implementations/Lua.hpp | 1 + src/headers/transpiler/implementations/Py.hpp | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index a987a3a..535ae5d 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -19,7 +19,7 @@ class Target { constexpr static const char* const interpolationString = "${"; constexpr static const char* const interpolationCloseString = "}"; protected: - virtual constexpr bool supportsOneLine() { return true; }; + inline bool supportsOneLine() { return uniqueLineSeparator().has_value(); }; std::stringstream output; inline void stringInterpolation(const char* multiline, const string& view) { stringInterpolation(view, multiline, multiline); } void stringInterpolation(string view, const char* openMultiline = "", const char* closeMultiline = "", const char* concatenationCharacters = "+") { @@ -74,6 +74,10 @@ protected: typedef pair print_functions_pair; virtual unordered_task_map getTaskMap() = 0; virtual print_functions_pair printFunctions() = 0; + typedef optional optional_string; + virtual optional_string uniqueLineSeparator() { return ";"; }; + const bool newLines; + const char* separator; public: const unordered_task_map& getTaskMapInstance() { static unordered_task_map staticMap = getTaskMap(); @@ -101,12 +105,9 @@ public: return staticMap; }; static shared_ptr forName(string_view name, bool newLines); - const bool newLines; string transpileWithTree(const ParseTree& tree) { + separator = newLines ? "\n" : (supportsOneLine() ? uniqueLineSeparator().value() : throw Yerbacon::Exception("--newlines=off is not supported by the current target")); const unordered_task_map& taskMap = getTaskMapInstance(); - if (not newLines && !supportsOneLine()) { - throw Yerbacon::Exception("--newlines=off is not supported by the current target"); - } output.str(string()); for (unsigned int i = 0; i < tree.size(); ++i) { const component_ptr& component = tree[i]; @@ -125,7 +126,7 @@ public: } return output.str() + '\n'; }; - explicit Target(const bool newLines): newLines(newLines) {}; + explicit Target(const bool& newLines): newLines(newLines), separator() {}; virtual ~Target() = default; }; diff --git a/src/headers/transpiler/implementations/Lua.hpp b/src/headers/transpiler/implementations/Lua.hpp index 57ef702..d8c9b58 100644 --- a/src/headers/transpiler/implementations/Lua.hpp +++ b/src/headers/transpiler/implementations/Lua.hpp @@ -4,6 +4,7 @@ using namespace StandardComponents; struct LuaTarget: Target { print_functions_pair printFunctions() final { return make_pair("io.write", "print"); } + optional_string uniqueLineSeparator() final { return " "; } unordered_task_map getTaskMap() final { return { make_task(Define, diff --git a/src/headers/transpiler/implementations/Py.hpp b/src/headers/transpiler/implementations/Py.hpp index c9dde6a..2b2396a 100644 --- a/src/headers/transpiler/implementations/Py.hpp +++ b/src/headers/transpiler/implementations/Py.hpp @@ -3,8 +3,8 @@ using namespace StandardComponents; struct PyTarget: Target { - bool supportsOneLine() final { return false; } print_functions_pair printFunctions() final { return make_pair("sys.stdout.write", "print"); } + optional_string uniqueLineSeparator() final { return {}; } unordered_task_map getTaskMap() final { return { make_task(Define, output << parseComponent.name << " = ";), From 56e1db5fcceb5f209b60aa99fe7f5dca72f79e68 Mon Sep 17 00:00:00 2001 From: Username404 Date: Mon, 14 Feb 2022 13:32:10 +0100 Subject: [PATCH 075/254] Add a transpileTree function to Target.hpp Signed-off-by: Username404 --- src/headers/transpiler/Target.hpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 535ae5d..235b3e0 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -74,6 +74,17 @@ protected: typedef pair print_functions_pair; virtual unordered_task_map getTaskMap() = 0; virtual print_functions_pair printFunctions() = 0; + void transpileTree(const derived_from auto& parseTree) { + if (parseTree.size() > 0) { + unsigned int subIndex = 0; + for (auto pointer_iterator = parseTree.cbegin(); pointer_iterator < parseTree.cend(); ++pointer_iterator) { + getTaskMapInstance().at(pointer_iterator->get()->getId())(parseTree, subIndex); ++subIndex; + if ((pointer_iterator + 1) != parseTree.cend() && parseTree.getId() == typeid(StandardComponents::Call)) { + output << ", "; + } + } + } + } typedef optional optional_string; virtual optional_string uniqueLineSeparator() { return ";"; }; const bool newLines; @@ -83,22 +94,14 @@ public: static unordered_task_map staticMap = getTaskMap(); // Default / Shared tasks: staticMap.merge(unordered_task_map({ - make_task(ParseTree, - unsigned int subIndex = 0; - for (auto pointer_iterator = parseComponent.cbegin(); pointer_iterator < parseComponent.cend(); ++pointer_iterator) { - staticMap[pointer_iterator->get()->getId()](parseComponent, subIndex); ++subIndex; - if ((pointer_iterator + 1) != parseComponent.cend() && parseComponent.getId() == typeid(StandardComponents::Call)) { - output << ", "; - } - } - ), + make_task(ParseTree, transpileTree(parseComponent);), make_task(StandardComponents::Reference, const auto print_functions = printFunctions(); output << ((parseComponent.name == "print") ? print_functions.first : (parseComponent.name == "print_line") ? print_functions.second : parseComponent.name); ), - make_task_noR(StandardComponents::Call, + make_task(StandardComponents::Call, output << '('; - staticMap[typeid(ParseTree)](parsedTree, index); + transpileTree(parseComponent); output << ')'; ) })); From ec4121de1cac0188e5a90bbadfb236d52f4037dc Mon Sep 17 00:00:00 2001 From: Username404 Date: Mon, 14 Feb 2022 16:02:30 +0100 Subject: [PATCH 076/254] Fix parsing of parentheses by searching after the current index Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index f3b09ee..a129bc8 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -63,7 +63,7 @@ namespace Parser { } case LPAR: case LBRACE: case LBRACKET: { const auto inverseCharacter = tok::inverseLCharacter(current.toktype); - const auto closingCharacter = find_if(lexed.cbegin(), lexed.cend(), [&inverseCharacter](const tok& it){ + const auto closingCharacter = find_if(lexed.cbegin() + i, lexed.cend(), [&inverseCharacter](const tok& it){ return it.toktype == inverseCharacter; }); if (closingCharacter != lexed.cend()) { From df10215e4e00060ff31ab15287ed617cbd39a190 Mon Sep 17 00:00:00 2001 From: Username404 Date: Mon, 14 Feb 2022 22:42:00 +0100 Subject: [PATCH 077/254] Rename LEGALCOPYRIGHT to LEGAL-COPYRIGHT in the CMakeLists.txt and resources/Yerbacon.rc files Signed-off-by: Username404 --- CMakeLists.txt | 2 +- resources/Yerbacon.rc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d0d9b58..debd24d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ set(EXEDESC "Transpiler for the yerbacon language.") string(TIMESTAMP SHORT_BUILD_TIMESTAMP "%Y%m") string(SUBSTRING ${SHORT_BUILD_TIMESTAMP} 2 4 SHORT_BUILD_TIMESTAMP) string(ASCII 169 CopyrightCharacter) -string(TIMESTAMP LEGALCOPYRIGHT "Copyright ${CopyrightCharacter} 2020-%Y. Available under the MPL-2.0 license.") +string(TIMESTAMP LEGAL-COPYRIGHT "Copyright ${CopyrightCharacter} 2020-%Y. Available under the MPL-2.0 license.") file(COPY "resources/${PROJECT_NAME}.ico" DESTINATION "processed") configure_file("resources/${PROJECT_NAME}.manifest" "processed/${PROJECT_NAME}.manifest" @ONLY) configure_file("resources/${PROJECT_NAME}.rc" "processed/${PROJECT_NAME}.rc" @ONLY) diff --git a/resources/Yerbacon.rc b/resources/Yerbacon.rc index 9da11b5..5325fe8 100644 --- a/resources/Yerbacon.rc +++ b/resources/Yerbacon.rc @@ -14,7 +14,7 @@ BEGIN VALUE "FileDescription", "@EXEDESC@" VALUE "FileVersion", "@CMAKE_PROJECT_VERSION@.@SHORT_BUILD_TIMESTAMP@" VALUE "InternalName", "@EXENAME@" - VALUE "LegalCopyright", "@LEGALCOPYRIGHT@" + VALUE "LegalCopyright", "@LEGAL-COPYRIGHT@" VALUE "OriginalName", "@EXENAME@.exe" VALUE "ProductName", "@PROJECT_NAME@" VALUE "ProductVersion", "@CODENAME@ @CMAKE_PROJECT_VERSION@" From 6955c5cb4d12a15d7e55d4e2ea2c62ef70d6f73f Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 1 Mar 2022 19:40:30 +0100 Subject: [PATCH 078/254] Remove tok::type::EOF_ because it is useless, and fix the `next` local constant reference in Parser.hpp Signed-off-by: Username404 --- src/etc/lexer.cpp | 5 ++--- src/headers/lex.hpp | 2 +- src/headers/parsing/Parser.hpp | 9 ++++----- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/etc/lexer.cpp b/src/etc/lexer.cpp index bc88f68..4a048b0 100644 --- a/src/etc/lexer.cpp +++ b/src/etc/lexer.cpp @@ -13,7 +13,7 @@ vector lex(const string& in) { vector resVal; unsigned long lineNumber = 1; - for (unsigned int i = 0; i <= in.size(); ++i) { + for (unsigned int i = 0; i < in.size(); ++i) { const char& current = in[i]; switch (current) { @@ -22,7 +22,7 @@ vector lex(const string& in) if (current == TAG && in[i + 1] == DEFINE) { // See the IDENTIFIER case in Parser.hpp goto insertToken; } else { - while (not (in[i + 1] == EOF_ || in[i + 1] == '\n')) { + while (not (i == in.size() || in[i + 1] == '\n')) { ++i; } break; @@ -42,7 +42,6 @@ vector lex(const string& in) break; } else goto insertToken; } - [[unlikely]] case EOF_: --lineNumber; case DEFINE: case LPAR: case RPAR: case COMMA: case LBRACE: case RBRACE: case LBRACKET: case RBRACKET: case PLUS: case HYPHEN: case LCOMP: case RCOMP: diff --git a/src/headers/lex.hpp b/src/headers/lex.hpp index 4a8903d..d73e65e 100644 --- a/src/headers/lex.hpp +++ b/src/headers/lex.hpp @@ -10,7 +10,7 @@ struct tok { typedef Yerbacon::Exception LexerException; enum type: const unsigned short { UNEXPECTED = std::numeric_limits::max() + 1, IDENTIFIER, NUMBER, ALPHACHAR, - EOF_ = '\0', DEFINE = '=', TAG = '#', DOLLAR_SIGN = '$', DOT = '.', COMMA = ',', + DEFINE = '=', TAG = '#', DOLLAR_SIGN = '$', DOT = '.', COMMA = ',', LPAR = '(', LBRACE = '{', LBRACKET = '[', RPAR = ')', RBRACE = '}', RBRACKET = ']', PLUS = '+', HYPHEN = '-', DIVIDE = '/', diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index a129bc8..7edd31e 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -32,7 +32,8 @@ namespace Parser { return true; }; for (;i < lexed.size(); ++i) { - const tok& current = lexed[i], next = (current.toktype != EOF_) ? lexed[i + 1] : current; + const bool hasNext = (i + 1) < lexed.size(); + const tok& current = lexed[i], next = hasNext ? lexed[i + 1] : tok(UNEXPECTED); switch (current.toktype) { case STRING: parseTree << types::String(current.toktext.data()); break; @@ -41,7 +42,7 @@ namespace Parser { if (next.toktype == IDENTIFIER) { parseTree << Class(next.toktext); ++i; } else { - const bool isNotBlank = (not (next.toktext.empty() or next.toktype == tok::EOF_)); + const bool isNotBlank = not next.toktext.empty(); parsingError(next, isNotBlank ? " is not a valid class identifier" : "A class identifier is required", isNotBlank); } } else { @@ -67,9 +68,7 @@ namespace Parser { return it.toktype == inverseCharacter; }); if (closingCharacter != lexed.cend()) { - vector subTokens; - subTokens.reserve(distance(lexed.cbegin() + i, closingCharacter)); - subTokens.assign(lexed.cbegin() + i + 1, closingCharacter); + vector subTokens(lexed.cbegin() + i + 1, closingCharacter); if (current.toktype == LPAR || current.toktype == LBRACKET) { if (subTokens.size() >= 2 && subTokens[1].toktype != RPAR) { for (auto iterator = subTokens.cbegin(); iterator < (subTokens.cend() - 1); ++iterator) { From 33e29ccb8e874af3cd3607ba7e8894d39ee3dad4 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 1 Mar 2022 20:16:15 +0100 Subject: [PATCH 079/254] Remove the tok default constructor in lex.hpp Signed-off-by: Username404 --- src/headers/lex.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/lex.hpp b/src/headers/lex.hpp index d73e65e..bb418e5 100644 --- a/src/headers/lex.hpp +++ b/src/headers/lex.hpp @@ -23,7 +23,7 @@ struct tok { type toktype; std::string toktext; unsigned long line; - tok(): toktype(UNEXPECTED), toktext(), line(0) {}; + tok() = delete; tok(const type& Type, std::string_view Text, const decltype(line)& line = 0): toktype(Type), toktext(Text), line(line) {} explicit tok(const type& Type, const decltype(line)& line = 0): tok(Type, std::string(1, Type), line) {}; friend std::ostream& operator<<(std::ostream& output, const tok& it) { return output << it.toktext; } From 9d7300ce89d5f6c37c04a1bbe490cacd5f4b82a9 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 4 Mar 2022 19:18:46 +0100 Subject: [PATCH 080/254] Fix errors by removing the isNotBlank boolean and using hasNext instead Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 7edd31e..dc4e35c 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -42,8 +42,7 @@ namespace Parser { if (next.toktype == IDENTIFIER) { parseTree << Class(next.toktext); ++i; } else { - const bool isNotBlank = not next.toktext.empty(); - parsingError(next, isNotBlank ? " is not a valid class identifier" : "A class identifier is required", isNotBlank); + parsingError(next, hasNext ? " is not a valid class identifier" : "A class identifier is required", hasNext); } } else { bool isFinalDefine = nextAre({TAG, DEFINE}); From 26d88c2f9131cea4beb736923041e0891ae59794 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 4 Mar 2022 19:25:15 +0100 Subject: [PATCH 081/254] Set line to 1 by default in the tok structure Signed-off-by: Username404 --- src/headers/lex.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/headers/lex.hpp b/src/headers/lex.hpp index bb418e5..8035055 100644 --- a/src/headers/lex.hpp +++ b/src/headers/lex.hpp @@ -24,8 +24,8 @@ struct tok { std::string toktext; unsigned long line; tok() = delete; - tok(const type& Type, std::string_view Text, const decltype(line)& line = 0): toktype(Type), toktext(Text), line(line) {} - explicit tok(const type& Type, const decltype(line)& line = 0): tok(Type, std::string(1, Type), line) {}; + tok(const type& Type, std::string_view Text, const decltype(line)& line = 1): toktype(Type), toktext(Text), line(line) {} + explicit tok(const type& Type, const decltype(line)& line = 1): tok(Type, std::string(1, Type), line) {}; friend std::ostream& operator<<(std::ostream& output, const tok& it) { return output << it.toktext; } }; std::vector lex(const std::string& in); From cca696b27a7271251291cf42b2c29b35b8a41455 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 4 Mar 2022 19:30:58 +0100 Subject: [PATCH 082/254] Fix the line number of next in Parser.hpp Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index dc4e35c..69ac05e 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -33,7 +33,7 @@ namespace Parser { }; for (;i < lexed.size(); ++i) { const bool hasNext = (i + 1) < lexed.size(); - const tok& current = lexed[i], next = hasNext ? lexed[i + 1] : tok(UNEXPECTED); + const tok& current = lexed[i], next = hasNext ? lexed[i + 1] : tok(UNEXPECTED, current.line); switch (current.toktype) { case STRING: parseTree << types::String(current.toktext.data()); break; From 8e7aaadbd05c89cb9e3b0f519643174dcafcd2fd Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 9 Mar 2022 19:28:59 +0100 Subject: [PATCH 083/254] Rename parseVector to parse in Parser.hpp, and make the parameter a span instead of a vector Signed-off-by: Username404 --- src/headers/misc.hpp | 2 +- src/headers/parsing/Parser.hpp | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/headers/misc.hpp b/src/headers/misc.hpp index 0962dee..f741593 100644 --- a/src/headers/misc.hpp +++ b/src/headers/misc.hpp @@ -6,6 +6,6 @@ void outputFileContent(const string& file, string_view content); #include "lex.hpp" #include "parsing/Parser.hpp" -inline auto parseString(const string& toParse) { return Parser::parseVector(lex(toParse)); } +inline auto parseString(const string& toParse) { return Parser::parse(lex(toParse)); } #endif //YERBACON_MISC_HPP \ No newline at end of file diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 69ac05e..20e612d 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -5,6 +5,7 @@ #include "ParseComponents.hpp" #include "../Yerbacon.hpp" #include +#include namespace Parser { typedef Yerbacon::Exception ParsingException; @@ -16,7 +17,7 @@ namespace Parser { const bool& quoteTokenText = false ) { error(token, text, token.line, quoteTokenText); } IS(ParseTree) - T parseVector(const vector& lexed) { + T parse(const span&& lexed) { T parseTree; using namespace StandardComponents; using enum tok::type; @@ -63,11 +64,11 @@ namespace Parser { } case LPAR: case LBRACE: case LBRACKET: { const auto inverseCharacter = tok::inverseLCharacter(current.toktype); - const auto closingCharacter = find_if(lexed.cbegin() + i, lexed.cend(), [&inverseCharacter](const tok& it){ + const auto closingCharacter = find_if(lexed.begin() + i, lexed.end(), [&inverseCharacter](const tok& it){ return it.toktype == inverseCharacter; }); - if (closingCharacter != lexed.cend()) { - vector subTokens(lexed.cbegin() + i + 1, closingCharacter); + if (closingCharacter != lexed.end()) { + vector subTokens(lexed.begin() + i + 1, closingCharacter); if (current.toktype == LPAR || current.toktype == LBRACKET) { if (subTokens.size() >= 2 && subTokens[1].toktype != RPAR) { for (auto iterator = subTokens.cbegin(); iterator < (subTokens.cend() - 1); ++iterator) { @@ -79,12 +80,12 @@ namespace Parser { } } switch (current.toktype) { - case LPAR: parseTree << parseVector(subTokens); break; + case LPAR: parseTree << parse(subTokens); break; case LBRACE: // TODO Add structures for class/function bodies case LBRACKET: - default: parseTree << parseVector(subTokens); break; + default: parseTree << parse(subTokens); break; } - i = distance(lexed.cbegin(), closingCharacter); + i = distance(lexed.begin(), closingCharacter); } else parsingError(current, string(" is missing a closing \"").append(1, inverseCharacter) + '"', true); break; } From 2425d19f9f445182a8c357f8d3269ca7c7a438ae Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 9 Mar 2022 20:47:15 +0100 Subject: [PATCH 084/254] Add a Parser::parse overload which takes input iterators as arguments Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 20e612d..2ea29ed 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -16,6 +16,10 @@ namespace Parser { const tok& token, const string& text, const bool& quoteTokenText = false ) { error(token, text, token.line, quoteTokenText); } + + IS(ParseTree) + inline T parse(const input_iterator auto&, const input_iterator auto&); + IS(ParseTree) T parse(const span&& lexed) { T parseTree; @@ -95,6 +99,8 @@ namespace Parser { } return parseTree; } + template T> + inline T parse(const input_iterator auto& begin, const input_iterator auto& end) { return parse(span(begin, end)); } } #endif //YERBACON_PARSER_HPP \ No newline at end of file From 74c5904d219bd9e19cbba4bf8f970ed2d5561fa0 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 12 Mar 2022 11:16:14 +0100 Subject: [PATCH 085/254] Add a character cast operator to tok in lex.hpp Signed-off-by: Username404 --- src/headers/lex.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/headers/lex.hpp b/src/headers/lex.hpp index 8035055..41a8334 100644 --- a/src/headers/lex.hpp +++ b/src/headers/lex.hpp @@ -26,6 +26,7 @@ struct tok { tok() = delete; tok(const type& Type, std::string_view Text, const decltype(line)& line = 1): toktype(Type), toktext(Text), line(line) {} explicit tok(const type& Type, const decltype(line)& line = 1): tok(Type, std::string(1, Type), line) {}; + operator char() const { return static_cast(toktype); } friend std::ostream& operator<<(std::ostream& output, const tok& it) { return output << it.toktext; } }; std::vector lex(const std::string& in); From b47c8b3dc72bdd8bc1fe4c19eaa4f6e447199fc2 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 13 Mar 2022 10:23:06 +0100 Subject: [PATCH 086/254] Add a "Build for other architectures" stage to the Jenkinsfile Signed-off-by: Username404 --- Jenkinsfile | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 01879d2..52d5da6 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -37,10 +37,16 @@ pipeline { // Multi-branch pipeline script for Yerbacon. echo "Building the ${env.BRANCH_NAME} branch.." buildTarget('x86_64-linux-gnu', 'x86_64', 'amd64') buildTarget('i686-linux-gnu', 'i386', 'i386') - buildTarget('arm-linux-gnueabi', 'armv4l', 'armel') - buildTarget('arm-linux-gnueabihf', 'armv7hl', 'armhf') - buildTarget('aarch64-linux-gnu', 'aarch64', 'arm64', false) - buildTarget('riscv64-linux-gnu', 'riscv64', 'riscv64') + } + } + stage('Build for other architectures') { + steps { + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + buildTarget('arm-linux-gnueabi', 'armv4l', 'armel') + buildTarget('arm-linux-gnueabihf', 'armv7hl', 'armhf') + buildTarget('aarch64-linux-gnu', 'aarch64', 'arm64', false) + buildTarget('riscv64-linux-gnu', 'riscv64', 'riscv64') + } } } stage('Build for other platforms') { From f3d03adeaddeda1c0e8c51ac2a3a32515efb4a26 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 13 Mar 2022 15:11:07 +0100 Subject: [PATCH 087/254] Add functions, indentation, better variables parsing and more Signed-off-by: Username404 --- src/etc/lexer.cpp | 10 ++- src/headers/lex.hpp | 14 ++++ src/headers/parsing/ParseComponents.hpp | 16 +++- src/headers/parsing/Parser.hpp | 76 +++++++++++++------ src/headers/transpiler/Target.hpp | 66 +++++++++------- src/headers/transpiler/implementations/Js.hpp | 12 ++- .../transpiler/implementations/Lua.hpp | 11 ++- src/headers/transpiler/implementations/Py.hpp | 10 ++- src/main.cpp | 5 +- 9 files changed, 155 insertions(+), 65 deletions(-) diff --git a/src/etc/lexer.cpp b/src/etc/lexer.cpp index 4a048b0..22ffbd2 100644 --- a/src/etc/lexer.cpp +++ b/src/etc/lexer.cpp @@ -17,6 +17,12 @@ vector lex(const string& in) const char& current = in[i]; switch (current) { + case LPAR: case LBRACE: case LBRACKET: { + const auto reversedCharacter = static_cast(tok::inverseLCharacter(current)); + if (find_corresponding(in.cbegin() + i + 1, in.cend(), current, reversedCharacter) != in.cend()) { + goto insertToken; + } else throw tok::LexerException(string("Missing \"") + reversedCharacter + "\" character", lineNumber); + } case DIVIDE: if (in[i + 1] == current) i += 2; else goto insertToken; case TAG: { if (current == TAG && in[i + 1] == DEFINE) { // See the IDENTIFIER case in Parser.hpp @@ -42,8 +48,8 @@ vector lex(const string& in) break; } else goto insertToken; } - case DEFINE: case LPAR: case RPAR: case COMMA: - case LBRACE: case RBRACE: case LBRACKET: case RBRACKET: + case DEFINE: case RPAR: case COMMA: + case RBRACE: case RBRACKET: case PLUS: case HYPHEN: case LCOMP: case RCOMP: case DOT: case DOLLAR_SIGN: case SQUOTE: insertToken: resVal.emplace_back(static_cast(current), lineNumber); diff --git a/src/headers/lex.hpp b/src/headers/lex.hpp index 41a8334..b578b84 100644 --- a/src/headers/lex.hpp +++ b/src/headers/lex.hpp @@ -5,6 +5,7 @@ #include "Yerbacon.hpp" #include #include +#include struct tok { typedef Yerbacon::Exception LexerException; @@ -29,6 +30,19 @@ struct tok { operator char() const { return static_cast(toktype); } friend std::ostream& operator<<(std::ostream& output, const tok& it) { return output << it.toktext; } }; + +auto find_corresponding(std::input_iterator auto begin, std::input_iterator auto end, const unsigned char open, const unsigned char close) { + unsigned short occurrences = 1; + return std::find_if(begin, end, [&open, &close, &occurrences](const char& it){ + if (it == open) { + ++occurrences; + } else if (it == close) { + return --occurrences == 0; + } + return false; + }); +} + std::vector lex(const std::string& in); #endif //YERBACON_TEST_H \ No newline at end of file diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index f4e5877..5130c06 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -23,6 +23,7 @@ struct ParseComponent { struct NamedIdentifier: virtual ParseComponent { const string name; explicit NamedIdentifier(string_view nameText): name(nameText) {} + NamedIdentifier() = default; }; typedef unique_ptr component_ptr; @@ -95,8 +96,10 @@ public: namespace StandardComponents { struct Define: NamedIdentifier { const bool final; - explicit Define(const bool& isFinal, string_view nameText): NamedIdentifier(nameText), final(isFinal) {} - explicit Define(string_view nameText): Define(false, nameText) {} + ParseTree content; + explicit Define(const bool& isFinal, string_view nameText, ParseTree&& content): NamedIdentifier(nameText), final(isFinal), content(move(content)) {} + explicit Define(string_view nameText, ParseTree&& content): Define(false, nameText, move(content)) {} + Define(Define&& define) noexcept: Define(define.final, define.name, move(define.content)) {} }; struct Reference: NamedIdentifier { using NamedIdentifier::NamedIdentifier; @@ -107,9 +110,16 @@ namespace StandardComponents { explicit String(const char* string): content(string) {} }; } - struct Call: ParseTree {}; + struct Call: ParseTree, Reference { + using Reference::Reference; + }; + struct Function: NamedIdentifier, ParseTree { + ParseTree parameters; + using NamedIdentifier::NamedIdentifier; + }; struct Class: NamedIdentifier { + ParseTree body; using NamedIdentifier::NamedIdentifier; }; } diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 2ea29ed..7b68e15 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -6,6 +6,7 @@ #include "../Yerbacon.hpp" #include #include +#include namespace Parser { typedef Yerbacon::Exception ParsingException; @@ -50,6 +51,22 @@ namespace Parser { parsingError(next, hasNext ? " is not a valid class identifier" : "A class identifier is required", hasNext); } } else { + unsigned int parametersDistance = 0; + if (next.toktype == LPAR) { + const auto it = find_if(lexed.begin() + i, lexed.end(), [](const tok& token){ return token.toktype == RPAR; }); + parametersDistance = distance(lexed.begin() + i, it); + i += parametersDistance; + } + if (nextAre({LCOMP, LCOMP, LBRACE})) { + Function function(current.toktext); + if (parametersDistance > 2) { + function.parameters = parse(lexed.begin() + ((i + 2) - parametersDistance), lexed.begin() + i); + } + parseTree << function; + i += 2; + break; + } else i -= parametersDistance; + bool isFinalDefine = nextAre({TAG, DEFINE}); if (isFinalDefine || next.toktype == DEFINE) { const optional previousDefinition = parseTree.template findReferenceByName(current.toktext); @@ -58,39 +75,48 @@ namespace Parser { parsingError(current, previousDefinition->get().final ? " cannot be redefined as it is final" : " cannot be made final after it has been declared", true); } } - parseTree << Define(isFinalDefine, current.toktext); - i += 1 + isFinalDefine; - } else { + parseTree << Define(isFinalDefine, current.toktext, parse( // TODO Find another way of choosing the tokens to parse + lexed.begin() + i + 2 + isFinalDefine, find_if(lexed.begin() + i + 2 + isFinalDefine, lexed.end(), [¤t](const tok& it){ + return it.line != current.line; + }) + )); + i += 2 + isFinalDefine; + } else if (next.toktype == '(') { + parseTree << Call(current.toktext); + } else parseTree << Reference(current.toktext); } } break; - } case LPAR: case LBRACE: case LBRACKET: { - const auto inverseCharacter = tok::inverseLCharacter(current.toktype); - const auto closingCharacter = find_if(lexed.begin() + i, lexed.end(), [&inverseCharacter](const tok& it){ - return it.toktype == inverseCharacter; - }); - if (closingCharacter != lexed.end()) { - vector subTokens(lexed.begin() + i + 1, closingCharacter); - if (current.toktype == LPAR || current.toktype == LBRACKET) { - if (subTokens.size() >= 2 && subTokens[1].toktype != RPAR) { - for (auto iterator = subTokens.cbegin(); iterator < (subTokens.cend() - 1); ++iterator) { - const auto nextIterator = iterator + 1; - if (nextIterator->toktype == COMMA) { - subTokens.erase(nextIterator); - } else throw ParsingException("Missing comma after \"" + iterator->toktext + '"'); - } + const auto closingCharacter = find_corresponding(lexed.begin() + i + 1, lexed.end(), current.toktype, tok::inverseLCharacter(current.toktype)); + vector subTokens(lexed.begin() + i + 1, closingCharacter); + if (current.toktype == LPAR || current.toktype == LBRACKET) { + if (subTokens.size() >= 2 && subTokens[1].toktype != RPAR) { + for (auto iterator = subTokens.cbegin(); iterator < (subTokens.cend() - 1); ++iterator) { + const auto nextIterator = iterator + 1; + if (nextIterator->toktype == COMMA) { + subTokens.erase(nextIterator); + } else throw ParsingException("Missing comma after \"" + iterator->toktext + '"'); } } - switch (current.toktype) { - case LPAR: parseTree << parse(subTokens); break; - case LBRACE: // TODO Add structures for class/function bodies - case LBRACKET: - default: parseTree << parse(subTokens); break; + } + const component_ptr& previous = parseTree.at(parseTree.size() - 1); + if (current.toktype == LPAR) { + try { + dynamic_cast(*previous).ParseTree::operator=(parse(subTokens)); + } catch (const bad_cast&) { + parsingError(current, "Unexpected parenthesis"); } - i = distance(lexed.begin(), closingCharacter); - } else parsingError(current, string(" is missing a closing \"").append(1, inverseCharacter) + '"', true); + } else if (current.toktype == LBRACE) { + const type_info& previous_id = previous->getId(); + if (previous_id == typeid(Function)) { + dynamic_cast(*previous).ParseTree::operator=(parse(subTokens)); + } else if (previous_id == typeid(Class)) { + dynamic_cast(*previous).body = parse(subTokens); + } + } else parseTree << parse(subTokens); + i = distance(lexed.begin(), closingCharacter); break; } case RPAR: case RBRACE: case RBRACKET: parsingError(current, " \u27F5 Unexpected character", true); diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 235b3e0..eb758e9 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -74,33 +74,58 @@ protected: typedef pair print_functions_pair; virtual unordered_task_map getTaskMap() = 0; virtual print_functions_pair printFunctions() = 0; - void transpileTree(const derived_from auto& parseTree) { + IS(ParseTree) + void transpileTree(const T& parseTree, const unsigned short& indentationLevel = 0, const function&& postInsertionFunction = [](auto&){}) { if (parseTree.size() > 0) { - unsigned int subIndex = 0; - for (auto pointer_iterator = parseTree.cbegin(); pointer_iterator < parseTree.cend(); ++pointer_iterator) { - getTaskMapInstance().at(pointer_iterator->get()->getId())(parseTree, subIndex); ++subIndex; - if ((pointer_iterator + 1) != parseTree.cend() && parseTree.getId() == typeid(StandardComponents::Call)) { - output << ", "; + const auto added_size = indentationLevel * strlen(indentation); + if (newLines) { + separator.reserve(separator.size() + added_size); + for (unsigned short level = 0; level < indentationLevel; ++level) { + separator.append(indentation); } } + unsigned int subIndex = 0; + for (auto pointer_iterator = parseTree.cbegin(); pointer_iterator < parseTree.cend(); ++pointer_iterator) { + const type_info& id = pointer_iterator->get()->getId(); + try { + getTaskMapInstance().at(id)(parseTree, subIndex); ++subIndex; + } catch (const out_of_range&) { + throw Yerbacon::Exception(string( + #ifndef __GNUC__ + id.name() + #else + abi::__cxa_demangle(id.name(), nullptr, nullptr, nullptr) + #endif + ) += " is not supported by the current target"); + } + postInsertionFunction(pointer_iterator); + } + if (newLines) separator.erase(separator.size() - added_size); } } + IS(ParseTree) + void separate_transpileTree(const T& parseTree, const unsigned short& indentationLevel = 0) { + transpileTree(parseTree, indentationLevel, [this, &parseTree](const auto& iterator){ + if (iterator + 1 != parseTree.cend()) { + output << separator; + } + }); + } typedef optional optional_string; virtual optional_string uniqueLineSeparator() { return ";"; }; const bool newLines; - const char* separator; + string separator; + static constexpr const char* indentation = " "; public: const unordered_task_map& getTaskMapInstance() { static unordered_task_map staticMap = getTaskMap(); // Default / Shared tasks: staticMap.merge(unordered_task_map({ make_task(ParseTree, transpileTree(parseComponent);), - make_task(StandardComponents::Reference, - const auto print_functions = printFunctions(); - output << ((parseComponent.name == "print") ? print_functions.first : (parseComponent.name == "print_line") ? print_functions.second : parseComponent.name); - ), + make_task(StandardComponents::Reference, output << parseComponent.name;), make_task(StandardComponents::Call, - output << '('; + const auto print_functions = printFunctions(); + output << ((parseComponent.name == "print") ? print_functions.first : (parseComponent.name == "print_line") ? print_functions.second : parseComponent.name) << '('; transpileTree(parseComponent); output << ')'; ) @@ -110,23 +135,8 @@ public: static shared_ptr forName(string_view name, bool newLines); string transpileWithTree(const ParseTree& tree) { separator = newLines ? "\n" : (supportsOneLine() ? uniqueLineSeparator().value() : throw Yerbacon::Exception("--newlines=off is not supported by the current target")); - const unordered_task_map& taskMap = getTaskMapInstance(); output.str(string()); - for (unsigned int i = 0; i < tree.size(); ++i) { - const component_ptr& component = tree[i]; - const type_info& id = component->getId(); - try { - taskMap.at(id)(tree, i); - } catch (const out_of_range&) { - throw Yerbacon::Exception(string( - #ifndef __GNUC__ - id.name() - #else - abi::__cxa_demangle(id.name(), nullptr, nullptr, nullptr) - #endif - ) += " is not supported by the current target"); - } - } + separate_transpileTree(tree); return output.str() + '\n'; }; explicit Target(const bool& newLines): newLines(newLines), separator() {}; diff --git a/src/headers/transpiler/implementations/Js.hpp b/src/headers/transpiler/implementations/Js.hpp index 60c476f..9c0da05 100644 --- a/src/headers/transpiler/implementations/Js.hpp +++ b/src/headers/transpiler/implementations/Js.hpp @@ -8,8 +8,18 @@ struct JsTarget: Target { return { make_task(Define, output << (parseComponent.final ? "const " : "let ") << parseComponent.name << " = "; + transpileTree(parseComponent.content); ), - make_task(types::String, stringInterpolation(parseComponent.content);) + make_task(types::String, stringInterpolation(parseComponent.content);), + make_task(Function, + output << "function " << parseComponent.name << '('; + transpileTree(parseComponent.parameters); + output << ") {"; + if (newLines) output << separator << indentation; + separate_transpileTree(parseComponent, 1); + if (newLines) output << separator; + output << '}'; + ) }; } using Target::Target; diff --git a/src/headers/transpiler/implementations/Lua.hpp b/src/headers/transpiler/implementations/Lua.hpp index d8c9b58..bfdc7f4 100644 --- a/src/headers/transpiler/implementations/Lua.hpp +++ b/src/headers/transpiler/implementations/Lua.hpp @@ -12,8 +12,17 @@ struct LuaTarget: Target { output << parseComponent.name; if (parseComponent.final) output << " "; // TODO Find an alternative to for lua <5.4 output << " = "; + transpileTree(parseComponent.content); ), - make_task(types::String, stringInterpolation(parseComponent.content, "[[", "]]", "..");) + make_task(types::String, stringInterpolation(parseComponent.content, "[[", "]]", "..");), + make_task(Function, + output << "function " << parseComponent.name << '('; + transpileTree(parseComponent.parameters); + output << ')' << separator; + if (newLines) output << indentation; + separate_transpileTree(parseComponent, 1); + output << separator << "end"; + ) }; } using Target::Target; diff --git a/src/headers/transpiler/implementations/Py.hpp b/src/headers/transpiler/implementations/Py.hpp index 2b2396a..8a71409 100644 --- a/src/headers/transpiler/implementations/Py.hpp +++ b/src/headers/transpiler/implementations/Py.hpp @@ -7,8 +7,14 @@ struct PyTarget: Target { optional_string uniqueLineSeparator() final { return {}; } unordered_task_map getTaskMap() final { return { - make_task(Define, output << parseComponent.name << " = ";), - make_task(types::String, stringInterpolation(R"(""")", parseComponent.content);) + make_task(Define, output << parseComponent.name << " = "; transpileTree(parseComponent.content);), + make_task(types::String, stringInterpolation(R"(""")", parseComponent.content);), + make_task(Function, + output << "def " << parseComponent.name << '('; + transpileTree(parseComponent.parameters); + output << "):" << separator << indentation; + separate_transpileTree(parseComponent, 1); + ), }; } using Target::Target; diff --git a/src/main.cpp b/src/main.cpp index 45a9656..4bed4eb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,9 +46,8 @@ int main(int argc, char* argv[]) { } else invalid_argument: Yerbacon::fail({"\"", currentArg.data(), "\" is not a valid argument."}); } } - const auto currentTarget = Target::forName(target, newLines); - const auto compile = [&target, ¤tTarget](string_view name) -> string { - string transpiledString = currentTarget->transpileWithTree(parseString(getFileContent(name.data()))); + const auto compile = [&target, &newLines](string_view name) -> string { + string transpiledString = Target::forName(target, newLines)->transpileWithTree(parseString(getFileContent(name.data()))); name.remove_suffix(6); string outputFile; (outputFile = name).append(target); From f21a79fb29b98fca0daf3ffced98508e537416b2 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 13 Mar 2022 15:39:16 +0100 Subject: [PATCH 088/254] Include Yerbacon.hpp in filefuncs.cpp Signed-off-by: Username404 --- src/etc/filefuncs.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/etc/filefuncs.cpp b/src/etc/filefuncs.cpp index b7f44f7..d379fb5 100644 --- a/src/etc/filefuncs.cpp +++ b/src/etc/filefuncs.cpp @@ -1,6 +1,7 @@ #include #include #include +#include "../headers/Yerbacon.hpp" using namespace std; string getFileContent(const string& file) From 4057423b8f62ad26c9563c43e33a91e9d252b21c Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 13 Mar 2022 15:42:02 +0100 Subject: [PATCH 089/254] Set CMAKE_DISABLE_PRECOMPILE_HEADERS to "ON" in the Jenkinsfile Signed-off-by: Username404 --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 52d5da6..5ec256f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -3,7 +3,7 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: "cmake-build-${packageArch}${suffix}", buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=/usr/bin/${path}-ld.gold -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS_PRIVATE_DIRS=/usr/${path}/lib/ -DNO_CCACHE=ON", + cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=/usr/bin/${path}-ld.gold -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS_PRIVATE_DIRS=/usr/${path}/lib/ -DNO_CCACHE=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON", generator: fileExists('/usr/bin/ninja') ? 'Ninja' : 'Unix Makefiles' cmake arguments: "--build ./cmake-build-${packageArch}${suffix} --target ybcon", installation: 'Latest' sh "/usr/bin/${path}-strip -s ./cmake-build-${packageArch}${suffix}/ybcon*" From 6dc658664af8e2a984ce3860f2d7bcd56d60b4f8 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 13 Mar 2022 21:49:28 +0100 Subject: [PATCH 090/254] Make the stage result 'UNSTABLE' when arm mingw32 targets fail to build in the Jenkinsfile Signed-off-by: Username404 --- Jenkinsfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 5ec256f..90d1ba8 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -54,6 +54,8 @@ pipeline { // Multi-branch pipeline script for Yerbacon. catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { buildTarget('x86_64-w64-mingw32', 'x86_64', 'amd64', true, windowsSuffix) buildTarget('i686-w64-mingw32', 'i386', 'i386', true, windowsSuffix) + } + catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') { buildTarget('armv7-w64-mingw32', 'armv7hl', 'armhf', true, windowsSuffix) buildTarget('aarch64-w64-mingw32', 'aarch64', 'arm64', false, windowsSuffix) } From bd6212daea526bfe90e9e00349c7911e8f6e61fb Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 13 Mar 2022 21:55:07 +0100 Subject: [PATCH 091/254] Build x86_64 and i686 mingw32 targets before arm targets to give priority to the FAILURE stage result in the Jenkinsfile Signed-off-by: Username404 --- Jenkinsfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 90d1ba8..6c1f72e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -51,14 +51,14 @@ pipeline { // Multi-branch pipeline script for Yerbacon. } stage('Build for other platforms') { steps { - catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { - buildTarget('x86_64-w64-mingw32', 'x86_64', 'amd64', true, windowsSuffix) - buildTarget('i686-w64-mingw32', 'i386', 'i386', true, windowsSuffix) - } catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') { buildTarget('armv7-w64-mingw32', 'armv7hl', 'armhf', true, windowsSuffix) buildTarget('aarch64-w64-mingw32', 'aarch64', 'arm64', false, windowsSuffix) } + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + buildTarget('x86_64-w64-mingw32', 'x86_64', 'amd64', true, windowsSuffix) + buildTarget('i686-w64-mingw32', 'i386', 'i386', true, windowsSuffix) + } } } stage('Deploy') { From fb1ec6813f61897ee98eff92890bc2b4bdeb43cb Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 13 Mar 2022 22:12:51 +0100 Subject: [PATCH 092/254] Require clang 14.0 or higher Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index debd24d..05880e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ endif() set(CMAKE_CXX_FLAGS "-Wall") set(CMAKE_CXX_FLAGS_RELEASE "-Os") set(MINIMAL_GNU "11.0") -set(MINIMAL_CLANG "13.0") +set(MINIMAL_CLANG "14.0") set(MINIMAL_MSVC "19.25") set(IS_GNU (${CMAKE_CXX_COMPILER_ID} STREQUAL GNU)) set(IS_CLANG (${CMAKE_CXX_COMPILER_ID} STREQUAL Clang)) From 1f819bc136ac34ce64af6e6b8b960283eab1652e Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 13 Mar 2022 22:31:34 +0100 Subject: [PATCH 093/254] When parsing a function call, invoke parse without specialization since the "=" operator needs a ParseTree Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 7b68e15..ed6a580 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -104,7 +104,7 @@ namespace Parser { const component_ptr& previous = parseTree.at(parseTree.size() - 1); if (current.toktype == LPAR) { try { - dynamic_cast(*previous).ParseTree::operator=(parse(subTokens)); + dynamic_cast(*previous).ParseTree::operator=(parse(subTokens)); } catch (const bad_cast&) { parsingError(current, "Unexpected parenthesis"); } From 513c9a44a08bb1a1aa58a9bed68104b49b352791 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 16 Mar 2022 13:51:36 +0100 Subject: [PATCH 094/254] Re-add a variable to hold the current target in main.cpp, and capture it by value in the compile function Signed-off-by: Username404 --- src/main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 4bed4eb..031c72e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,8 +46,9 @@ int main(int argc, char* argv[]) { } else invalid_argument: Yerbacon::fail({"\"", currentArg.data(), "\" is not a valid argument."}); } } - const auto compile = [&target, &newLines](string_view name) -> string { - string transpiledString = Target::forName(target, newLines)->transpileWithTree(parseString(getFileContent(name.data()))); + const auto current_target = Target::forName(target, newLines); + const auto compile = [&target, current_target](string_view name) -> string { + string transpiledString = current_target->transpileWithTree(parseString(getFileContent(name.data()))); name.remove_suffix(6); string outputFile; (outputFile = name).append(target); From 98435c90ae86ded0da199bfad9d910dd1b1ae70e Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 16 Mar 2022 22:10:17 +0100 Subject: [PATCH 095/254] Update the linux target requirements in the README.md Signed-off-by: Username404 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aea8514..619080d 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ CMake 3.18 or higher is needed. ### Linux target -- GCC 11+ or Clang 13+ with llvm-gold +- GCC 11+ or Clang 14+ with llvm-gold ### Windows target From 272323d0916d372aede91aa3da40d518b77e832a Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 17 Mar 2022 15:42:54 +0100 Subject: [PATCH 096/254] Add two local variables to Parser.hpp Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index ed6a580..7335bab 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -75,12 +75,14 @@ namespace Parser { parsingError(current, previousDefinition->get().final ? " cannot be redefined as it is final" : " cannot be made final after it has been declared", true); } } + const unsigned increment = 2 + isFinalDefine; + const auto beginning = lexed.begin() + i + increment; parseTree << Define(isFinalDefine, current.toktext, parse( // TODO Find another way of choosing the tokens to parse - lexed.begin() + i + 2 + isFinalDefine, find_if(lexed.begin() + i + 2 + isFinalDefine, lexed.end(), [¤t](const tok& it){ + beginning, find_if(beginning, lexed.end(), [¤t](const tok& it){ return it.line != current.line; }) )); - i += 2 + isFinalDefine; + i += increment; } else if (next.toktype == '(') { parseTree << Call(current.toktext); } else From bee9917947c3827e79f4c09a35beabb638699b3d Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 17 Mar 2022 15:49:01 +0100 Subject: [PATCH 097/254] Use LPAR instead of a character in a condition of Parser.hpp Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 7335bab..bb7c02d 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -83,7 +83,7 @@ namespace Parser { }) )); i += increment; - } else if (next.toktype == '(') { + } else if (next.toktype == LPAR) { parseTree << Call(current.toktext); } else parseTree << Reference(current.toktext); From 5f3c8d785d4a28df244dda037974b1a3302f13e4 Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 17 Mar 2022 16:42:28 +0100 Subject: [PATCH 098/254] Use to_address instead of the unique_ptr::get function in ParseTree::findById Signed-off-by: Username404 --- src/headers/parsing/ParseComponents.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index 5130c06..7d709fb 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -62,7 +62,7 @@ public: vector filteredComponents; for_each(cbegin(), cend(), [&filteredComponents](const component_ptr& it) { if (it->getId() == typeid(T)) { - filteredComponents.push_back(dynamic_cast(it.get())); + filteredComponents.push_back(dynamic_cast(to_address(it))); } }); return filteredComponents; From ba14e95d50445a2312ffe8f12244db724465609a Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 19 Mar 2022 12:40:14 +0100 Subject: [PATCH 099/254] Add a separate_transpileTree overload and transpile function parameters correctly Signed-off-by: Username404 --- src/headers/transpiler/Target.hpp | 10 +++++++--- src/headers/transpiler/implementations/Js.hpp | 2 +- src/headers/transpiler/implementations/Lua.hpp | 2 +- src/headers/transpiler/implementations/Py.hpp | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index eb758e9..8620fdf 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -106,9 +106,13 @@ protected: IS(ParseTree) void separate_transpileTree(const T& parseTree, const unsigned short& indentationLevel = 0) { transpileTree(parseTree, indentationLevel, [this, &parseTree](const auto& iterator){ - if (iterator + 1 != parseTree.cend()) { - output << separator; - } + if (iterator + 1 != parseTree.cend()) { output << separator; } + }); + } + IS(ParseTree) + void separate_transpileTree(const T& parseTree, const string_view separation_characters) { + transpileTree(parseTree, 0, [this, &parseTree, &separation_characters](const auto& iterator){ + if (iterator + 1 != parseTree.cend()) { output << separation_characters; } }); } typedef optional optional_string; diff --git a/src/headers/transpiler/implementations/Js.hpp b/src/headers/transpiler/implementations/Js.hpp index 9c0da05..7c11394 100644 --- a/src/headers/transpiler/implementations/Js.hpp +++ b/src/headers/transpiler/implementations/Js.hpp @@ -13,7 +13,7 @@ struct JsTarget: Target { make_task(types::String, stringInterpolation(parseComponent.content);), make_task(Function, output << "function " << parseComponent.name << '('; - transpileTree(parseComponent.parameters); + separate_transpileTree(parseComponent.parameters, ", "); output << ") {"; if (newLines) output << separator << indentation; separate_transpileTree(parseComponent, 1); diff --git a/src/headers/transpiler/implementations/Lua.hpp b/src/headers/transpiler/implementations/Lua.hpp index bfdc7f4..421e944 100644 --- a/src/headers/transpiler/implementations/Lua.hpp +++ b/src/headers/transpiler/implementations/Lua.hpp @@ -17,7 +17,7 @@ struct LuaTarget: Target { make_task(types::String, stringInterpolation(parseComponent.content, "[[", "]]", "..");), make_task(Function, output << "function " << parseComponent.name << '('; - transpileTree(parseComponent.parameters); + separate_transpileTree(parseComponent.parameters, ", "); output << ')' << separator; if (newLines) output << indentation; separate_transpileTree(parseComponent, 1); diff --git a/src/headers/transpiler/implementations/Py.hpp b/src/headers/transpiler/implementations/Py.hpp index 8a71409..2e58832 100644 --- a/src/headers/transpiler/implementations/Py.hpp +++ b/src/headers/transpiler/implementations/Py.hpp @@ -11,7 +11,7 @@ struct PyTarget: Target { make_task(types::String, stringInterpolation(R"(""")", parseComponent.content);), make_task(Function, output << "def " << parseComponent.name << '('; - transpileTree(parseComponent.parameters); + separate_transpileTree(parseComponent.parameters, ", "); output << "):" << separator << indentation; separate_transpileTree(parseComponent, 1); ), From 3a7553166488d1955ef74569693452b8afe67e67 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 19 Mar 2022 13:09:46 +0100 Subject: [PATCH 100/254] Transpile arguments correctly in Target.hpp Signed-off-by: Username404 --- src/headers/transpiler/Target.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 8620fdf..ec8e129 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -130,7 +130,7 @@ public: make_task(StandardComponents::Call, const auto print_functions = printFunctions(); output << ((parseComponent.name == "print") ? print_functions.first : (parseComponent.name == "print_line") ? print_functions.second : parseComponent.name) << '('; - transpileTree(parseComponent); + separate_transpileTree(parseComponent, ", "); output << ')'; ) })); From 01abadc1faf2635374774666c88a8e29ea5b108f Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 19 Mar 2022 16:28:32 +0100 Subject: [PATCH 101/254] Use cmp_less instead of cmp_greater in Parser.hpp Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index bb7c02d..ccb2c0a 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -30,7 +30,7 @@ namespace Parser { const auto nextAre = [&i, &lexed] Y>(const initializer_list& nextValues) -> bool { unsigned int j = 1; for (const Y& nextValue: nextValues) { - if (!cmp_greater(lexed.size() - i, nextValues.size()) || lexed[i + j].toktype != nextValue) { + if (cmp_less(lexed.size() - i, nextValues.size()) || lexed[i + j].toktype != nextValue) { return false; } ++j; From adbe98ec00afe2fd8b755ff5d6c464172191ed87 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 22 Mar 2022 13:14:32 +0100 Subject: [PATCH 102/254] Increment i after finding the end iterator when parsing variables Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index ccb2c0a..907bdf6 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -77,12 +77,11 @@ namespace Parser { } const unsigned increment = 2 + isFinalDefine; const auto beginning = lexed.begin() + i + increment; - parseTree << Define(isFinalDefine, current.toktext, parse( // TODO Find another way of choosing the tokens to parse - beginning, find_if(beginning, lexed.end(), [¤t](const tok& it){ - return it.line != current.line; - }) - )); - i += increment; + const auto end = find_if(beginning, lexed.end(), [¤t](const tok& it){ // TODO Find another way of choosing the tokens to parse + return it.line != current.line; + }); + parseTree << Define(isFinalDefine, current.toktext, parse(beginning, end)); + i += 1 + isFinalDefine + distance(beginning, end); } else if (next.toktype == LPAR) { parseTree << Call(current.toktext); } else From 8a97def6b29c50ec19333debfab3c6e174aece26 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 22 Mar 2022 13:40:17 +0100 Subject: [PATCH 103/254] Add integer parsing Signed-off-by: Username404 --- src/headers/parsing/ParseComponents.hpp | 4 ++++ src/headers/parsing/Parser.hpp | 10 ++++++++++ src/headers/transpiler/Target.hpp | 3 ++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index 7d709fb..ce5ef71 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -105,6 +105,10 @@ namespace StandardComponents { using NamedIdentifier::NamedIdentifier; }; namespace types { + struct Integer: ParseComponent { + long double value; + Integer(const string& value): value(stold(value)) {} + }; struct String: ParseComponent { const string content; explicit String(const char* string): content(string) {} diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 907bdf6..86afbb8 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -42,6 +42,16 @@ namespace Parser { const tok& current = lexed[i], next = hasNext ? lexed[i + 1] : tok(UNEXPECTED, current.line); switch (current.toktype) { + case NUMBER: { + types::Integer Int = current.toktext; + if (nextAre({DOT, NUMBER})) { + i += 2; + const string& right = lexed[i].toktext; + Int.value += stold(right) / pow(10, right.size()); + } + parseTree << Int; + break; + } case STRING: parseTree << types::String(current.toktext.data()); break; case IDENTIFIER: { if (current.toktext == "class" || current.toktext == "structure") { diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index ec8e129..dd6e32b 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -132,7 +132,8 @@ public: output << ((parseComponent.name == "print") ? print_functions.first : (parseComponent.name == "print_line") ? print_functions.second : parseComponent.name) << '('; separate_transpileTree(parseComponent, ", "); output << ')'; - ) + ), + make_task(StandardComponents::types::Integer, output << parseComponent.value;) })); return staticMap; }; From ce8e21ee25480f3b717ddbc7977f9ce50a5daa05 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 22 Mar 2022 15:37:08 +0100 Subject: [PATCH 104/254] Include cmath in Parser.hpp Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 86afbb8..15c5e69 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace Parser { typedef Yerbacon::Exception ParsingException; From db0ada09f6c4cfcaa15f044e07523c596e029ad7 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 22 Mar 2022 15:52:06 +0100 Subject: [PATCH 105/254] Use powl instead of pow in Parser.hpp Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 15c5e69..2516884 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -48,7 +48,7 @@ namespace Parser { if (nextAre({DOT, NUMBER})) { i += 2; const string& right = lexed[i].toktext; - Int.value += stold(right) / pow(10, right.size()); + Int.value += stold(right) / powl(10, right.size()); } parseTree << Int; break; From ca3b030fedc6d9c9be90630bedf1e8433519a6ec Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 22 Mar 2022 15:59:30 +0100 Subject: [PATCH 106/254] Delete the default constructor in Target.hpp and always initialize output Signed-off-by: Username404 --- src/headers/transpiler/Target.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index dd6e32b..795aac7 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -144,7 +144,8 @@ public: separate_transpileTree(tree); return output.str() + '\n'; }; - explicit Target(const bool& newLines): newLines(newLines), separator() {}; + explicit Target(const bool& newLines): output(), newLines(newLines), separator() {}; + Target() = delete; virtual ~Target() = default; }; From 88d0774d30f7feff986c1baf19a92e8d1eef4fa5 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 22 Mar 2022 18:17:36 +0100 Subject: [PATCH 107/254] Fix the precision of StandardComponents::types::Integer Signed-off-by: Username404 --- src/headers/parsing/ParseComponents.hpp | 6 ++++-- src/headers/parsing/Parser.hpp | 9 ++++++--- src/headers/transpiler/Target.hpp | 3 ++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index ce5ef71..e7b7b04 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -106,8 +106,10 @@ namespace StandardComponents { }; namespace types { struct Integer: ParseComponent { - long double value; - Integer(const string& value): value(stold(value)) {} + typedef uint_fast8_t precision_type; + const long double value; + const precision_type precision; + Integer(const long double& value, const precision_type& precision): value(value), precision(precision) {} }; struct String: ParseComponent { const string content; diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 2516884..02d5062 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -44,13 +44,16 @@ namespace Parser { switch (current.toktype) { case NUMBER: { - types::Integer Int = current.toktext; + long double v = stoul(current.toktext); + if (i > 0 && lexed[i - 1].toktype == HYPHEN) v = -v; + types::Integer::precision_type p = 0; if (nextAre({DOT, NUMBER})) { i += 2; const string& right = lexed[i].toktext; - Int.value += stold(right) / powl(10, right.size()); + p = min(static_cast(right.size()), numeric_limits::digits10); + v += copysign(stold(right.substr(0, p)) / powl(10, p), v); } - parseTree << Int; + parseTree << types::Integer(v, p); break; } case STRING: parseTree << types::String(current.toktext.data()); break; diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 795aac7..c649356 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef __GNUC__ #include #endif @@ -133,7 +134,7 @@ public: separate_transpileTree(parseComponent, ", "); output << ')'; ), - make_task(StandardComponents::types::Integer, output << parseComponent.value;) + make_task(StandardComponents::types::Integer, output << setprecision(parseComponent.precision) << fixed << parseComponent.value;) })); return staticMap; }; From 4a795b9ca0d6835547f77ec8d6ee8e94e252a333 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 22 Mar 2022 18:40:39 +0100 Subject: [PATCH 108/254] Specify that variables are static by default only at compile time in docs/gettingstarted.md Signed-off-by: Username404 --- docs/gettingstarted.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/gettingstarted.md b/docs/gettingstarted.md index 6fb4a38..0f6611b 100644 --- a/docs/gettingstarted.md +++ b/docs/gettingstarted.md @@ -67,7 +67,7 @@ Types are *inferred*, which means that specifying types of variables or returned Note: While primitives types (`String`, `int`, `double`, `boolean`, `float`) will be transpiled to their equivalents for the target of the transpiler, this is not the case for other types. -Every variable has a static type by default; it is possible to make a **non-final** variable dynamic by adding `dyn`/`dynamic` to the attributes or making it the return type: +Every variable has a static type by default at compile time; it is possible to make a **non-final** variable dynamic by adding `dyn`/`dynamic` to the attributes or making it the return type: ``` dyn helloWorld = 0 # helloWorld: dyn = 0 would also work helloWorld = "Hello, World!" From bc1564aadc41ca9d3af7852198388c9ad4de76de Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 27 Mar 2022 16:14:57 +0200 Subject: [PATCH 109/254] Set the MSVC minimum version to 19.30 Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 05880e7..cc4da16 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,7 @@ set(CMAKE_CXX_FLAGS "-Wall") set(CMAKE_CXX_FLAGS_RELEASE "-Os") set(MINIMAL_GNU "11.0") set(MINIMAL_CLANG "14.0") -set(MINIMAL_MSVC "19.25") +set(MINIMAL_MSVC "19.30") set(IS_GNU (${CMAKE_CXX_COMPILER_ID} STREQUAL GNU)) set(IS_CLANG (${CMAKE_CXX_COMPILER_ID} STREQUAL Clang)) From 0a90c25487e43eb54a5ebfc9761c8da976a73364 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 3 Apr 2022 11:45:54 +0200 Subject: [PATCH 110/254] Set the minimal clang version to 14.0.1 because 14.0.0 breaks a std::span constructor (which worked in 14.0.0-rc1) Signed-off-by: Username404 --- CMakeLists.txt | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cc4da16..a7559c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ endif() set(CMAKE_CXX_FLAGS "-Wall") set(CMAKE_CXX_FLAGS_RELEASE "-Os") set(MINIMAL_GNU "11.0") -set(MINIMAL_CLANG "14.0") +set(MINIMAL_CLANG "14.0.1") set(MINIMAL_MSVC "19.30") set(IS_GNU (${CMAKE_CXX_COMPILER_ID} STREQUAL GNU)) set(IS_CLANG (${CMAKE_CXX_COMPILER_ID} STREQUAL Clang)) diff --git a/README.md b/README.md index 619080d..ea764ba 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ CMake 3.18 or higher is needed. ### Linux target -- GCC 11+ or Clang 14+ with llvm-gold +- GCC 11+ or Clang 14.0.1+ with llvm-gold ### Windows target From 00a8fbaa83f7499700341ff5ee726c0bc8fe0d92 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 3 Apr 2022 12:02:49 +0200 Subject: [PATCH 111/254] Improve the Build Requirements section in the README.md file Signed-off-by: Username404 --- README.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index ea764ba..bea13d8 100644 --- a/README.md +++ b/README.md @@ -23,14 +23,11 @@ main >> { ## Build requirements -CMake 3.18 or higher is needed. +1. CMake 3.18 *or higher* -### Linux target +2. A compiler from the following list: + - GCC 11+ + - Clang 14.0.1+ with llvm-gold + - MSVC 19.30+ -- GCC 11+ or Clang 14.0.1+ with llvm-gold - -### Windows target - - - MinGW32 (on debian you will need to use the `i686-w64-mingw32-gcc-posix` executable provided by the `gcc-mingw-w64-i686-posix-runtime` package) - -MSVC could also be used instead if you are on Windows. \ No newline at end of file +Note that to build for Windows targets with a mingw toolchain on debian, you will need to use the `i686-w64-mingw32-gcc-posix` executable provided by the `gcc-mingw-w64-i686-posix-runtime` package. \ No newline at end of file From 1d3046892f24eb14342b331508e324b049d683a2 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 8 Apr 2022 10:53:19 +0200 Subject: [PATCH 112/254] Change the syntax for anonymous functions in docs/gettingstarted.md Signed-off-by: Username404 --- docs/gettingstarted.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/gettingstarted.md b/docs/gettingstarted.md index 0f6611b..1a3a146 100644 --- a/docs/gettingstarted.md +++ b/docs/gettingstarted.md @@ -7,15 +7,13 @@ helloworld #= "Hello, World!" ## 2 - (Anonymous) Functions You can make an anonymous functions using the following syntax: ``` -getHelloWorld: ~String => { +getHelloWorld: ~String #= { return "Hello, World!" } ``` The type (`~String` here, which basically means "an anonymous function that returns a String") can be omitted, see [#3](#3---types). -Note that you can make `getHelloWorld` final by replacing `=>` with `#=>`. - -To define a **named** (and mandatorily final) function, replace `=>` with `>>`: +To define a **named** (and mandatorily final) function, replace `#=` with `>>`: ``` getHelloWorld: String >> { return "Hello, World!" @@ -25,7 +23,7 @@ getHelloWorld: String >> { ### 2.1 - Main Main can be a variable named `main` that contains an anonymous function, a function named `main` or a function that has the `as_main` attribute: ``` -main #=> {} +main #= {} main >> {} as_main helloWorld >> {} ``` @@ -33,7 +31,7 @@ as_main helloWorld >> {} ### 2.2 - Function parameters Parameters can be added to an anonymous function by specifying the types as follows: ``` -addIntToString (int, String) => { a, b; +addIntToString: (int, String)~ #= { a, b; print_line(b + a) } ``` From 14b71906b7c6f8a755bdad4b317c6a179a7297f4 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 8 Apr 2022 11:01:07 +0200 Subject: [PATCH 113/254] Add a SEMICOLON token Signed-off-by: Username404 --- src/etc/lexer.cpp | 4 ++-- src/headers/lex.hpp | 2 +- src/headers/parsing/Parser.hpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/etc/lexer.cpp b/src/etc/lexer.cpp index 22ffbd2..ca773ff 100644 --- a/src/etc/lexer.cpp +++ b/src/etc/lexer.cpp @@ -49,11 +49,11 @@ vector lex(const string& in) } else goto insertToken; } case DEFINE: case RPAR: case COMMA: - case RBRACE: case RBRACKET: + case RBRACE: case RBRACKET: case SEMICOLON: case PLUS: case HYPHEN: case LCOMP: case RCOMP: case DOT: case DOLLAR_SIGN: case SQUOTE: insertToken: resVal.emplace_back(static_cast(current), lineNumber); - [[likely]] case ' ': case '\t': case '\r': case ';': break; + [[likely]] case ' ': case '\t': case '\r': break; [[likely]] case '\n': ++lineNumber; break; default: { const tok::type type = getIdentifierCharType(current); diff --git a/src/headers/lex.hpp b/src/headers/lex.hpp index b578b84..f2c3fc2 100644 --- a/src/headers/lex.hpp +++ b/src/headers/lex.hpp @@ -11,7 +11,7 @@ struct tok { typedef Yerbacon::Exception LexerException; enum type: const unsigned short { UNEXPECTED = std::numeric_limits::max() + 1, IDENTIFIER, NUMBER, ALPHACHAR, - DEFINE = '=', TAG = '#', DOLLAR_SIGN = '$', DOT = '.', COMMA = ',', + DEFINE = '=', TAG = '#', DOLLAR_SIGN = '$', DOT = '.', COMMA = ',', SEMICOLON = ';', LPAR = '(', LBRACE = '{', LBRACKET = '[', RPAR = ')', RBRACE = '}', RBRACKET = ']', PLUS = '+', HYPHEN = '-', DIVIDE = '/', diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 02d5062..a002912 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -92,7 +92,7 @@ namespace Parser { const unsigned increment = 2 + isFinalDefine; const auto beginning = lexed.begin() + i + increment; const auto end = find_if(beginning, lexed.end(), [¤t](const tok& it){ // TODO Find another way of choosing the tokens to parse - return it.line != current.line; + return it.toktype == SEMICOLON || it.line != current.line; }); parseTree << Define(isFinalDefine, current.toktext, parse(beginning, end)); i += 1 + isFinalDefine + distance(beginning, end); From 2b596e691c554907acc8889033126bede3c2a863 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 8 Apr 2022 12:46:53 +0200 Subject: [PATCH 114/254] Rename the "it" local variable to "closing" in Parser.hpp Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index a002912..4ce100b 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -67,8 +67,8 @@ namespace Parser { } else { unsigned int parametersDistance = 0; if (next.toktype == LPAR) { - const auto it = find_if(lexed.begin() + i, lexed.end(), [](const tok& token){ return token.toktype == RPAR; }); - parametersDistance = distance(lexed.begin() + i, it); + const auto closing = find_if(lexed.begin() + i, lexed.end(), [](const tok& token){ return token.toktype == RPAR; }); + parametersDistance = distance(lexed.begin() + i, closing); i += parametersDistance; } if (nextAre({LCOMP, LCOMP, LBRACE})) { From 49dc7d0ebb88b0beacdd9398eff977df0282c2b1 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 8 Apr 2022 19:44:57 +0200 Subject: [PATCH 115/254] main.cpp: Use a map instead of a set and a vector in main.cpp Target.hpp: make staticMap thread-local to avoid issues with the "--parallel" argument, and don't include dots in the languages array Signed-off-by: Username404 --- src/headers/transpiler/Target.hpp | 4 +- src/main.cpp | 84 +++++++++++++------------------ 2 files changed, 38 insertions(+), 50 deletions(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index c649356..aee6af8 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -123,7 +123,7 @@ protected: static constexpr const char* indentation = " "; public: const unordered_task_map& getTaskMapInstance() { - static unordered_task_map staticMap = getTaskMap(); + static thread_local unordered_task_map staticMap = getTaskMap(); // Default / Shared tasks: staticMap.merge(unordered_task_map({ make_task(ParseTree, transpileTree(parseComponent);), @@ -155,7 +155,7 @@ public: #include "implementations/Py.hpp" enum LANGUAGE: signed short { NONE = -1, LUA, JS, PY }; -constinit const array languages { ".lua", ".js", ".py" }; +constinit const array languages { "lua", "js", "py" }; shared_ptr Target::forName(string_view name, const bool newLines = true) { LANGUAGE selected = NONE; diff --git a/src/main.cpp b/src/main.cpp index 031c72e..2f16f21 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include "headers/Yerbacon.hpp" #include #include @@ -11,18 +11,26 @@ using namespace std; int main(int argc, char* argv[]) { setlocale(LC_ALL, ""); - string target = ".lua"; + string target = "lua"; bool printResult = false, parallel = false, newLines = true; - set files; + using unit_result = pair>; + using unit = future; + map Units; + const auto compile = [&target, &newLines](string_view name) -> string { + string transpiledString = Target::forName(target, newLines)->transpileWithTree(parseString(getFileContent(name.data()))); + name.remove_suffix(6); + outputFileContent(string(name) + '.' + target, transpiledString); + return transpiledString; + }; for (signed int i = 1; i < argc; ++i) { const string_view currentArg (argv[i]); if (currentArg == ArgumentShort("printresult")) printResult = true; else if (currentArg == ArgumentAssignable("target")) { const string_view value = ArgumentAssignable::getValueFor(currentArg); - if (not value.empty()) (target = '.') += value; + if (not value.empty()) target = value; else Yerbacon::fail("No target was provided."); } else if (currentArg == Argument("parallel")) parallel = true; @@ -34,8 +42,25 @@ int main(int argc, char* argv[]) { newLines = true; } else goto invalid_argument; } - else if (currentArg.ends_with(".ybcon")) files.insert(currentArg); - else { + else if (currentArg.ends_with(".ybcon")) Units.insert_or_assign(currentArg, async(not parallel ? launch::deferred : launch::async, [fileName = currentArg, &compile]() { + unit_result resultingPair; + try { + resultingPair.first = compile(fileName); + } catch (const Yerbacon::Exception& error) { + size_t lastSlash = 0; + const size_t position1 = fileName.find_last_of('/'); + if (cmp_not_equal(position1, string_view::npos)) lastSlash = position1; + if constexpr(filesystem::path::preferred_separator != '/') { + const size_t position2 = fileName.find_last_of(filesystem::path::preferred_separator); + if (cmp_not_equal(position2, string_view::npos)) { + lastSlash = max(lastSlash, position2); + } + } + resultingPair.first = fileName.substr(lastSlash + 1); + resultingPair.second.emplace(error); + } + return resultingPair; + })); else { if (argc == 2) { if (currentArg == Argument("version")) { cout << Yerbacon::getVersion(); @@ -46,45 +71,10 @@ int main(int argc, char* argv[]) { } else invalid_argument: Yerbacon::fail({"\"", currentArg.data(), "\" is not a valid argument."}); } } - const auto current_target = Target::forName(target, newLines); - const auto compile = [&target, current_target](string_view name) -> string { - string transpiledString = current_target->transpileWithTree(parseString(getFileContent(name.data()))); - name.remove_suffix(6); - string outputFile; - (outputFile = name).append(target); - outputFileContent(outputFile, transpiledString); - return transpiledString; - }; - int8_t exit_code = EXIT_SUCCESS; - if (!files.empty()) { - using unit_result = pair>; - using unit = future; - vector Units(files.size()); - const launch& Policy = not parallel ? launch::deferred : launch::async; - transform(files.cbegin(), files.cend(), Units.begin(), [&Policy, &compile](const string_view& fileName){ - return async(Policy, [&fileName, &compile]() { - unit_result resultingPair; - try { - resultingPair.first = compile(fileName); - } catch (const Yerbacon::Exception& error) { - size_t lastSlash = 0; - const size_t position1 = fileName.find_last_of('/'); - if (cmp_not_equal(position1, string_view::npos)) lastSlash = position1; - if constexpr(filesystem::path::preferred_separator != '/') { - const size_t position2 = fileName.find_last_of(filesystem::path::preferred_separator); - if (cmp_not_equal(position2, string_view::npos)) { - lastSlash = max(lastSlash, position2); - } - } - resultingPair.first = fileName.substr(lastSlash + 1); - resultingPair.second.emplace(error); - } - return resultingPair; - }); - }); + if (!Units.empty()) { if (printResult) cout << "~~~~[Yerbacon compilation result]~~~~\n\n"; - if (any_of(Units.rbegin(), Units.rend(), [&printResult](unit& currentFuture) -> bool { - const pair result = currentFuture.get(); + for (auto entry_iterator = Units.rbegin(); entry_iterator != Units.rend(); ++entry_iterator) { + const pair result = entry_iterator->second.get(); const bool is_exception = result.second.has_value(); if (not is_exception) { if (printResult && !(result.first.empty() || all_of(result.first.begin(), result.first.end(), [](const char& character){ @@ -95,11 +85,9 @@ int main(int argc, char* argv[]) { } else { cout << "Compilation of " << result.first << " has failed with the following error:" << endl; cerr << result.second.value().what() << '\n'; + return EXIT_FAILURE; } - return is_exception; - })) { - exit_code = EXIT_FAILURE; } } else cout << "No valid file provided.\n"; - return exit_code; + return EXIT_SUCCESS; } \ No newline at end of file From 7a18bfad5902fd9b6468b3b0bc99363b65b3e133 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 9 Apr 2022 00:15:35 +0200 Subject: [PATCH 116/254] Add support for Emscripten toolchains in the CMakeLists.txt file Signed-off-by: Username404 --- CMakeLists.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a7559c7..d04353e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,7 +55,10 @@ if (${IS_GNU} OR ${IS_CLANG}) add_definitions(-D_GLIBCXX_PARALLEL) endif() endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstrict-enums -pipe -fstack-protector-strong -fstack-clash-protection -funwind-tables -fasynchronous-unwind-tables -frtti -fexceptions") + if (NOT DEFINED EMSCRIPTEN) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong -fstack-clash-protection") + endif() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstrict-enums -pipe -funwind-tables -fasynchronous-unwind-tables -frtti -fexceptions") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections -fmerge-all-constants -ftree-vectorize -fno-math-errno") include(CheckCXXCompilerFlag) set(CF_PROTECTION "-fcf-protection") @@ -84,7 +87,10 @@ elseif(${IS_CLANG}) message(FATAL_ERROR "Clang ${MINIMAL_CLANG} or higher is required.") endif() if (${CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE} OR MINGW) # CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE is false on llvm-mingw toolchains even though it is supported - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto=full -fwhole-program-vtables") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto=full") + if (NOT DEFINED EMSCRIPTEN) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fwhole-program-vtables") + endif() endif() set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fstrict-vtable-pointers") elseif(MSVC) From 21137f5bebf6254cc4a0b17d446f5071884d62a4 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 9 Apr 2022 22:43:52 +0200 Subject: [PATCH 117/254] Add a "--text" argument Signed-off-by: Username404 --- scripts/completions/bash-completion.sh | 2 +- scripts/completions/fish-completion.fish | 3 +- scripts/completions/zsh-completion.zsh | 1 + scripts/ybcon | 45 +++++++++----------- src/etc/lexer.cpp | 2 +- src/headers/lex.hpp | 2 +- src/headers/misc.hpp | 2 +- src/main.cpp | 53 ++++++++++++------------ 8 files changed, 54 insertions(+), 56 deletions(-) diff --git a/scripts/completions/bash-completion.sh b/scripts/completions/bash-completion.sh index 520c8c5..fa1546e 100644 --- a/scripts/completions/bash-completion.sh +++ b/scripts/completions/bash-completion.sh @@ -8,7 +8,7 @@ _ybconAutoComplete() { COMPREPLY=() current="${COMP_WORDS[COMP_CWORD]}" previous="${COMP_WORDS[COMP_CWORD-1]}" - options='-h -p --help --parallel --target= --newlines= --printresult --version --buildInfo' + options='-h -p -t --help --parallel --target= --newlines= --printresult --text --version --buildInfo' if [[ "${current}" == -* ]]; then YCompReply "$(compgen -W "$options" -- "$current")" return 0 diff --git a/scripts/completions/fish-completion.fish b/scripts/completions/fish-completion.fish index 9977067..b88b157 100644 --- a/scripts/completions/fish-completion.fish +++ b/scripts/completions/fish-completion.fish @@ -7,4 +7,5 @@ complete -c ybcon -x -l buildInfo -d "Print informations about how the ybcon exe complete -c ybcon -l parallel -k -d "Transpile files in parallel mode" complete -c ybcon -l target -k -f -a 'lua js py' -d "Set the transpilation target" complete -c ybcon -l newlines -k -f -a 'on off' -d "Enable or disable new lines" -complete -c ybcon -s p -l printresult -d "Enable printing the transpilation result to stdout" \ No newline at end of file +complete -c ybcon -s p -l printresult -d "Enable printing the transpilation result to stdout" +complete -c ybcon -x -s t -l text -d "Transpile text provided after this argument (implies -p)" \ No newline at end of file diff --git a/scripts/completions/zsh-completion.zsh b/scripts/completions/zsh-completion.zsh index ea58753..4d227d7 100644 --- a/scripts/completions/zsh-completion.zsh +++ b/scripts/completions/zsh-completion.zsh @@ -9,6 +9,7 @@ _ybcon() { --target='[Set the transpilation target]:language:(lua js py)' \ --newlines='[Enable or disable new lines]:state:(on off)' \ {-p,--printresult}'[Enable printing the transpilation result to stdout]' \ + {-t,--text}'[Transpile text provided after this argument (implies -p)]' \ "*:$completeyfile" return 0 } diff --git a/scripts/ybcon b/scripts/ybcon index f086ed0..9b21044 100755 --- a/scripts/ybcon +++ b/scripts/ybcon @@ -11,7 +11,7 @@ defaultBinLocation="$scriptDir/../libexec/ybcon" usage() { if [ "$1" = false ]; then echo "Invalid arguments, usage:"; fi - echo "$EXENAME [--version] [--buildInfo] [-h|--help] [--parallel] [--target=] [--newlines=on/off] [-p|--printresult] " + echo "$EXENAME [--version] [--buildInfo] [-h|--help] [--parallel] [--target=] [--newlines=on/off] [-p|--printresult] [-t|--text] " if [ "$1" = true ]; then echo " --version Print the version" echo " --buildInfo Print informations about how the ybcon executable was built" @@ -20,6 +20,7 @@ usage() { echo " --target= Set the transpilation target" echo " --newlines=on/off Enable or disable new lines" echo " -p or --printresult Enable printing the transpilation result to stdout" + echo " -t or --text Transpile text provided after this argument (implies -p)" printf "\n" fi } @@ -29,57 +30,51 @@ usageExit() { exit 0 }; helpExit() { usage true; exit 0; } -args=""; +arguments=""; run=false; -newArgs() { - if [ "$args" = "" ]; then - args="$args$1" - else - args="$args $1" - fi -} - if [ "$#" != 0 ]; then if [ "$#" = 1 ]; then case "$1" in -h | --help ) helpExit ;; - --version | --buildInfo ) - run=true; args="$1" ;; - *.ybcon ) - newArgs "$1"; run=true ;; + --version | --buildInfo | *.ybcon ) + run=true ;; * ) usageExit ;; esac else + text_provided=false for it in "$@" do case "$it" in -p | --printresult | --parallel | --target=* | --newlines=on | --newlines=off ) - if test "${args#*$it}" = "$args"; then - newArgs "$it" + if test "${arguments#*$it}" != "$arguments"; then + usageExit + fi ;; + -t | --text ) + text_provided=true ;; + * ) + if [ $text_provided = true ] || test "${it%*.ybcon}" != "$it"; then + run=true else usageExit fi ;; - *.ybcon ) - newArgs "$it" - run=true ;; - * ) - usageExit ;; esac + if [ "$arguments" != "" ]; then + arguments="$arguments " + fi + arguments="$arguments$it" done - if test "${args#*".ybcon"}" = "$args" ; then usageExit; fi + if test $run = false ; then usageExit; fi fi else usage false fi -runIt() { eval "$1" " $args"; } - if [ "$run" = true ]; then if [ -f "$defaultBinLocation" ]; then - runIt "$defaultBinLocation" + exec "$defaultBinLocation" "$@" else echo "Yerbacon executable not found at $defaultBinLocation" fi diff --git a/src/etc/lexer.cpp b/src/etc/lexer.cpp index ca773ff..b11187d 100644 --- a/src/etc/lexer.cpp +++ b/src/etc/lexer.cpp @@ -9,7 +9,7 @@ tok::type getIdentifierCharType(const char& Char) { else return UNEXPECTED; } -vector lex(const string& in) +vector lex(const string_view& in) { vector resVal; unsigned long lineNumber = 1; diff --git a/src/headers/lex.hpp b/src/headers/lex.hpp index f2c3fc2..5aab51c 100644 --- a/src/headers/lex.hpp +++ b/src/headers/lex.hpp @@ -43,6 +43,6 @@ auto find_corresponding(std::input_iterator auto begin, std::input_iterator auto }); } -std::vector lex(const std::string& in); +std::vector lex(const std::string_view& in); #endif //YERBACON_TEST_H \ No newline at end of file diff --git a/src/headers/misc.hpp b/src/headers/misc.hpp index f741593..ac29321 100644 --- a/src/headers/misc.hpp +++ b/src/headers/misc.hpp @@ -6,6 +6,6 @@ void outputFileContent(const string& file, string_view content); #include "lex.hpp" #include "parsing/Parser.hpp" -inline auto parseString(const string& toParse) { return Parser::parse(lex(toParse)); } +inline auto parseString(const string_view& toParse) { return Parser::parse(lex(toParse)); } #endif //YERBACON_MISC_HPP \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 2f16f21..fb74d80 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,16 +14,11 @@ int main(int argc, char* argv[]) { string target = "lua"; bool printResult = false, parallel = false, - newLines = true; + newLines = true, + text_provided = false; using unit_result = pair>; using unit = future; map Units; - const auto compile = [&target, &newLines](string_view name) -> string { - string transpiledString = Target::forName(target, newLines)->transpileWithTree(parseString(getFileContent(name.data()))); - name.remove_suffix(6); - outputFileContent(string(name) + '.' + target, transpiledString); - return transpiledString; - }; for (signed int i = 1; i < argc; ++i) { const string_view currentArg (argv[i]); @@ -42,25 +37,31 @@ int main(int argc, char* argv[]) { newLines = true; } else goto invalid_argument; } - else if (currentArg.ends_with(".ybcon")) Units.insert_or_assign(currentArg, async(not parallel ? launch::deferred : launch::async, [fileName = currentArg, &compile]() { - unit_result resultingPair; - try { - resultingPair.first = compile(fileName); - } catch (const Yerbacon::Exception& error) { - size_t lastSlash = 0; - const size_t position1 = fileName.find_last_of('/'); - if (cmp_not_equal(position1, string_view::npos)) lastSlash = position1; - if constexpr(filesystem::path::preferred_separator != '/') { - const size_t position2 = fileName.find_last_of(filesystem::path::preferred_separator); - if (cmp_not_equal(position2, string_view::npos)) { - lastSlash = max(lastSlash, position2); + else if (currentArg == ArgumentShort("text")) { text_provided = true; printResult = true; } + else if ((currentArg.ends_with(".ybcon") && !text_provided) || text_provided) + Units.insert_or_assign(currentArg, async(not parallel ? launch::deferred : launch::async, [currentArg, &text_provided, &target, &newLines]() { + unit_result resultingPair; + try { + resultingPair.first = Target::forName(target, newLines)->transpileWithTree( + parseString(text_provided ? currentArg : getFileContent(currentArg.data())) + ); + if (not text_provided) outputFileContent(string(currentArg.substr(0, currentArg.size() - 6)) + '.' + target, resultingPair.first); + } catch (const Yerbacon::Exception& error) { + size_t lastSlash = 0; + const size_t position1 = currentArg.find_last_of('/'); + if (cmp_not_equal(position1, string_view::npos)) lastSlash = position1; + if constexpr(filesystem::path::preferred_separator != '/') { + const size_t position2 = currentArg.find_last_of(filesystem::path::preferred_separator); + if (cmp_not_equal(position2, string_view::npos)) { + lastSlash = max(lastSlash, position2); + } } + resultingPair.first = currentArg.substr(lastSlash + 1); + resultingPair.second.emplace(error); } - resultingPair.first = fileName.substr(lastSlash + 1); - resultingPair.second.emplace(error); - } - return resultingPair; - })); else { + return resultingPair; + })); + else { if (argc == 2) { if (currentArg == Argument("version")) { cout << Yerbacon::getVersion(); @@ -83,11 +84,11 @@ int main(int argc, char* argv[]) { cout << result.first << '\n'; } } else { - cout << "Compilation of " << result.first << " has failed with the following error:" << endl; + cout << "Compilation"; if (not text_provided) cout << " of " << result.first; cout << " has failed with the following error:" << endl; cerr << result.second.value().what() << '\n'; return EXIT_FAILURE; } } - } else cout << "No valid file provided.\n"; + } else cout << (!text_provided ? "No valid file provided" : "No text was provided") << ".\n"; return EXIT_SUCCESS; } \ No newline at end of file From 6945900140b05a45058d77d7da523f617557d8ba Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 9 Apr 2022 22:53:45 +0200 Subject: [PATCH 118/254] main.cpp: Rename "currentArg" to "currentArgument" Signed-off-by: Username404 --- src/main.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index fb74d80..7423ac6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,55 +21,55 @@ int main(int argc, char* argv[]) { map Units; for (signed int i = 1; i < argc; ++i) { - const string_view currentArg (argv[i]); - if (currentArg == ArgumentShort("printresult")) printResult = true; - else if (currentArg == ArgumentAssignable("target")) { - const string_view value = ArgumentAssignable::getValueFor(currentArg); + const string_view currentArgument (argv[i]); + if (currentArgument == ArgumentShort("printresult")) printResult = true; + else if (currentArgument == ArgumentAssignable("target")) { + const string_view value = ArgumentAssignable::getValueFor(currentArgument); if (not value.empty()) target = value; else Yerbacon::fail("No target was provided."); } - else if (currentArg == Argument("parallel")) parallel = true; - else if (currentArg == ArgumentAssignable("newlines")) { - const string_view enabled = ArgumentAssignable::getValueFor(currentArg); + else if (currentArgument == Argument("parallel")) parallel = true; + else if (currentArgument == ArgumentAssignable("newlines")) { + const string_view enabled = ArgumentAssignable::getValueFor(currentArgument); if (enabled == "off") { newLines = false; } else if (enabled == "on") { newLines = true; } else goto invalid_argument; } - else if (currentArg == ArgumentShort("text")) { text_provided = true; printResult = true; } - else if ((currentArg.ends_with(".ybcon") && !text_provided) || text_provided) - Units.insert_or_assign(currentArg, async(not parallel ? launch::deferred : launch::async, [currentArg, &text_provided, &target, &newLines]() { + else if (currentArgument == ArgumentShort("text")) { text_provided = true; printResult = true; } + else if ((currentArgument.ends_with(".ybcon") && !text_provided) || text_provided) + Units.insert_or_assign(currentArgument, async(not parallel ? launch::deferred : launch::async, [currentArgument, &text_provided, &target, &newLines]() { unit_result resultingPair; try { resultingPair.first = Target::forName(target, newLines)->transpileWithTree( - parseString(text_provided ? currentArg : getFileContent(currentArg.data())) + parseString(text_provided ? currentArgument : getFileContent(currentArgument.data())) ); - if (not text_provided) outputFileContent(string(currentArg.substr(0, currentArg.size() - 6)) + '.' + target, resultingPair.first); + if (not text_provided) outputFileContent(string(currentArgument.substr(0, currentArgument.size() - 6)) + '.' + target, resultingPair.first); } catch (const Yerbacon::Exception& error) { size_t lastSlash = 0; - const size_t position1 = currentArg.find_last_of('/'); + const size_t position1 = currentArgument.find_last_of('/'); if (cmp_not_equal(position1, string_view::npos)) lastSlash = position1; if constexpr(filesystem::path::preferred_separator != '/') { - const size_t position2 = currentArg.find_last_of(filesystem::path::preferred_separator); + const size_t position2 = currentArgument.find_last_of(filesystem::path::preferred_separator); if (cmp_not_equal(position2, string_view::npos)) { lastSlash = max(lastSlash, position2); } } - resultingPair.first = currentArg.substr(lastSlash + 1); + resultingPair.first = currentArgument.substr(lastSlash + 1); resultingPair.second.emplace(error); } return resultingPair; })); else { if (argc == 2) { - if (currentArg == Argument("version")) { + if (currentArgument == Argument("version")) { cout << Yerbacon::getVersion(); - } else if (currentArg == Argument("buildInfo")) { + } else if (currentArgument == Argument("buildInfo")) { cout << Yerbacon::getBuildInfo(); } else goto invalid_argument; cout << '\n'; exit(EXIT_SUCCESS); - } else invalid_argument: Yerbacon::fail({"\"", currentArg.data(), "\" is not a valid argument."}); + } else invalid_argument: Yerbacon::fail({"\"", currentArgument.data(), "\" is not a valid argument."}); } } if (!Units.empty()) { From dce232c5c949c4ac7f8a116a417362bbb69b1c20 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 10 Apr 2022 00:36:00 +0200 Subject: [PATCH 119/254] Fix different arguments being treated as duplicates because of short versions in the shell wrapper script Signed-off-by: Username404 --- scripts/ybcon | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/ybcon b/scripts/ybcon index 9b21044..86a6ee8 100755 --- a/scripts/ybcon +++ b/scripts/ybcon @@ -49,13 +49,13 @@ if [ "$#" != 0 ]; then do case "$it" in -p | --printresult | --parallel | --target=* | --newlines=on | --newlines=off ) - if test "${arguments#*$it}" != "$arguments"; then + if [ "${arguments#*$it}" != "$arguments" ] && [ "${arguments%*-$it}" = "${arguments#*-$it}" ]; then usageExit fi ;; -t | --text ) text_provided=true ;; * ) - if [ $text_provided = true ] || test "${it%*.ybcon}" != "$it"; then + if [ $text_provided = true ] || [ "${it%*.ybcon}" != "$it" ]; then run=true else usageExit From 7b8f4fc6c49ade4f27dd3155314532924358731a Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 10 Apr 2022 12:51:06 +0200 Subject: [PATCH 120/254] Add a javascript target to the Jenkinsfile Signed-off-by: Username404 --- Jenkinsfile | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 6c1f72e..557824f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,10 +1,13 @@ +String cmake_generator() { return fileExists('/usr/bin/ninja') ? 'Ninja' : 'Unix Makefiles' } +String no_compilation_cache_flags() { return '-DNO_CCACHE=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON' } + def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch', boolean isPackageArchDeb = true, String suffix = '') { final String packageArch = isPackageArchDeb ? debArch : rpmArch; final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: "cmake-build-${packageArch}${suffix}", buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=/usr/bin/${path}-ld.gold -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS_PRIVATE_DIRS=/usr/${path}/lib/ -DNO_CCACHE=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON", - generator: fileExists('/usr/bin/ninja') ? 'Ninja' : 'Unix Makefiles' + cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=/usr/bin/${path}-ld.gold -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS_PRIVATE_DIRS=/usr/${path}/lib/ ${no_compilation_cache_flags()}", + generator: cmake_generator() cmake arguments: "--build ./cmake-build-${packageArch}${suffix} --target ybcon", installation: 'Latest' sh "/usr/bin/${path}-strip -s ./cmake-build-${packageArch}${suffix}/ybcon*" cpack installation: 'Latest', workingDir: "cmake-build-${packageArch}${suffix}" @@ -37,6 +40,10 @@ pipeline { // Multi-branch pipeline script for Yerbacon. echo "Building the ${env.BRANCH_NAME} branch.." buildTarget('x86_64-linux-gnu', 'x86_64', 'amd64') buildTarget('i686-linux-gnu', 'i386', 'i386') + cmakeBuild buildDir: "cmake-build-release-emscripten", buildType: 'release', cleanBuild: true, installation: 'Latest', + cmakeArgs: "-DCMAKE_TOOLCHAIN_FILE=\"/usr/share/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake\" -DCMAKE_EXE_LINKER_FLAGS=\"--closure 1 -sWASM=0 --memory-init-file 0\" ${no_compilation_cache_flags()}", + generator: cmake_generator() + cmake arguments: "--build ./cmake-build-release-emscripten", installation: 'Latest' } } stage('Build for other architectures') { @@ -64,7 +71,7 @@ pipeline { // Multi-branch pipeline script for Yerbacon. stage('Deploy') { steps { echo 'Deploying....' - archiveArtifacts artifacts: 'cmake-build-*/*.deb, cmake-build-*/*.rpm, cmake-build-*/*.tar.gz, cmake-build-*/*.sh', fingerprint: false + archiveArtifacts artifacts: 'cmake-build-*/*.deb, cmake-build-*/*.rpm, cmake-build-*/*.tar.gz, cmake-build-*/*.sh, cmake-build-release-emscripten/*.js', fingerprint: false catchError(buildResult: 'SUCCESS', stageResult: 'SUCCESS') { archiveArtifacts artifacts: 'cmake-build-*/*wpkg.*.exe, cmake-build-*/*.zip' } From 6ecd006d09f71e081b474941d707683e9641aef4 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 10 Apr 2022 12:41:04 +0200 Subject: [PATCH 121/254] Add a list of required compilers to the Jenkinsfile Signed-off-by: Username404 --- Jenkinsfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 557824f..b93c81a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -19,6 +19,10 @@ final String windowsSuffix = '-windows' - CMake - Sidebar Link - Workspace Cleanup + Required Compilers: + - G++ for x86_64, i686, armel, armhf, aarch64 and riscv64 + - Emscripten Clang (https://github.com/emscripten-core/emsdk) + - MinGW32 G++/Clang (https://github.com/mstorsjo/llvm-mingw) for x86_64, i686, armhf and aarch64 */ pipeline { // Multi-branch pipeline script for Yerbacon. From 87c090ceeb9532ae23c7db88da4ad496710f8068 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 10 Apr 2022 11:39:42 +0200 Subject: [PATCH 122/254] Remove a useless comment in the Jenkinsfile Signed-off-by: Username404 --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index b93c81a..73a5c75 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -25,7 +25,7 @@ final String windowsSuffix = '-windows' - MinGW32 G++/Clang (https://github.com/mstorsjo/llvm-mingw) for x86_64, i686, armhf and aarch64 */ -pipeline { // Multi-branch pipeline script for Yerbacon. +pipeline { agent any options { From 4da10b61dd42d9cac192a7a74c0a5ebf3f3280b1 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 12 Apr 2022 18:51:26 +0200 Subject: [PATCH 123/254] Add default linker flags for emscripten toolchains in the CMakeLists.txt file Signed-off-by: Username404 --- CMakeLists.txt | 2 ++ Jenkinsfile | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d04353e..19724f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,8 @@ if (${IS_GNU} OR ${IS_CLANG}) endif() if (NOT DEFINED EMSCRIPTEN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong -fstack-clash-protection") + else() + set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main ${CMAKE_EXE_LINKER_FLAGS}") endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstrict-enums -pipe -funwind-tables -fasynchronous-unwind-tables -frtti -fexceptions") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections -fmerge-all-constants -ftree-vectorize -fno-math-errno") diff --git a/Jenkinsfile b/Jenkinsfile index 73a5c75..cd3f403 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -45,7 +45,7 @@ pipeline { buildTarget('x86_64-linux-gnu', 'x86_64', 'amd64') buildTarget('i686-linux-gnu', 'i386', 'i386') cmakeBuild buildDir: "cmake-build-release-emscripten", buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "-DCMAKE_TOOLCHAIN_FILE=\"/usr/share/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake\" -DCMAKE_EXE_LINKER_FLAGS=\"--closure 1 -sWASM=0 --memory-init-file 0\" ${no_compilation_cache_flags()}", + cmakeArgs: "-DCMAKE_TOOLCHAIN_FILE=\"/usr/share/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake\" ${no_compilation_cache_flags()}", generator: cmake_generator() cmake arguments: "--build ./cmake-build-release-emscripten", installation: 'Latest' } From 29a5630e95acc5e518ccba03110f58fc8a641dd5 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 12 Apr 2022 22:18:03 +0200 Subject: [PATCH 124/254] Support usage of the posix thread library with emscripten toolchains Signed-off-by: Username404 --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 19724f7..32a10be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,11 @@ if (${IS_GNU} OR ${IS_CLANG}) if (NOT DEFINED EMSCRIPTEN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong -fstack-clash-protection") else() - set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main ${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 ${CMAKE_EXE_LINKER_FLAGS}") + if (CMAKE_USE_PTHREADS_INIT) + set(CMAKE_CXX_FLAGS "-pthread ${CMAKE_CXX_FLAGS}") # Emscripten requires the -pthread flag + set(CMAKE_EXE_LINKER_FLAGS "--closure-args=\"--compilation_level SIMPLE\" -sPROXY_TO_PTHREAD=1 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706 + endif() endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstrict-enums -pipe -funwind-tables -fasynchronous-unwind-tables -frtti -fexceptions") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections -fmerge-all-constants -ftree-vectorize -fno-math-errno") From 5f1e8482cd8870fb3347285b9b4d26a74ffab64d Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 13 Apr 2022 23:15:30 +0200 Subject: [PATCH 125/254] Add "-sSAFE_HEAP=1" to the default linker flags for emscripten toolchains Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 32a10be..6745b2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,7 @@ if (${IS_GNU} OR ${IS_CLANG}) if (NOT DEFINED EMSCRIPTEN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong -fstack-clash-protection") else() - set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 ${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 ${CMAKE_EXE_LINKER_FLAGS}") if (CMAKE_USE_PTHREADS_INIT) set(CMAKE_CXX_FLAGS "-pthread ${CMAKE_CXX_FLAGS}") # Emscripten requires the -pthread flag set(CMAKE_EXE_LINKER_FLAGS "--closure-args=\"--compilation_level SIMPLE\" -sPROXY_TO_PTHREAD=1 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706 From 1622096d8b3c9068ad14e70093e78bf2ede152c8 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 13 Apr 2022 23:40:02 +0200 Subject: [PATCH 126/254] Add "-sABORTING_MALLOC=0" to the default flags for emscripten toolchains Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6745b2d..77cc767 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,7 @@ if (${IS_GNU} OR ${IS_CLANG}) if (NOT DEFINED EMSCRIPTEN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong -fstack-clash-protection") else() - set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 ${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 ${CMAKE_EXE_LINKER_FLAGS}") if (CMAKE_USE_PTHREADS_INIT) set(CMAKE_CXX_FLAGS "-pthread ${CMAKE_CXX_FLAGS}") # Emscripten requires the -pthread flag set(CMAKE_EXE_LINKER_FLAGS "--closure-args=\"--compilation_level SIMPLE\" -sPROXY_TO_PTHREAD=1 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706 From feb6aedde079ff7476fcb464b16c196637ffe81d Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 13 Apr 2022 23:41:46 +0200 Subject: [PATCH 127/254] Add "-sJS_MATH=1" to the default flags for emscripten toolchains Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 77cc767..9d212ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,7 @@ if (${IS_GNU} OR ${IS_CLANG}) if (NOT DEFINED EMSCRIPTEN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong -fstack-clash-protection") else() - set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 ${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 -sJS_MATH=1 ${CMAKE_EXE_LINKER_FLAGS}") if (CMAKE_USE_PTHREADS_INIT) set(CMAKE_CXX_FLAGS "-pthread ${CMAKE_CXX_FLAGS}") # Emscripten requires the -pthread flag set(CMAKE_EXE_LINKER_FLAGS "--closure-args=\"--compilation_level SIMPLE\" -sPROXY_TO_PTHREAD=1 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706 From 660f73a3d2ab0b6d74452f8879c45d95af62d9bc Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 13 Apr 2022 23:50:00 +0200 Subject: [PATCH 128/254] Specify the environments to support by default with emscripten toolchains Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d212ad..76b2794 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,7 @@ if (${IS_GNU} OR ${IS_CLANG}) if (NOT DEFINED EMSCRIPTEN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong -fstack-clash-protection") else() - set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 -sJS_MATH=1 ${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' ${CMAKE_EXE_LINKER_FLAGS}") if (CMAKE_USE_PTHREADS_INIT) set(CMAKE_CXX_FLAGS "-pthread ${CMAKE_CXX_FLAGS}") # Emscripten requires the -pthread flag set(CMAKE_EXE_LINKER_FLAGS "--closure-args=\"--compilation_level SIMPLE\" -sPROXY_TO_PTHREAD=1 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706 From dadfea85ebf359458c54d2e9889198fbcfcad8c3 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 13 Apr 2022 23:55:40 +0200 Subject: [PATCH 129/254] Set NODEJS_CATCH_EXIT to 0 since it is not needed Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 76b2794..7641c2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,7 @@ if (${IS_GNU} OR ${IS_CLANG}) if (NOT DEFINED EMSCRIPTEN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong -fstack-clash-protection") else() - set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' ${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 ${CMAKE_EXE_LINKER_FLAGS}") if (CMAKE_USE_PTHREADS_INIT) set(CMAKE_CXX_FLAGS "-pthread ${CMAKE_CXX_FLAGS}") # Emscripten requires the -pthread flag set(CMAKE_EXE_LINKER_FLAGS "--closure-args=\"--compilation_level SIMPLE\" -sPROXY_TO_PTHREAD=1 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706 From 38fa99155be2bf5f04939f74aab8d59c64e39a41 Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 14 Apr 2022 00:02:09 +0200 Subject: [PATCH 130/254] Set NODERAWFS to 1 when using emscripten toolchains to use the raw filesystem backend Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7641c2a..4cd3ce3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,7 @@ if (${IS_GNU} OR ${IS_CLANG}) if (NOT DEFINED EMSCRIPTEN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong -fstack-clash-protection") else() - set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 ${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 -sNODERAWFS=1 ${CMAKE_EXE_LINKER_FLAGS}") if (CMAKE_USE_PTHREADS_INIT) set(CMAKE_CXX_FLAGS "-pthread ${CMAKE_CXX_FLAGS}") # Emscripten requires the -pthread flag set(CMAKE_EXE_LINKER_FLAGS "--closure-args=\"--compilation_level SIMPLE\" -sPROXY_TO_PTHREAD=1 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706 From 30c9515106a5c4e064e2e1e311178419203be9fb Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 14 Apr 2022 00:08:59 +0200 Subject: [PATCH 131/254] Turn on strict mode on emscripten toolchains Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4cd3ce3..84dc678 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,7 @@ if (${IS_GNU} OR ${IS_CLANG}) if (NOT DEFINED EMSCRIPTEN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong -fstack-clash-protection") else() - set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 -sNODERAWFS=1 ${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 -sNODERAWFS=1 -sSTRICT=1 ${CMAKE_EXE_LINKER_FLAGS}") if (CMAKE_USE_PTHREADS_INIT) set(CMAKE_CXX_FLAGS "-pthread ${CMAKE_CXX_FLAGS}") # Emscripten requires the -pthread flag set(CMAKE_EXE_LINKER_FLAGS "--closure-args=\"--compilation_level SIMPLE\" -sPROXY_TO_PTHREAD=1 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706 From bcda5c9b32337dca120c0fbcd98e74e0f9653a3c Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 14 Apr 2022 08:52:54 +0200 Subject: [PATCH 132/254] Revert "Set NODERAWFS to 1 when using emscripten toolchains to use the raw filesystem backend" This reverts commit 82b3e2a5 Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 84dc678..d8b4e56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,7 +58,7 @@ if (${IS_GNU} OR ${IS_CLANG}) if (NOT DEFINED EMSCRIPTEN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong -fstack-clash-protection") else() - set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 -sNODERAWFS=1 -sSTRICT=1 ${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 -sSTRICT=1 ${CMAKE_EXE_LINKER_FLAGS}") if (CMAKE_USE_PTHREADS_INIT) set(CMAKE_CXX_FLAGS "-pthread ${CMAKE_CXX_FLAGS}") # Emscripten requires the -pthread flag set(CMAKE_EXE_LINKER_FLAGS "--closure-args=\"--compilation_level SIMPLE\" -sPROXY_TO_PTHREAD=1 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706 From 27c8b642d6cf9d2d2286da047310d154a7d21d16 Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 14 Apr 2022 16:13:19 +0200 Subject: [PATCH 133/254] Check if i is equal to zero instead of checking whether it is greater, since i is unsigned in Parser.hpp Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 4ce100b..53b1d3b 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -45,7 +45,7 @@ namespace Parser { switch (current.toktype) { case NUMBER: { long double v = stoul(current.toktext); - if (i > 0 && lexed[i - 1].toktype == HYPHEN) v = -v; + if (i != 0 && lexed[i - 1].toktype == HYPHEN) v = -v; types::Integer::precision_type p = 0; if (nextAre({DOT, NUMBER})) { i += 2; From b96b48788224caf777d2123a044fcacb4c819ab6 Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 14 Apr 2022 16:33:42 +0200 Subject: [PATCH 134/254] Add a "IGNORE_MINIMAL_COMPILER_VERSION" option to the CMakeLists.txt file Signed-off-by: Username404 --- CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d8b4e56..3b14bdc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,7 @@ set(CMAKE_CXX_FLAGS_RELEASE "-Os") set(MINIMAL_GNU "11.0") set(MINIMAL_CLANG "14.0.1") set(MINIMAL_MSVC "19.30") +option(IGNORE_MINIMAL_COMPILER_VERSION "Whether or not to ignore the minimal compiler versions") set(IS_GNU (${CMAKE_CXX_COMPILER_ID} STREQUAL GNU)) set(IS_CLANG (${CMAKE_CXX_COMPILER_ID} STREQUAL Clang)) @@ -78,7 +79,7 @@ include(CheckIPOSupported) check_ipo_supported(RESULT CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE LANGUAGES CXX) if (${IS_GNU}) - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_GNU}) + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_GNU} AND NOT ${IGNORE_MINIMAL_COMPILER_VERSION}) message(FATAL_ERROR "G++ ${MINIMAL_GNU} or higher is required.") endif() if (Threads_FOUND) @@ -89,7 +90,7 @@ if (${IS_GNU}) set(CMAKE_CXX_FLAGS_RELEASE "-fwhole-program ${CMAKE_CXX_FLAGS_RELEASE}") endif() elseif(${IS_CLANG}) - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_CLANG}) + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_CLANG} AND NOT ${IGNORE_MINIMAL_COMPILER_VERSION}) message(FATAL_ERROR "Clang ${MINIMAL_CLANG} or higher is required.") endif() if (${CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE} OR MINGW) # CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE is false on llvm-mingw toolchains even though it is supported @@ -100,7 +101,7 @@ elseif(${IS_CLANG}) endif() set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fstrict-vtable-pointers") elseif(MSVC) - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_MSVC}) + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_MSVC} AND NOT ${IGNORE_MINIMAL_COMPILER_VERSION}) message(FATAL_ERROR "MSVC ${MINIMAL_MSVC} or higher is required") endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR /W3 /Zc:__cplusplus /Zc:preprocessor /Zc:throwingNew /Zc:inline") From 3c4902605a18d6e893774f1210a46afa0ef8b16d Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 14 Apr 2022 16:37:36 +0200 Subject: [PATCH 135/254] Set IGNORE_MINIMAL_COMPILER_VERSION to "ON" in the Jenkinsfile Signed-off-by: Username404 --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index cd3f403..566050e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -6,7 +6,7 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: "cmake-build-${packageArch}${suffix}", buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=/usr/bin/${path}-ld.gold -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS_PRIVATE_DIRS=/usr/${path}/lib/ ${no_compilation_cache_flags()}", + cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=/usr/bin/${path}-ld.gold -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS_PRIVATE_DIRS=/usr/${path}/lib/ -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", generator: cmake_generator() cmake arguments: "--build ./cmake-build-${packageArch}${suffix} --target ybcon", installation: 'Latest' sh "/usr/bin/${path}-strip -s ./cmake-build-${packageArch}${suffix}/ybcon*" From d059d1e5076ce822066deab2df1104f114a8b796 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 16 Apr 2022 15:34:31 +0200 Subject: [PATCH 136/254] Throw the "Unexpected character" error for all unrecognized characters in Parser.hpp Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 53b1d3b..fc7f9a1 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -103,6 +103,7 @@ namespace Parser { } } break; + case ';': break; case LPAR: case LBRACE: case LBRACKET: { const auto closingCharacter = find_corresponding(lexed.begin() + i + 1, lexed.end(), current.toktype, tok::inverseLCharacter(current.toktype)); vector subTokens(lexed.begin() + i + 1, closingCharacter); @@ -134,8 +135,7 @@ namespace Parser { i = distance(lexed.begin(), closingCharacter); break; } - case RPAR: case RBRACE: case RBRACKET: parsingError(current, " \u27F5 Unexpected character", true); - default: break; + default: parsingError(current, " \u27F5 Unexpected character", true); } } return parseTree; From 453025b18c9d08394be044951cc215d30b0283a3 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 16 Apr 2022 16:23:33 +0200 Subject: [PATCH 137/254] Add an "empty" function to the ParseTree class Signed-off-by: Username404 --- src/headers/parsing/ParseComponents.hpp | 1 + src/headers/transpiler/Target.hpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index e7b7b04..a373c04 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -53,6 +53,7 @@ protected: } public: inline size_t size() const { return subComponents.size(); } + inline bool empty() const { return size() == 0; } inline iterator begin() const noexcept { return subComponents.begin(); } inline constant_iterator cbegin() const noexcept { return subComponents.cbegin(); } inline iterator end() const noexcept { return subComponents.end(); } diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index aee6af8..7366c9f 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -77,7 +77,7 @@ protected: virtual print_functions_pair printFunctions() = 0; IS(ParseTree) void transpileTree(const T& parseTree, const unsigned short& indentationLevel = 0, const function&& postInsertionFunction = [](auto&){}) { - if (parseTree.size() > 0) { + if (not parseTree.empty()) { const auto added_size = indentationLevel * strlen(indentation); if (newLines) { separator.reserve(separator.size() + added_size); From 5a96757942385b526a026876ec7b078923e57d63 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 16 Apr 2022 21:14:22 +0200 Subject: [PATCH 138/254] Always throw an error when an unexpected expression is found in Parser.hpp Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index fc7f9a1..2a9a7b6 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -117,23 +117,23 @@ namespace Parser { } } } - const component_ptr& previous = parseTree.at(parseTree.size() - 1); - if (current.toktype == LPAR) { + if (not parseTree.empty()) { try { - dynamic_cast(*previous).ParseTree::operator=(parse(subTokens)); - } catch (const bad_cast&) { - parsingError(current, "Unexpected parenthesis"); - } - } else if (current.toktype == LBRACE) { - const type_info& previous_id = previous->getId(); - if (previous_id == typeid(Function)) { - dynamic_cast(*previous).ParseTree::operator=(parse(subTokens)); - } else if (previous_id == typeid(Class)) { - dynamic_cast(*previous).body = parse(subTokens); - } - } else parseTree << parse(subTokens); - i = distance(lexed.begin(), closingCharacter); - break; + const component_ptr& previous = parseTree.at(parseTree.size() - 1); + if (current.toktype == LPAR) { + dynamic_cast(*previous).ParseTree::operator=(parse(subTokens)); + } else if (current.toktype == LBRACE) { + const type_info& previous_id = previous->getId(); + if (previous_id == typeid(Function)) { + dynamic_cast(*previous).ParseTree::operator=(parse(subTokens)); + } else if (previous_id == typeid(Class)) { + dynamic_cast(*previous).body = parse(subTokens); + } + } else parseTree << parse(subTokens); + i = distance(lexed.begin(), closingCharacter); + break; + } catch (const out_of_range&) {} catch (const bad_cast&) {} + } } default: parsingError(current, " \u27F5 Unexpected character", true); } From e9d7c27d4f98a1a3c52b782b01d5de086fb25440 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 16 Apr 2022 21:28:20 +0200 Subject: [PATCH 139/254] Simplify parsing of functions/calls/classes and remove the Class.body variable Signed-off-by: Username404 --- src/headers/parsing/ParseComponents.hpp | 3 +-- src/headers/parsing/Parser.hpp | 19 ++++++------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index a373c04..cdf2d91 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -125,8 +125,7 @@ namespace StandardComponents { ParseTree parameters; using NamedIdentifier::NamedIdentifier; }; - struct Class: NamedIdentifier { - ParseTree body; + struct Class: NamedIdentifier, ParseTree { using NamedIdentifier::NamedIdentifier; }; } diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 2a9a7b6..f7aec91 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -119,19 +119,12 @@ namespace Parser { } if (not parseTree.empty()) { try { - const component_ptr& previous = parseTree.at(parseTree.size() - 1); - if (current.toktype == LPAR) { - dynamic_cast(*previous).ParseTree::operator=(parse(subTokens)); - } else if (current.toktype == LBRACE) { - const type_info& previous_id = previous->getId(); - if (previous_id == typeid(Function)) { - dynamic_cast(*previous).ParseTree::operator=(parse(subTokens)); - } else if (previous_id == typeid(Class)) { - dynamic_cast(*previous).body = parse(subTokens); - } - } else parseTree << parse(subTokens); - i = distance(lexed.begin(), closingCharacter); - break; + auto& previous = dynamic_cast(*parseTree.at(parseTree.size() - 1)); + if (current.toktype != LPAR or previous.getId() == typeid(Call)) { + previous = parse(subTokens); + i = distance(lexed.begin(), closingCharacter); + break; + } } catch (const out_of_range&) {} catch (const bad_cast&) {} } } From 5d2b630ec6afbee381cdb987354aca11ceb65a67 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 16 Apr 2022 22:31:54 +0200 Subject: [PATCH 140/254] Remove a TODO comment in Parser.hpp Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index f7aec91..65f1350 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -91,7 +91,7 @@ namespace Parser { } const unsigned increment = 2 + isFinalDefine; const auto beginning = lexed.begin() + i + increment; - const auto end = find_if(beginning, lexed.end(), [¤t](const tok& it){ // TODO Find another way of choosing the tokens to parse + const auto end = find_if(beginning, lexed.end(), [¤t](const tok& it){ return it.toktype == SEMICOLON || it.line != current.line; }); parseTree << Define(isFinalDefine, current.toktext, parse(beginning, end)); From 3c7835b2a6141c9ae04fc35cb279da84d7b980af Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 16 Apr 2022 22:33:21 +0200 Subject: [PATCH 141/254] Remove the useless scripts/TestYbcon file Signed-off-by: Username404 --- scripts/TestYbcon | 1 - 1 file changed, 1 deletion(-) delete mode 100644 scripts/TestYbcon diff --git a/scripts/TestYbcon b/scripts/TestYbcon deleted file mode 100644 index 42c763b..0000000 --- a/scripts/TestYbcon +++ /dev/null @@ -1 +0,0 @@ -cd ./cmake-build-release/ && clear && ./ybcon --printresult ../examples/HelloWorld.ybcon From 663979ea6572ec2796edd72f5b56a81c0c445353 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 17 Apr 2022 12:57:21 +0200 Subject: [PATCH 142/254] Fix allocation of more memory in the ParseTree.addAllComponents function Signed-off-by: Username404 --- src/headers/parsing/ParseComponents.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index cdf2d91..8d6496b 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -48,7 +48,7 @@ protected: void addAllComponents( const initializer_list& components ) const { - subComponents.reserve(components.size()); + subComponents.reserve(subComponents.size() + components.size()); for (const T& current: components) addComponent(current); } public: From 8d239694cf00394b88c5dde01012c4043d194daa Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 17 Apr 2022 13:10:58 +0200 Subject: [PATCH 143/254] Remove the const specifier in the "begin" and "end" functions of ParseTree, since they call non-const functions Signed-off-by: Username404 --- src/headers/parsing/ParseComponents.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index 8d6496b..79df329 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -54,9 +54,9 @@ protected: public: inline size_t size() const { return subComponents.size(); } inline bool empty() const { return size() == 0; } - inline iterator begin() const noexcept { return subComponents.begin(); } + inline iterator begin() noexcept { return subComponents.begin(); } inline constant_iterator cbegin() const noexcept { return subComponents.cbegin(); } - inline iterator end() const noexcept { return subComponents.end(); } + inline iterator end() noexcept { return subComponents.end(); } inline constant_iterator cend() const noexcept { return subComponents.cend(); } IS_PARSECOMPONENT vector findById() const { From 3c4dc0ea2881e153a3d0b9c3b5f54e540bd8f0a7 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 17 Apr 2022 14:36:28 +0200 Subject: [PATCH 144/254] Remove a useless break statement in Parser.hpp Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 65f1350..6e49511 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -102,7 +102,6 @@ namespace Parser { parseTree << Reference(current.toktext); } } - break; case ';': break; case LPAR: case LBRACE: case LBRACKET: { const auto closingCharacter = find_corresponding(lexed.begin() + i + 1, lexed.end(), current.toktype, tok::inverseLCharacter(current.toktype)); From e32b2172e5204835f124c61b37fa95b5cd1667e1 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 17 Apr 2022 18:15:16 +0200 Subject: [PATCH 145/254] Use deca::num in Parser.hpp Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 6e49511..0e3f6af 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -51,7 +51,7 @@ namespace Parser { i += 2; const string& right = lexed[i].toktext; p = min(static_cast(right.size()), numeric_limits::digits10); - v += copysign(stold(right.substr(0, p)) / powl(10, p), v); + v += copysign(stold(right.substr(0, p)) / powl(deca::num, p), v); } parseTree << types::Integer(v, p); break; From 014ea9060b0265f72a131b68653bdc8d3b33c04e Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 19 Apr 2022 23:23:49 +0200 Subject: [PATCH 146/254] ParserComponents.hpp: Add a "<<" operator overload (which takes a constant string reference as its argument) to the ParseTree class Signed-off-by: Username404 --- src/headers/parsing/ParseComponents.hpp | 7 ++++++- src/headers/parsing/Parser.hpp | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index 79df329..603052a 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -85,6 +85,7 @@ public: IS_PARSECOMPONENT inline void add(const T& component) { addComponent(component); } IS_PARSECOMPONENT inline void addAll(const initializer_list& components) { addAllComponents(components); } IS_PARSECOMPONENT inline ParseTree& operator<<(const T& component) { add(component); return *this; } + ParseTree& operator<<(const string&); ParseTree(): subComponents() {}; IS_PARSECOMPONENT inline explicit ParseTree(const T& element): ParseTree() { addComponent(element); } IS_PARSECOMPONENT inline ParseTree(const initializer_list& elements): ParseTree() { addAllComponents(elements); } @@ -114,7 +115,7 @@ namespace StandardComponents { }; struct String: ParseComponent { const string content; - explicit String(const char* string): content(string) {} + explicit String(string content_string): content(move(content_string)) {} }; } struct Call: ParseTree, Reference { @@ -130,4 +131,8 @@ namespace StandardComponents { }; } +ParseTree& ParseTree::operator<<(const string& text) { + return *this << StandardComponents::types::String(text); +} + #endif //YERBACON_PARSECOMPONENTS_HPP \ No newline at end of file diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 0e3f6af..2a69526 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -56,7 +56,7 @@ namespace Parser { parseTree << types::Integer(v, p); break; } - case STRING: parseTree << types::String(current.toktext.data()); break; + case STRING: parseTree << current.toktext; break; case IDENTIFIER: { if (current.toktext == "class" || current.toktext == "structure") { if (next.toktype == IDENTIFIER) { From 7df47da35486d607c1871e11d7050b0fbf7cb61f Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 20 Apr 2022 15:23:00 +0200 Subject: [PATCH 147/254] Fix the parsing of ParseTree to ignore previous parsed instances Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 2a69526..c5a3939 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -119,7 +119,9 @@ namespace Parser { if (not parseTree.empty()) { try { auto& previous = dynamic_cast(*parseTree.at(parseTree.size() - 1)); - if (current.toktype != LPAR or previous.getId() == typeid(Call)) { + if (find_if(reverse_iterator(lexed.begin() + i), lexed.rend(), [&closingCharacter](const tok& token){ + return token.toktype != SEMICOLON; + })->toktype != *closingCharacter) { previous = parse(subTokens); i = distance(lexed.begin(), closingCharacter); break; From 97a9703a1a6d5ef0ce2087a3050dba4d73e9f68b Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 20 Apr 2022 19:06:09 +0200 Subject: [PATCH 148/254] Lua.hpp & Js.hpp: Don't insert new lines and indentation when a function is empty Py.hpp: Support empty functions Signed-off-by: Username404 --- src/headers/transpiler/implementations/Js.hpp | 4 ++-- src/headers/transpiler/implementations/Lua.hpp | 8 +++++--- src/headers/transpiler/implementations/Py.hpp | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/headers/transpiler/implementations/Js.hpp b/src/headers/transpiler/implementations/Js.hpp index 7c11394..2efd8c8 100644 --- a/src/headers/transpiler/implementations/Js.hpp +++ b/src/headers/transpiler/implementations/Js.hpp @@ -15,9 +15,9 @@ struct JsTarget: Target { output << "function " << parseComponent.name << '('; separate_transpileTree(parseComponent.parameters, ", "); output << ") {"; - if (newLines) output << separator << indentation; + if (newLines and not parseComponent.empty()) output << separator << indentation; separate_transpileTree(parseComponent, 1); - if (newLines) output << separator; + if (newLines and not parseComponent.empty()) output << separator; output << '}'; ) }; diff --git a/src/headers/transpiler/implementations/Lua.hpp b/src/headers/transpiler/implementations/Lua.hpp index 421e944..d512bb2 100644 --- a/src/headers/transpiler/implementations/Lua.hpp +++ b/src/headers/transpiler/implementations/Lua.hpp @@ -18,10 +18,12 @@ struct LuaTarget: Target { make_task(Function, output << "function " << parseComponent.name << '('; separate_transpileTree(parseComponent.parameters, ", "); - output << ')' << separator; - if (newLines) output << indentation; + output << ')'; + if (not parseComponent.empty()) output << separator << indentation; + else output << ' '; separate_transpileTree(parseComponent, 1); - output << separator << "end"; + if (not parseComponent.empty()) output << separator; + output << "end"; ) }; } diff --git a/src/headers/transpiler/implementations/Py.hpp b/src/headers/transpiler/implementations/Py.hpp index 2e58832..829caf3 100644 --- a/src/headers/transpiler/implementations/Py.hpp +++ b/src/headers/transpiler/implementations/Py.hpp @@ -13,6 +13,7 @@ struct PyTarget: Target { output << "def " << parseComponent.name << '('; separate_transpileTree(parseComponent.parameters, ", "); output << "):" << separator << indentation; + if (parseComponent.empty()) output << "pass"; separate_transpileTree(parseComponent, 1); ), }; From 2330b87c0f06c1d65fa0eee356e40bc4a51dbd4a Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 21 Apr 2022 22:21:08 +0200 Subject: [PATCH 149/254] Target.hpp: Add a "use_uniqueLineSeparator" virtual function Js.hpp: override the new virtual function to always output semicolons Signed-off-by: Username404 --- src/headers/transpiler/Target.hpp | 6 ++++-- src/headers/transpiler/implementations/Js.hpp | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 7366c9f..5dbdc2b 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -107,7 +107,8 @@ protected: IS(ParseTree) void separate_transpileTree(const T& parseTree, const unsigned short& indentationLevel = 0) { transpileTree(parseTree, indentationLevel, [this, &parseTree](const auto& iterator){ - if (iterator + 1 != parseTree.cend()) { output << separator; } + if ((newLines || iterator + 1 == parseTree.cend()) && use_uniqueLineSeparator()) output << uniqueLineSeparator().value(); + if (iterator + 1 != parseTree.cend()) output << separator; }); } IS(ParseTree) @@ -118,6 +119,7 @@ protected: } typedef optional optional_string; virtual optional_string uniqueLineSeparator() { return ";"; }; + virtual bool use_uniqueLineSeparator() { return supportsOneLine(); }; const bool newLines; string separator; static constexpr const char* indentation = " "; @@ -140,7 +142,7 @@ public: }; static shared_ptr forName(string_view name, bool newLines); string transpileWithTree(const ParseTree& tree) { - separator = newLines ? "\n" : (supportsOneLine() ? uniqueLineSeparator().value() : throw Yerbacon::Exception("--newlines=off is not supported by the current target")); + separator = newLines ? "\n" : (use_uniqueLineSeparator() ? uniqueLineSeparator().value() : throw Yerbacon::Exception("--newlines=off is not supported by the current target")); output.str(string()); separate_transpileTree(tree); return output.str() + '\n'; diff --git a/src/headers/transpiler/implementations/Js.hpp b/src/headers/transpiler/implementations/Js.hpp index 2efd8c8..78bb491 100644 --- a/src/headers/transpiler/implementations/Js.hpp +++ b/src/headers/transpiler/implementations/Js.hpp @@ -4,6 +4,7 @@ using namespace StandardComponents; struct JsTarget: Target { print_functions_pair printFunctions() final { return make_pair("util.write", "console.log"); } + bool use_uniqueLineSeparator() final { return true; } unordered_task_map getTaskMap() final { return { make_task(Define, From 0d12f7eceb30d8ed1bf95bb1243d4b064047a89f Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 21 Apr 2022 23:41:28 +0200 Subject: [PATCH 150/254] Parser.hpp: Replace ';' with SEMICOLON Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index c5a3939..a52f3db 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -102,7 +102,7 @@ namespace Parser { parseTree << Reference(current.toktext); } } - case ';': break; + case SEMICOLON: break; case LPAR: case LBRACE: case LBRACKET: { const auto closingCharacter = find_corresponding(lexed.begin() + i + 1, lexed.end(), current.toktype, tok::inverseLCharacter(current.toktype)); vector subTokens(lexed.begin() + i + 1, closingCharacter); From 21ab59fc6d9486193ed59ca61c160e5fe0d4b626 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 22 Apr 2022 01:04:03 +0200 Subject: [PATCH 151/254] Parser.hpp: Add a "filter_comma_list" function to fix commas in parameters or arguments lists Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index a52f3db..4711f64 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -19,6 +19,18 @@ namespace Parser { const bool& quoteTokenText = false ) { error(token, text, token.line, quoteTokenText); } + void filter_comma_list(vector& tokens) { + if (tokens.size() >= 2 && tokens[1].toktype != tok::RPAR) { + for (auto iterator = tokens.begin(); iterator < tokens.end() - 1; ++iterator) { + const auto nextIterator = iterator + 1; + if (nextIterator->toktype == tok::COMMA) { + tokens.erase(nextIterator); + } else throw ParsingException("Missing comma after \"" + iterator->toktext + '"'); + } + } + } + inline vector filter_comma_list(vector&& tokens) { filter_comma_list(tokens); return tokens; } + IS(ParseTree) inline T parse(const input_iterator auto&, const input_iterator auto&); @@ -74,7 +86,7 @@ namespace Parser { if (nextAre({LCOMP, LCOMP, LBRACE})) { Function function(current.toktext); if (parametersDistance > 2) { - function.parameters = parse(lexed.begin() + ((i + 2) - parametersDistance), lexed.begin() + i); + function.parameters = parse(filter_comma_list(vector(lexed.begin() + ((i + 2) - parametersDistance), lexed.begin() + i))); } parseTree << function; i += 2; @@ -106,16 +118,7 @@ namespace Parser { case LPAR: case LBRACE: case LBRACKET: { const auto closingCharacter = find_corresponding(lexed.begin() + i + 1, lexed.end(), current.toktype, tok::inverseLCharacter(current.toktype)); vector subTokens(lexed.begin() + i + 1, closingCharacter); - if (current.toktype == LPAR || current.toktype == LBRACKET) { - if (subTokens.size() >= 2 && subTokens[1].toktype != RPAR) { - for (auto iterator = subTokens.cbegin(); iterator < (subTokens.cend() - 1); ++iterator) { - const auto nextIterator = iterator + 1; - if (nextIterator->toktype == COMMA) { - subTokens.erase(nextIterator); - } else throw ParsingException("Missing comma after \"" + iterator->toktext + '"'); - } - } - } + if (current.toktype == LPAR || current.toktype == LBRACKET) filter_comma_list(subTokens); if (not parseTree.empty()) { try { auto& previous = dynamic_cast(*parseTree.at(parseTree.size() - 1)); From d3b05461cbdb03c5ea210e9adee88baace7294d5 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 22 Apr 2022 12:59:11 +0200 Subject: [PATCH 152/254] Parser.hpp: Stop the loop in the filter_comma_list function when the current iterator points to a COMMA token Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 4711f64..8af5e81 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -21,7 +21,7 @@ namespace Parser { void filter_comma_list(vector& tokens) { if (tokens.size() >= 2 && tokens[1].toktype != tok::RPAR) { - for (auto iterator = tokens.begin(); iterator < tokens.end() - 1; ++iterator) { + for (auto iterator = tokens.begin(); iterator->toktype != tok::COMMA && iterator < tokens.end() - 1; ++iterator) { const auto nextIterator = iterator + 1; if (nextIterator->toktype == tok::COMMA) { tokens.erase(nextIterator); From c0f7b4cc228b091387df4dd36569b3c1982c44a8 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 22 Apr 2022 13:07:31 +0200 Subject: [PATCH 153/254] Parser.hpp: Change the parameters of the filter_comma_list overload to two input iterators Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 8af5e81..835187e 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -29,7 +29,11 @@ namespace Parser { } } } - inline vector filter_comma_list(vector&& tokens) { filter_comma_list(tokens); return tokens; } + vector filter_comma_list(input_iterator auto begin, input_iterator auto end) { + vector tokens(begin, end); + filter_comma_list(tokens); + return tokens; + } IS(ParseTree) inline T parse(const input_iterator auto&, const input_iterator auto&); @@ -86,7 +90,7 @@ namespace Parser { if (nextAre({LCOMP, LCOMP, LBRACE})) { Function function(current.toktext); if (parametersDistance > 2) { - function.parameters = parse(filter_comma_list(vector(lexed.begin() + ((i + 2) - parametersDistance), lexed.begin() + i))); + function.parameters = parse(filter_comma_list(lexed.begin() + ((i + 2) - parametersDistance), lexed.begin() + i)); } parseTree << function; i += 2; From 51b5a546c75c3c36722a29a3f8adff644785bf31 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 23 Apr 2022 01:07:50 +0200 Subject: [PATCH 154/254] Parser.hpp: Remove a useless condition in the filter_comma_list function Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 835187e..6cd1cda 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -20,7 +20,7 @@ namespace Parser { ) { error(token, text, token.line, quoteTokenText); } void filter_comma_list(vector& tokens) { - if (tokens.size() >= 2 && tokens[1].toktype != tok::RPAR) { + if (tokens.size() >= 2) { for (auto iterator = tokens.begin(); iterator->toktype != tok::COMMA && iterator < tokens.end() - 1; ++iterator) { const auto nextIterator = iterator + 1; if (nextIterator->toktype == tok::COMMA) { From b63bf0d480ca8edd9fb9eb4c328ba6c235678b3b Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 24 Apr 2022 01:09:17 +0200 Subject: [PATCH 155/254] Parser.hpp: Remove an unused closingCharacter capture Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 6cd1cda..16f1654 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -126,7 +126,7 @@ namespace Parser { if (not parseTree.empty()) { try { auto& previous = dynamic_cast(*parseTree.at(parseTree.size() - 1)); - if (find_if(reverse_iterator(lexed.begin() + i), lexed.rend(), [&closingCharacter](const tok& token){ + if (find_if(reverse_iterator(lexed.begin() + i), lexed.rend(), [](const tok& token){ return token.toktype != SEMICOLON; })->toktype != *closingCharacter) { previous = parse(subTokens); From 34134dda7122502166dfac7c1d949a090632cf99 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 6 May 2022 22:06:37 +0200 Subject: [PATCH 156/254] Target.hpp: Simplify the Target::forName function and change its return type to unique_ptr instead of shared_ptr Signed-off-by: Username404 --- src/headers/transpiler/Target.hpp | 36 +++++-------------- src/headers/transpiler/implementations/Js.hpp | 2 +- .../transpiler/implementations/Lua.hpp | 2 +- src/headers/transpiler/implementations/Py.hpp | 2 +- 4 files changed, 11 insertions(+), 31 deletions(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 5dbdc2b..3ff70cc 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -140,7 +140,7 @@ public: })); return staticMap; }; - static shared_ptr forName(string_view name, bool newLines); + static unique_ptr forName(string_view name, bool newLines); string transpileWithTree(const ParseTree& tree) { separator = newLines ? "\n" : (use_uniqueLineSeparator() ? uniqueLineSeparator().value() : throw Yerbacon::Exception("--newlines=off is not supported by the current target")); output.str(string()); @@ -156,39 +156,19 @@ public: #include "implementations/Js.hpp" #include "implementations/Py.hpp" -enum LANGUAGE: signed short { NONE = -1, LUA, JS, PY }; -constinit const array languages { "lua", "js", "py" }; - -shared_ptr Target::forName(string_view name, const bool newLines = true) { - LANGUAGE selected = NONE; - for (unsigned int i = 0; i < languages.size(); ++i) { - if (name == languages[i]) { - selected = static_cast(i); - break; - } - } - shared_ptr target; - #define ADDTARGET(X) target = shared_ptr(new X(newLines)) - switch (selected) { - #ifdef LUA_HPP - case LUA: ADDTARGET(LUA_HPP); break; - #endif - #ifdef JS_HPP - case JS: ADDTARGET(JS_HPP); break; - #endif - #ifdef PY_HPP - case PY: ADDTARGET(PY_HPP); break; - #endif - case NONE: - default: Yerbacon::fail({"\"", string(1, (char) toupper(name.at(1))).data(), name.substr(2).data(), "\" is not a valid target."}); - } +unique_ptr Target::forName(string_view name, const bool newLines = true) { + #define ADDTARGET(X, target_class) if (name == X) return unique_ptr(new target_class(newLines)) + ADDTARGET("lua", LuaTarget); + ADDTARGET("js", JsTarget); + ADDTARGET("py", PyTarget); #undef ADDTARGET #undef make_nonlocal_task #undef make_task_noR #undef make_task #undef make_task_base_R #undef make_task_base - return target; + Yerbacon::fail({"\"", to_string(toupper(name.at(1))).data(), name.substr(2).data(), "\" is not a valid target."}); + return nullptr; } #endif //YERBACON_TARGET_HPP \ No newline at end of file diff --git a/src/headers/transpiler/implementations/Js.hpp b/src/headers/transpiler/implementations/Js.hpp index 78bb491..ce8f5c7 100644 --- a/src/headers/transpiler/implementations/Js.hpp +++ b/src/headers/transpiler/implementations/Js.hpp @@ -1,5 +1,5 @@ #ifndef JS_HPP -#define JS_HPP JsTarget +#define JS_HPP using namespace StandardComponents; struct JsTarget: Target { diff --git a/src/headers/transpiler/implementations/Lua.hpp b/src/headers/transpiler/implementations/Lua.hpp index d512bb2..e6283bc 100644 --- a/src/headers/transpiler/implementations/Lua.hpp +++ b/src/headers/transpiler/implementations/Lua.hpp @@ -1,5 +1,5 @@ #ifndef LUA_HPP -#define LUA_HPP LuaTarget +#define LUA_HPP using namespace StandardComponents; struct LuaTarget: Target { diff --git a/src/headers/transpiler/implementations/Py.hpp b/src/headers/transpiler/implementations/Py.hpp index 829caf3..16081a7 100644 --- a/src/headers/transpiler/implementations/Py.hpp +++ b/src/headers/transpiler/implementations/Py.hpp @@ -1,5 +1,5 @@ #ifndef PY_HPP -#define PY_HPP PyTarget +#define PY_HPP using namespace StandardComponents; struct PyTarget: Target { From b7a22e0e5130823f6b5200001b4a17d1bc37cd4a Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 6 May 2022 22:08:17 +0200 Subject: [PATCH 157/254] main.cpp: Fix indentation at line 46 Signed-off-by: Username404 --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 7423ac6..9efd448 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,7 +43,7 @@ int main(int argc, char* argv[]) { unit_result resultingPair; try { resultingPair.first = Target::forName(target, newLines)->transpileWithTree( - parseString(text_provided ? currentArgument : getFileContent(currentArgument.data())) + parseString(text_provided ? currentArgument : getFileContent(currentArgument.data())) ); if (not text_provided) outputFileContent(string(currentArgument.substr(0, currentArgument.size() - 6)) + '.' + target, resultingPair.first); } catch (const Yerbacon::Exception& error) { From 6e3568291115ec0be2eea13e95cdb0a0362ef44e Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 7 May 2022 08:51:15 +0200 Subject: [PATCH 158/254] Target.hpp: Don't use to_string in the Target::forName function Signed-off-by: Username404 --- src/headers/transpiler/Target.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 3ff70cc..ddbc655 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -167,7 +167,7 @@ unique_ptr Target::forName(string_view name, const bool newLines = true) #undef make_task #undef make_task_base_R #undef make_task_base - Yerbacon::fail({"\"", to_string(toupper(name.at(1))).data(), name.substr(2).data(), "\" is not a valid target."}); + Yerbacon::fail({"\"", string(1, (char) toupper(name.at(1))).data(), name.substr(2).data(), "\" is not a valid target."}); return nullptr; } From de658bd03218aeea4cde91c3e29be93935f0d7bf Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 7 May 2022 09:07:32 +0200 Subject: [PATCH 159/254] Target.hpp: Return false by default in the uniqueLineSeparator function Signed-off-by: Username404 --- src/headers/transpiler/Target.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index ddbc655..d4d5fec 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -119,7 +119,7 @@ protected: } typedef optional optional_string; virtual optional_string uniqueLineSeparator() { return ";"; }; - virtual bool use_uniqueLineSeparator() { return supportsOneLine(); }; + virtual bool use_uniqueLineSeparator() { return false; }; const bool newLines; string separator; static constexpr const char* indentation = " "; @@ -142,7 +142,7 @@ public: }; static unique_ptr forName(string_view name, bool newLines); string transpileWithTree(const ParseTree& tree) { - separator = newLines ? "\n" : (use_uniqueLineSeparator() ? uniqueLineSeparator().value() : throw Yerbacon::Exception("--newlines=off is not supported by the current target")); + separator = newLines ? "\n" : (supportsOneLine() ? uniqueLineSeparator().value() : throw Yerbacon::Exception("--newlines=off is not supported by the current target")); output.str(string()); separate_transpileTree(tree); return output.str() + '\n'; From 4097b1c59a627374e7e2dc0cef9a76fcec0b8eaf Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 7 May 2022 09:30:21 +0200 Subject: [PATCH 160/254] Lua.hpp: Only output indentation when newLines is set to true Signed-off-by: Username404 --- src/headers/transpiler/implementations/Lua.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/headers/transpiler/implementations/Lua.hpp b/src/headers/transpiler/implementations/Lua.hpp index e6283bc..84939ad 100644 --- a/src/headers/transpiler/implementations/Lua.hpp +++ b/src/headers/transpiler/implementations/Lua.hpp @@ -19,8 +19,10 @@ struct LuaTarget: Target { output << "function " << parseComponent.name << '('; separate_transpileTree(parseComponent.parameters, ", "); output << ')'; - if (not parseComponent.empty()) output << separator << indentation; - else output << ' '; + if (not parseComponent.empty()) { + output << separator; + if (newLines) output << indentation; + } else output << ' '; separate_transpileTree(parseComponent, 1); if (not parseComponent.empty()) output << separator; output << "end"; From bf321d74652de997508874285a2a90ce813788d8 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 14 May 2022 16:22:58 +0200 Subject: [PATCH 161/254] CMakeLists.txt: Add "-flto-partition=none" to CMAKE_CXX_FLAGS_RELEASE when using G++ and interprocedural optimization Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b14bdc..7968937 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,7 +87,7 @@ if (${IS_GNU}) endif() set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvect-cost-model=unlimited -foptimize-strlen -fsched-pressure -flive-range-shrinkage -fpredictive-commoning -ftree-partial-pre -fzero-call-used-regs=used-gpr-arg -fira-loop-pressure -ftree-loop-distribution -floop-interchange -fsplit-paths -fgcse-las -fgcse-sm -fipa-pta -fstdarg-opt -fivopts") if (${CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE}) - set(CMAKE_CXX_FLAGS_RELEASE "-fwhole-program ${CMAKE_CXX_FLAGS_RELEASE}") + set(CMAKE_CXX_FLAGS_RELEASE "-fwhole-program -flto-partition=none ${CMAKE_CXX_FLAGS_RELEASE}") endif() elseif(${IS_CLANG}) if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_CLANG} AND NOT ${IGNORE_MINIMAL_COMPILER_VERSION}) From 7dadd216a726900701eae4061fafc67995b74184 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 14 May 2022 16:41:31 +0200 Subject: [PATCH 162/254] CMakeLists.txt: Add "-fweb" to the flags for G++ Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7968937..673635c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,7 +85,7 @@ if (${IS_GNU}) if (Threads_FOUND) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ftree-parallelize-loops=2") endif() - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvect-cost-model=unlimited -foptimize-strlen -fsched-pressure -flive-range-shrinkage -fpredictive-commoning -ftree-partial-pre -fzero-call-used-regs=used-gpr-arg -fira-loop-pressure -ftree-loop-distribution -floop-interchange -fsplit-paths -fgcse-las -fgcse-sm -fipa-pta -fstdarg-opt -fivopts") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvect-cost-model=unlimited -foptimize-strlen -fsched-pressure -flive-range-shrinkage -fpredictive-commoning -ftree-partial-pre -fzero-call-used-regs=used-gpr-arg -fira-loop-pressure -ftree-loop-distribution -floop-interchange -fsplit-paths -fgcse-las -fgcse-sm -fipa-pta -fstdarg-opt -fivopts -fweb") if (${CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE}) set(CMAKE_CXX_FLAGS_RELEASE "-fwhole-program -flto-partition=none ${CMAKE_CXX_FLAGS_RELEASE}") endif() From 617837fb916105475af9e7504b632e21e5caac4c Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 14 May 2022 16:50:45 +0200 Subject: [PATCH 163/254] CMakeLists.txt: Suppress the unqualified std cast call warning on clang 15 and higher Signed-off-by: Username404 --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 673635c..3a8c4b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,6 +99,7 @@ elseif(${IS_CLANG}) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fwhole-program-vtables") endif() endif() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-warning-option -Wno-unqualified-std-cast-call") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fstrict-vtable-pointers") elseif(MSVC) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_MSVC} AND NOT ${IGNORE_MINIMAL_COMPILER_VERSION}) From 394fbec4c99f694867b114a4a91e0f01f2c0b4dd Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 14 May 2022 16:54:23 +0200 Subject: [PATCH 164/254] CMakeLists.txt: Disable the "unused command line argument" warning on MinGW toolchains Signed-off-by: Username404 --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a8c4b3..f8cb8d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -214,6 +214,7 @@ elseif(MINGW OR MSVC) set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CODENAME}) set(CPACK_NSIS_INSTALL_ROOT "${CMAKE_INSTALL_PREFIX}") if (MINGW) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-command-line-argument") set(CMAKE_EXE_LINKER_FLAGS "-static -static-libstdc++ -static-libgcc ${CMAKE_EXE_LINKER_FLAGS}") endif() set(CPACK_PACKAGE_FILE_NAME "${PNAME}_wpkg") From 6afd81f9badb0725776ab3d7a6b702d25adae4d5 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 14 May 2022 18:48:14 +0200 Subject: [PATCH 165/254] Update README.md Signed-off-by: Username404 --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index bea13d8..321d4a8 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,16 @@ -# Yerbacon +# Yerbacon -[![Build Status](https://ci.username404.fr/buildStatus/icon?style=plastic)](https://ci.username404.fr/job/Yerbacon/job/stable/) +Yerbacon logo -Yerbacon logo -Aka Yer Bacon, - -- #### A language that transpiles into lua, javascript (ES6) or python code. +### ► A language that transpiles into lua, javascript (ES6) or python code. ``` main >> { print_line("Hello, World!") } ``` +[![Build Status](https://ci.username404.fr/buildStatus/icon?style=plastic)](https://ci.username404.fr/job/Yerbacon/job/stable/) + ### Planned features: - Type inference From 16eeea252423713cefb41f3f8a306a96446849de Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 18 May 2022 18:56:54 +0200 Subject: [PATCH 166/254] Target.hpp: Use reinterpret_cast instead of dynamic_cast CMakeLists.txt: Disable the reinterpret-base-class warning when using Clang Signed-off-by: Username404 --- CMakeLists.txt | 2 +- src/headers/transpiler/Target.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f8cb8d8..d801f8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,7 +99,7 @@ elseif(${IS_CLANG}) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fwhole-program-vtables") endif() endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-warning-option -Wno-unqualified-std-cast-call") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-warning-option -Wno-unqualified-std-cast-call -Wno-reinterpret-base-class") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fstrict-vtable-pointers") elseif(MSVC) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_MSVC} AND NOT ${IGNORE_MINIMAL_COMPILER_VERSION}) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index d4d5fec..9e84a84 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -67,7 +67,7 @@ protected: } typedef function task; #define make_task_base(start, type, captures, function_body) make_pair(type_index(typeid(type)), [captures](const ParseTree& parsedTree, unsigned int& index) { start; function_body }) - #define make_task_base_R(T, C, F) make_task_base(const T& parseComponent = dynamic_cast(*parsedTree[index]), T, C, F) + #define make_task_base_R(T, C, F) make_task_base(const T& parseComponent = reinterpret_cast(*parsedTree[index]), T, C, F) #define make_task(T, F) make_task_base_R(T, this, F) #define make_task_noR(T, F) make_task_base(,T, this, F) #define make_nonlocal_task(T, F) make_task_base_R(T, , F) From dcd3354604803b337f5a0f435baf7ff225d218f7 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 20 May 2022 17:10:37 +0200 Subject: [PATCH 167/254] CMakeLists.txt: Make sure conforming mode is enabled when using MSVC Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d801f8c..4b68f16 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,7 +105,7 @@ elseif(MSVC) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_MSVC} AND NOT ${IGNORE_MINIMAL_COMPILER_VERSION}) message(FATAL_ERROR "MSVC ${MINIMAL_MSVC} or higher is required") endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR /W3 /Zc:__cplusplus /Zc:preprocessor /Zc:throwingNew /Zc:inline") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive- /GR /W3 /Zc:__cplusplus /Zc:preprocessor /Zc:throwingNew /Zc:inline") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") endif() string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPERCASE_BUILD_TYPE) From dfb2ac8062de95d0710124bc4157f535155cc911 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 20 May 2022 17:11:12 +0200 Subject: [PATCH 168/254] CMakeLists.txt: Fix template errors on MSVC Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b68f16..3118604 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,7 +105,7 @@ elseif(MSVC) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_MSVC} AND NOT ${IGNORE_MINIMAL_COMPILER_VERSION}) message(FATAL_ERROR "MSVC ${MINIMAL_MSVC} or higher is required") endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive- /GR /W3 /Zc:__cplusplus /Zc:preprocessor /Zc:throwingNew /Zc:inline") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive- /Zc:twoPhase- /GR /W3 /Zc:__cplusplus /Zc:preprocessor /Zc:throwingNew /Zc:inline") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") endif() string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPERCASE_BUILD_TYPE) From f0128bf0c31dd6dae87f95eadedcba1a6d41e50d Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 20 May 2022 17:14:09 +0200 Subject: [PATCH 169/254] CMakeLists.txt: Use the standard C++ exception handling model on MSVC Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3118604..f6beaef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,7 +105,7 @@ elseif(MSVC) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_MSVC} AND NOT ${IGNORE_MINIMAL_COMPILER_VERSION}) message(FATAL_ERROR "MSVC ${MINIMAL_MSVC} or higher is required") endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive- /Zc:twoPhase- /GR /W3 /Zc:__cplusplus /Zc:preprocessor /Zc:throwingNew /Zc:inline") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive- /Zc:twoPhase- /EHsc /GR /W3 /Zc:__cplusplus /Zc:preprocessor /Zc:throwingNew /Zc:inline") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") endif() string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPERCASE_BUILD_TYPE) From a8e514d67fcb44ca6d3201d46b59bc1d52d5ce0d Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 26 May 2022 11:55:25 +0200 Subject: [PATCH 170/254] Parser.hpp: Prevent the redefinition of functions Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 16f1654..89591a7 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -88,6 +88,8 @@ namespace Parser { i += parametersDistance; } if (nextAre({LCOMP, LCOMP, LBRACE})) { + if (parseTree.template findReferenceByName(current.toktext).has_value()) + parsingError(current, " is already defined", true); Function function(current.toktext); if (parametersDistance > 2) { function.parameters = parse(filter_comma_list(lexed.begin() + ((i + 2) - parametersDistance), lexed.begin() + i)); From 46a09217fe29edd83af77fed2ff96cacbd96c72d Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 26 May 2022 13:32:41 +0200 Subject: [PATCH 171/254] Parser.hpp: Prevent the reuse of identifiers Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 89591a7..c69e239 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -88,8 +88,6 @@ namespace Parser { i += parametersDistance; } if (nextAre({LCOMP, LCOMP, LBRACE})) { - if (parseTree.template findReferenceByName(current.toktext).has_value()) - parsingError(current, " is already defined", true); Function function(current.toktext); if (parametersDistance > 2) { function.parameters = parse(filter_comma_list(lexed.begin() + ((i + 2) - parametersDistance), lexed.begin() + i)); @@ -140,6 +138,22 @@ namespace Parser { } default: parsingError(current, " \u27F5 Unexpected character", true); } + try { + const auto& last = parseTree.cend() - 1; + const type_info& lastId = last->get()->getId(); + const auto& last_identifier = dynamic_cast(**last); + if (lastId != typeid(Reference) && + lastId != typeid(Call) && + lastId != typeid(Define) and + any_of(parseTree.cbegin(), last, [&last_identifier](const component_ptr& pointer){ + try { + return dynamic_cast(*pointer).name == last_identifier.name; + } catch (const bad_cast&) { + return false; + } + })) + { parsingError(current, " has already been defined previously", true); } + } catch (const bad_cast&) {} } return parseTree; } From 7ebf0ab5a4c5822e6f3e89aeac62df81d43ff518 Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 26 May 2022 13:33:14 +0200 Subject: [PATCH 172/254] Parser.hpp: Shorten two "if" statements Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index c69e239..1d7f58c 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -89,9 +89,8 @@ namespace Parser { } if (nextAre({LCOMP, LCOMP, LBRACE})) { Function function(current.toktext); - if (parametersDistance > 2) { + if (parametersDistance > 2) function.parameters = parse(filter_comma_list(lexed.begin() + ((i + 2) - parametersDistance), lexed.begin() + i)); - } parseTree << function; i += 2; break; @@ -100,11 +99,8 @@ namespace Parser { bool isFinalDefine = nextAre({TAG, DEFINE}); if (isFinalDefine || next.toktype == DEFINE) { const optional previousDefinition = parseTree.template findReferenceByName(current.toktext); - if (previousDefinition.has_value()) { - if (previousDefinition.value().get().final || isFinalDefine) { - parsingError(current, previousDefinition->get().final ? " cannot be redefined as it is final" : " cannot be made final after it has been declared", true); - } - } + if (previousDefinition.has_value() && (previousDefinition.value().get().final || isFinalDefine)) + parsingError(current, previousDefinition->get().final ? " cannot be redefined as it is final" : " cannot be made final after it has been declared", true); const unsigned increment = 2 + isFinalDefine; const auto beginning = lexed.begin() + i + increment; const auto end = find_if(beginning, lexed.end(), [¤t](const tok& it){ From 9e29ec8c29b5452cd864d3c15c639eb6195ce2e8 Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 26 May 2022 13:42:52 +0200 Subject: [PATCH 173/254] docs/gettingstarted.md: Remove the "Main" section Signed-off-by: Username404 --- docs/gettingstarted.md | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/docs/gettingstarted.md b/docs/gettingstarted.md index 1a3a146..4358eba 100644 --- a/docs/gettingstarted.md +++ b/docs/gettingstarted.md @@ -20,15 +20,7 @@ getHelloWorld: String >> { } ``` -### 2.1 - Main -Main can be a variable named `main` that contains an anonymous function, a function named `main` or a function that has the `as_main` attribute: -``` -main #= {} -main >> {} -as_main helloWorld >> {} -``` - -### 2.2 - Function parameters +### 2.1 - Function parameters Parameters can be added to an anonymous function by specifying the types as follows: ``` addIntToString: (int, String)~ #= { a, b; @@ -43,7 +35,7 @@ addIntToString(a: int, b: String) => { } ``` -### 2.3 - Function calls +### 2.2 - Function calls A function can be simply invoked like this if it has no parameters: ``` helloWorld() @@ -97,7 +89,5 @@ class Program { } } -main >> { - Program("World") -} +program #= Program("World") ``` \ No newline at end of file From b206dfa879a81b85133ecbee2bd1480821b19916 Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 26 May 2022 13:44:35 +0200 Subject: [PATCH 174/254] Update examples/HelloWorld.ybcon and README.md Signed-off-by: Username404 --- README.md | 1 + examples/HelloWorld.ybcon | 2 ++ 2 files changed, 3 insertions(+) diff --git a/README.md b/README.md index 321d4a8..4d46185 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ main >> { print_line("Hello, World!") } +main() ``` [![Build Status](https://ci.username404.fr/buildStatus/icon?style=plastic)](https://ci.username404.fr/job/Yerbacon/job/stable/) diff --git a/examples/HelloWorld.ybcon b/examples/HelloWorld.ybcon index 5cd203f..086af0b 100644 --- a/examples/HelloWorld.ybcon +++ b/examples/HelloWorld.ybcon @@ -1,3 +1,5 @@ main >> { print_line("Hello, World!") } + +main() \ No newline at end of file From 1469d92bdf0888e2bbd9e5a8c24514ecfa30abac Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 10 Jun 2022 20:02:07 +0200 Subject: [PATCH 175/254] CMakeLists.txt: Don't link against OpenMP when using static linking Signed-off-by: Username404 --- CMakeLists.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f6beaef..64c831b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,10 +50,12 @@ find_package(Threads) if (${IS_GNU} OR ${IS_CLANG}) set(THREADS_PREFER_PTHREAD_FLAG TRUE) if (Threads_FOUND AND NOT MINGW) - include(FindOpenMP) - if (OpenMP_CXX_FOUND) - set(CMAKE_CXX_FLAGS "${OpenMP_CXX_FLAGS} ${CMAKE_CXX_FLAGS}") - add_definitions(-D_GLIBCXX_PARALLEL) + if (NOT ("${CMAKE_EXE_LINKER_FLAGS}" MATCHES "^-static")) + include(FindOpenMP) + if (OpenMP_CXX_FOUND) + set(CMAKE_CXX_FLAGS "${OpenMP_CXX_FLAGS} ${CMAKE_CXX_FLAGS}") + add_definitions(-D_GLIBCXX_PARALLEL) + endif() endif() endif() if (NOT DEFINED EMSCRIPTEN) From 853f9045289e2b0d11158a92fcd72bd6a6679d43 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 10 Jun 2022 22:15:51 +0200 Subject: [PATCH 176/254] Jenkinsfile: Link the binaries statically with muslc instead of linking them dynamically with glibc Signed-off-by: Username404 --- Jenkinsfile | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 566050e..f61ce62 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -6,7 +6,7 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: "cmake-build-${packageArch}${suffix}", buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=/usr/bin/${path}-ld.gold -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS_PRIVATE_DIRS=/usr/${path}/lib/ -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", + cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=/usr/bin/${path}-ld.gold -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", generator: cmake_generator() cmake arguments: "--build ./cmake-build-${packageArch}${suffix} --target ybcon", installation: 'Latest' sh "/usr/bin/${path}-strip -s ./cmake-build-${packageArch}${suffix}/ybcon*" @@ -20,9 +20,9 @@ final String windowsSuffix = '-windows' - Sidebar Link - Workspace Cleanup Required Compilers: - - G++ for x86_64, i686, armel, armhf, aarch64 and riscv64 - - Emscripten Clang (https://github.com/emscripten-core/emsdk) - - MinGW32 G++/Clang (https://github.com/mstorsjo/llvm-mingw) for x86_64, i686, armhf and aarch64 + - Musl cross-compiling toolchains (archives ending in "-cross" from https://musl.cc/#binaries) for x86_64, i686, armel, armhf, aarch64, riscv64, x86_64-w64 and i686-w64, unzipped into /usr/, along with soft links from /usr/bin/ to the binaries + - Emscripten Clang (https://github.com/emscripten-core/emsdk) in /usr/share/ + - MinGW32 G++/Clang (https://github.com/mstorsjo/llvm-mingw) for armhf and aarch64, unzipped into /usr/, along with soft links from /usr/bin/ to the binaries */ pipeline { @@ -42,8 +42,8 @@ pipeline { stage('Build') { steps { echo "Building the ${env.BRANCH_NAME} branch.." - buildTarget('x86_64-linux-gnu', 'x86_64', 'amd64') - buildTarget('i686-linux-gnu', 'i386', 'i386') + buildTarget('x86_64-linux-musl', 'x86_64', 'amd64') + buildTarget('i686-linux-musl', 'i386', 'i386') cmakeBuild buildDir: "cmake-build-release-emscripten", buildType: 'release', cleanBuild: true, installation: 'Latest', cmakeArgs: "-DCMAKE_TOOLCHAIN_FILE=\"/usr/share/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake\" ${no_compilation_cache_flags()}", generator: cmake_generator() @@ -53,10 +53,10 @@ pipeline { stage('Build for other architectures') { steps { catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { - buildTarget('arm-linux-gnueabi', 'armv4l', 'armel') - buildTarget('arm-linux-gnueabihf', 'armv7hl', 'armhf') - buildTarget('aarch64-linux-gnu', 'aarch64', 'arm64', false) - buildTarget('riscv64-linux-gnu', 'riscv64', 'riscv64') + buildTarget('armel-linux-musleabi', 'armv4l', 'armel') + buildTarget('armv7l-linux-musleabihf', 'armv7hl', 'armhf') + buildTarget('aarch64-linux-musl', 'aarch64', 'arm64', false) + buildTarget('riscv64-linux-musl', 'riscv64', 'riscv64') } } } From f88ceebf3a06036d6003024a1709b2dad0a392da Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 10 Jun 2022 22:41:14 +0200 Subject: [PATCH 177/254] Jenkinsfile: Use ld when ld.gold is not available Signed-off-by: Username404 --- Jenkinsfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index f61ce62..de08367 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -4,9 +4,10 @@ String no_compilation_cache_flags() { return '-DNO_CCACHE=ON -DCMAKE_DISABLE_PRE def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch', boolean isPackageArchDeb = true, String suffix = '') { final String packageArch = isPackageArchDeb ? debArch : rpmArch; final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' + final String linker = "/usr/bin/${path}-ld" // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: "cmake-build-${packageArch}${suffix}", buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=/usr/bin/${path}-ld.gold -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", + cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", generator: cmake_generator() cmake arguments: "--build ./cmake-build-${packageArch}${suffix} --target ybcon", installation: 'Latest' sh "/usr/bin/${path}-strip -s ./cmake-build-${packageArch}${suffix}/ybcon*" From 206549eb66c1dfbc04791e8334bf9f4949a94bb7 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 10 Jun 2022 22:51:38 +0200 Subject: [PATCH 178/254] Jenkinsfile: Update the "Required Compilers" since musl does not seem to support std::future when cross-compiling for Windows Signed-off-by: Username404 --- Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index de08367..07d4b06 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -21,9 +21,9 @@ final String windowsSuffix = '-windows' - Sidebar Link - Workspace Cleanup Required Compilers: - - Musl cross-compiling toolchains (archives ending in "-cross" from https://musl.cc/#binaries) for x86_64, i686, armel, armhf, aarch64, riscv64, x86_64-w64 and i686-w64, unzipped into /usr/, along with soft links from /usr/bin/ to the binaries + - Musl cross-compiling toolchains (archives ending in "-cross" from https://musl.cc/#binaries) for x86_64, i686, armel, armhf, aarch64 and riscv64, unzipped into /usr/, along with soft links from /usr/bin/ to the binaries - Emscripten Clang (https://github.com/emscripten-core/emsdk) in /usr/share/ - - MinGW32 G++/Clang (https://github.com/mstorsjo/llvm-mingw) for armhf and aarch64, unzipped into /usr/, along with soft links from /usr/bin/ to the binaries + - MinGW32 G++/Clang (https://github.com/mstorsjo/llvm-mingw) for x86_64, i686, armhf and aarch64, unzipped into /usr/, along with soft links from /usr/bin/ to the binaries */ pipeline { From 70f82953f894047badbc31b016253b6e1beba823 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 10 Jun 2022 22:58:22 +0200 Subject: [PATCH 179/254] Jenkinsfile: Clarify the MinGW part of the "Required Compilers" section Signed-off-by: Username404 --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 07d4b06..112ce77 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -23,7 +23,7 @@ final String windowsSuffix = '-windows' Required Compilers: - Musl cross-compiling toolchains (archives ending in "-cross" from https://musl.cc/#binaries) for x86_64, i686, armel, armhf, aarch64 and riscv64, unzipped into /usr/, along with soft links from /usr/bin/ to the binaries - Emscripten Clang (https://github.com/emscripten-core/emsdk) in /usr/share/ - - MinGW32 G++/Clang (https://github.com/mstorsjo/llvm-mingw) for x86_64, i686, armhf and aarch64, unzipped into /usr/, along with soft links from /usr/bin/ to the binaries + - MinGW32 G++/Clang (https://github.com/mstorsjo/llvm-mingw) for x86_64, i686, armhf and aarch64, (unzip the content of the folder in the tar.xz file) in /usr/, along with soft links from /usr/bin/ to the binaries */ pipeline { From 6afec609b0abffeaf6f9748124fba25674e93671 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 10 Jun 2022 23:43:30 +0200 Subject: [PATCH 180/254] Jenkinsfile: Use glibc when compiling for riscv64 since the riscv64 cross-compiler doesn't seem to work Signed-off-by: Username404 --- Jenkinsfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 112ce77..a23a1f5 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -21,7 +21,8 @@ final String windowsSuffix = '-windows' - Sidebar Link - Workspace Cleanup Required Compilers: - - Musl cross-compiling toolchains (archives ending in "-cross" from https://musl.cc/#binaries) for x86_64, i686, armel, armhf, aarch64 and riscv64, unzipped into /usr/, along with soft links from /usr/bin/ to the binaries + - G++ cross-compiler for riscv64 + - Musl cross-compiling toolchains (archives ending in "-cross" from https://musl.cc/#binaries) for x86_64, i686, armel, armhf and aarch64, unzipped into /usr/, along with soft links from /usr/bin/ to the binaries - Emscripten Clang (https://github.com/emscripten-core/emsdk) in /usr/share/ - MinGW32 G++/Clang (https://github.com/mstorsjo/llvm-mingw) for x86_64, i686, armhf and aarch64, (unzip the content of the folder in the tar.xz file) in /usr/, along with soft links from /usr/bin/ to the binaries */ @@ -57,7 +58,7 @@ pipeline { buildTarget('armel-linux-musleabi', 'armv4l', 'armel') buildTarget('armv7l-linux-musleabihf', 'armv7hl', 'armhf') buildTarget('aarch64-linux-musl', 'aarch64', 'arm64', false) - buildTarget('riscv64-linux-musl', 'riscv64', 'riscv64') + buildTarget('riscv64-linux-gnu', 'riscv64', 'riscv64') } } } From 7b6e2165ba507512af742ed55488a9bd9af43c50 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 11 Jun 2022 16:11:06 +0200 Subject: [PATCH 181/254] CMakeLists.txt: Find a self-packer and use it if it's found (except when CMAKE_BUILD_TYPE is set to Debug or RelWithDebInfo) Add the --ultra-brute flag when upx is found Signed-off-by: Username404 --- CMakeLists.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 64c831b..bb598e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,6 +152,17 @@ if (Threads_FOUND) target_link_libraries(${EXENAME} PRIVATE Threads::Threads) endif() +option(NO_SELF_PACKER "Disables usage of a self-packer") +if (NOT (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo OR NO_SELF_PACKER OR DEFINED EMSCRIPTEN)) + include(FindSelfPackers) + if (SELF_PACKER_FOR_EXECUTABLE MATCHES upx) + set(SELF_PACKER_FOR_EXECUTABLE_FLAGS ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} --ultra-brute) + endif() + if (NOT SELF_PACKER_FOR_EXECUTABLE EQUAL "") + add_custom_command(TARGET ${EXENAME} POST_BUILD COMMAND "${SELF_PACKER_FOR_EXECUTABLE}" ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} $ VERBATIM) + endif() +endif() + # lpkg = linux package, wpkg = windows package set(PNAME ${PROJECT_NAME}-${CODENAME}-${TIME}) if (UNIX AND NOT (MINGW OR CMAKE_HOST_WIN32)) From 4f2f4a7fa9a96bcc8e6fa06549eecd643bfbb90e Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 11 Jun 2022 16:11:56 +0200 Subject: [PATCH 182/254] CMakeLists.txt: Remove a few useless symbols in a condition Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bb598e8..3fa5695 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,7 @@ find_package(Threads) if (${IS_GNU} OR ${IS_CLANG}) set(THREADS_PREFER_PTHREAD_FLAG TRUE) if (Threads_FOUND AND NOT MINGW) - if (NOT ("${CMAKE_EXE_LINKER_FLAGS}" MATCHES "^-static")) + if (NOT ("${CMAKE_EXE_LINKER_FLAGS}" MATCHES -static)) include(FindOpenMP) if (OpenMP_CXX_FOUND) set(CMAKE_CXX_FLAGS "${OpenMP_CXX_FLAGS} ${CMAKE_CXX_FLAGS}") From faf15b4ccf6e42498b92d964d0a44605f5b6bd26 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 11 Jun 2022 16:26:44 +0200 Subject: [PATCH 183/254] CMakeLists.txt: Add "--best" to the flags for UPX Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3fa5695..1ba8c99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,7 +156,7 @@ option(NO_SELF_PACKER "Disables usage of a self-packer") if (NOT (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo OR NO_SELF_PACKER OR DEFINED EMSCRIPTEN)) include(FindSelfPackers) if (SELF_PACKER_FOR_EXECUTABLE MATCHES upx) - set(SELF_PACKER_FOR_EXECUTABLE_FLAGS ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} --ultra-brute) + set(SELF_PACKER_FOR_EXECUTABLE_FLAGS ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} --ultra-brute --best) endif() if (NOT SELF_PACKER_FOR_EXECUTABLE EQUAL "") add_custom_command(TARGET ${EXENAME} POST_BUILD COMMAND "${SELF_PACKER_FOR_EXECUTABLE}" ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} $ VERBATIM) From a741422dbc6c7bac0854e2be4b6a5ddaac776956 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 11 Jun 2022 16:31:56 +0200 Subject: [PATCH 184/254] Jenkinsfile: Add a "build_directory" local variable Signed-off-by: Username404 --- Jenkinsfile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index a23a1f5..dcf395c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -5,13 +5,14 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch final String packageArch = isPackageArchDeb ? debArch : rpmArch; final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' final String linker = "/usr/bin/${path}-ld" + final String build_directory = "cmake-build-${packageArch}${suffix}" // Note: CMake 3.20 or higher is needed - cmakeBuild buildDir: "cmake-build-${packageArch}${suffix}", buildType: 'release', cleanBuild: true, installation: 'Latest', + cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", generator: cmake_generator() - cmake arguments: "--build ./cmake-build-${packageArch}${suffix} --target ybcon", installation: 'Latest' - sh "/usr/bin/${path}-strip -s ./cmake-build-${packageArch}${suffix}/ybcon*" - cpack installation: 'Latest', workingDir: "cmake-build-${packageArch}${suffix}" + cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' + sh "/usr/bin/${path}-strip -s ./$build_directory/ybcon*" + cpack installation: 'Latest', workingDir: build_directory } final String windowsSuffix = '-windows' From c18e642903080913a2d8ea248489e9bad8277a42 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 11 Jun 2022 16:36:47 +0200 Subject: [PATCH 185/254] Jenkinsfile: Don't run strip on executables when UPX is installed on the host Signed-off-by: Username404 --- Jenkinsfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index dcf395c..4d3ca2b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -11,7 +11,9 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", generator: cmake_generator() cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' - sh "/usr/bin/${path}-strip -s ./$build_directory/ybcon*" + if (!fileExists('/usr/bin/upx')) { + sh "/usr/bin/${path}-strip -s ./$build_directory/ybcon*" + } cpack installation: 'Latest', workingDir: build_directory } From 8923bdb12e70c23d36b73551d6322714a9277cab Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 11 Jun 2022 17:12:38 +0200 Subject: [PATCH 186/254] Jenkinsfile: Add an "Optional Tools" section to the comment Signed-off-by: Username404 --- Jenkinsfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 4d3ca2b..89d8be3 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -28,6 +28,9 @@ final String windowsSuffix = '-windows' - Musl cross-compiling toolchains (archives ending in "-cross" from https://musl.cc/#binaries) for x86_64, i686, armel, armhf and aarch64, unzipped into /usr/, along with soft links from /usr/bin/ to the binaries - Emscripten Clang (https://github.com/emscripten-core/emsdk) in /usr/share/ - MinGW32 G++/Clang (https://github.com/mstorsjo/llvm-mingw) for x86_64, i686, armhf and aarch64, (unzip the content of the folder in the tar.xz file) in /usr/, along with soft links from /usr/bin/ to the binaries + Optional Tools: + - Ninja + - UPX (the devel branch is required because of a bug which is not fixed in the 3.96 version) */ pipeline { From 28bac143039432646d5c6dee8d278e266cb874a7 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 11 Jun 2022 17:19:48 +0200 Subject: [PATCH 187/254] Jenkinsfile: Disable UPX when compiling for the riscv architecture Signed-off-by: Username404 --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 89d8be3..2375ceb 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -8,7 +8,7 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch final String build_directory = "cmake-build-${packageArch}${suffix}" // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", + cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DNO_SELF_PACKER=${path.contains('riscv') ? 'ON' : 'OFF'} -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", generator: cmake_generator() cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' if (!fileExists('/usr/bin/upx')) { From ffb4b2bce38ba12b6f944c2787af56313105684f Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 11 Jun 2022 17:20:39 +0200 Subject: [PATCH 188/254] Jenkinsfile: Set the timeout to 25 minutes Signed-off-by: Username404 --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 2375ceb..0a68885 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -38,7 +38,7 @@ pipeline { options { buildDiscarder(logRotator(numToKeepStr: '48', artifactNumToKeepStr: '96')) - timeout(time: 8, unit: 'MINUTES') + timeout(time: 25, unit: 'MINUTES') sidebarLinks([ [displayName: 'Gitea Repository', iconFileName: '/userContent/Yerbacon.png', urlName: 'https://gits.username404.fr/Username404-59/Yerbacon/src/branch/' + env.BRANCH_NAME] ]) From e9468a3c7efe773790d8d7e5c04a0e905cc4634c Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 11 Jun 2022 17:21:48 +0200 Subject: [PATCH 189/254] Jenkinsfile: Fix indentation at line 31 Signed-off-by: Username404 --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 0a68885..ad95e67 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -28,7 +28,7 @@ final String windowsSuffix = '-windows' - Musl cross-compiling toolchains (archives ending in "-cross" from https://musl.cc/#binaries) for x86_64, i686, armel, armhf and aarch64, unzipped into /usr/, along with soft links from /usr/bin/ to the binaries - Emscripten Clang (https://github.com/emscripten-core/emsdk) in /usr/share/ - MinGW32 G++/Clang (https://github.com/mstorsjo/llvm-mingw) for x86_64, i686, armhf and aarch64, (unzip the content of the folder in the tar.xz file) in /usr/, along with soft links from /usr/bin/ to the binaries - Optional Tools: + Optional Tools: - Ninja - UPX (the devel branch is required because of a bug which is not fixed in the 3.96 version) */ From 89888113e7f14529331a3b4f79beb31c25d62a9e Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 11 Jun 2022 17:38:44 +0200 Subject: [PATCH 190/254] CMakeLists.txt: Disable UPX when using a mingw toolchain, else the produced executable crashes at runtime Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ba8c99..d1ada8e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,7 +153,7 @@ if (Threads_FOUND) endif() option(NO_SELF_PACKER "Disables usage of a self-packer") -if (NOT (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo OR NO_SELF_PACKER OR DEFINED EMSCRIPTEN)) +if (NOT (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo OR NO_SELF_PACKER OR DEFINED EMSCRIPTEN OR MINGW)) include(FindSelfPackers) if (SELF_PACKER_FOR_EXECUTABLE MATCHES upx) set(SELF_PACKER_FOR_EXECUTABLE_FLAGS ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} --ultra-brute --best) From 84add6cbde54efe426163ccc65093ae9e411e965 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 11 Jun 2022 19:06:24 +0200 Subject: [PATCH 191/254] Jenkinsfile: Set CPACK_STRIP_FILES to FALSE CMakeLists.txt: Don't redefine CPACK_STRIP_FILES if it is already defined Signed-off-by: Username404 --- CMakeLists.txt | 4 +++- Jenkinsfile | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d1ada8e..f2bd6a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,7 +130,9 @@ endif() # CPack configuration set(CPACK_THREADS 0) # Used by CMake 3.20+ set(CPACK_ARCHIVE_THREADS ${CPACK_THREADS}) -set(CPACK_STRIP_FILES TRUE) +if (NOT DEFINED CPACK_STRIP_FILES) + set(CPACK_STRIP_FILES TRUE) +endif() set(CPACK_VERBATIM_VARIABLES TRUE) string(TIMESTAMP TIME "%Y.%m+%d") set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}-${TIME}") diff --git a/Jenkinsfile b/Jenkinsfile index ad95e67..e0090d4 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -8,7 +8,7 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch final String build_directory = "cmake-build-${packageArch}${suffix}" // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DNO_SELF_PACKER=${path.contains('riscv') ? 'ON' : 'OFF'} -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", + cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DNO_SELF_PACKER=${path.contains('riscv') ? 'ON' : 'OFF'} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DCPACK_STRIP_FILES=FALSE ${no_compilation_cache_flags()}", generator: cmake_generator() cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' if (!fileExists('/usr/bin/upx')) { From f391b637a9f21d0e6aded728c729ed7e2aea5997 Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 16 Jun 2022 22:38:05 +0200 Subject: [PATCH 192/254] Jenkinsfile: Set NO_SELF_PACKER to ON when upx does not exist in the /usr/bin directory Signed-off-by: Username404 --- Jenkinsfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index e0090d4..5ec9ba1 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -6,12 +6,13 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' final String linker = "/usr/bin/${path}-ld" final String build_directory = "cmake-build-${packageArch}${suffix}" + final boolean upx_exists = fileExists('/usr/bin/upx') // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DNO_SELF_PACKER=${path.contains('riscv') ? 'ON' : 'OFF'} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DCPACK_STRIP_FILES=FALSE ${no_compilation_cache_flags()}", + cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DNO_SELF_PACKER=${!upx_exists || path.contains('riscv') ? 'ON' : 'OFF'} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DCPACK_STRIP_FILES=FALSE ${no_compilation_cache_flags()}", generator: cmake_generator() cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' - if (!fileExists('/usr/bin/upx')) { + if (!upx_exists) { sh "/usr/bin/${path}-strip -s ./$build_directory/ybcon*" } cpack installation: 'Latest', workingDir: build_directory From c7fcee143ce51d6d541f084073d72d68d04d29d2 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 18 Jun 2022 13:54:02 +0200 Subject: [PATCH 193/254] Jenkinsfile: Strip riscv executables Signed-off-by: Username404 --- Jenkinsfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 5ec9ba1..01e4c10 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -7,12 +7,13 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch final String linker = "/usr/bin/${path}-ld" final String build_directory = "cmake-build-${packageArch}${suffix}" final boolean upx_exists = fileExists('/usr/bin/upx') + final boolean is_riscv = path.contains('riscv') // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DNO_SELF_PACKER=${!upx_exists || path.contains('riscv') ? 'ON' : 'OFF'} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DCPACK_STRIP_FILES=FALSE ${no_compilation_cache_flags()}", + cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DNO_SELF_PACKER=${!upx_exists || is_riscv ? 'ON' : 'OFF'} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DCPACK_STRIP_FILES=FALSE ${no_compilation_cache_flags()}", generator: cmake_generator() cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' - if (!upx_exists) { + if (!upx_exists || is_riscv) { sh "/usr/bin/${path}-strip -s ./$build_directory/ybcon*" } cpack installation: 'Latest', workingDir: build_directory From 6ddf9a5dd213141fec9d1321a6bcdfc077c9da05 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 18 Jun 2022 14:45:53 +0200 Subject: [PATCH 194/254] Revert "Jenkinsfile: Set CPACK_STRIP_FILES to FALSE" This reverts commit 84add6cb Signed-off-by: Username404 --- CMakeLists.txt | 4 +--- Jenkinsfile | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f2bd6a0..d1ada8e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,9 +130,7 @@ endif() # CPack configuration set(CPACK_THREADS 0) # Used by CMake 3.20+ set(CPACK_ARCHIVE_THREADS ${CPACK_THREADS}) -if (NOT DEFINED CPACK_STRIP_FILES) - set(CPACK_STRIP_FILES TRUE) -endif() +set(CPACK_STRIP_FILES TRUE) set(CPACK_VERBATIM_VARIABLES TRUE) string(TIMESTAMP TIME "%Y.%m+%d") set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}-${TIME}") diff --git a/Jenkinsfile b/Jenkinsfile index 01e4c10..e05dd43 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -10,7 +10,7 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch final boolean is_riscv = path.contains('riscv') // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DNO_SELF_PACKER=${!upx_exists || is_riscv ? 'ON' : 'OFF'} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DCPACK_STRIP_FILES=FALSE ${no_compilation_cache_flags()}", + cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DNO_SELF_PACKER=${!upx_exists || is_riscv ? 'ON' : 'OFF'} -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", generator: cmake_generator() cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' if (!upx_exists || is_riscv) { From 219fb02a57bf9845621c048f74a9f18abe1d2077 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 19 Jun 2022 11:51:45 +0200 Subject: [PATCH 195/254] Jenkinsfile: Use strip only because upx does not seem to work with stripped executables and therefore can't possibly save more memory Signed-off-by: Username404 --- Jenkinsfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index e05dd43..427a641 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -5,16 +5,17 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch final String packageArch = isPackageArchDeb ? debArch : rpmArch; final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' final String linker = "/usr/bin/${path}-ld" + final String strip = "/usr/bin/${path}-strip" final String build_directory = "cmake-build-${packageArch}${suffix}" final boolean upx_exists = fileExists('/usr/bin/upx') final boolean is_riscv = path.contains('riscv') // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DNO_SELF_PACKER=${!upx_exists || is_riscv ? 'ON' : 'OFF'} -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", + cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DNO_SELF_PACKER=ON -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", generator: cmake_generator() cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' - if (!upx_exists || is_riscv) { - sh "/usr/bin/${path}-strip -s ./$build_directory/ybcon*" + if (fileExists(strip)) { + sh "$strip -s ./$build_directory/ybcon*" } cpack installation: 'Latest', workingDir: build_directory } From 1d33c25c56c8c7f25525f7cc394d8aa0900bd095 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 19 Jun 2022 11:55:22 +0200 Subject: [PATCH 196/254] Jenkinsfile: Remove the upx section in the tools comment Signed-off-by: Username404 --- Jenkinsfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 427a641..c2b219f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -33,7 +33,6 @@ final String windowsSuffix = '-windows' - MinGW32 G++/Clang (https://github.com/mstorsjo/llvm-mingw) for x86_64, i686, armhf and aarch64, (unzip the content of the folder in the tar.xz file) in /usr/, along with soft links from /usr/bin/ to the binaries Optional Tools: - Ninja - - UPX (the devel branch is required because of a bug which is not fixed in the 3.96 version) */ pipeline { From 7baac757d25e23b46f76751de21a599b0b5f8644 Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 23 Jun 2022 22:49:06 +0200 Subject: [PATCH 197/254] CMakeLists.txt: Use PROJECT_NAME in more places for consistency Signed-off-by: Username404 --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d1ada8e..40178de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,13 +135,13 @@ set(CPACK_VERBATIM_VARIABLES TRUE) string(TIMESTAMP TIME "%Y.%m+%d") set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}-${TIME}") set(CPACK_PACKAGE_VENDOR "Contributor(s)") -set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/resources/Yerbacon.png") +set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/resources/${PROJECT_NAME}.png") set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/misc/desc.txt") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${EXEDESC}") set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt") set(CPACK_PACKAGE_CONTACT "Username404 ") -set(CPACK_PACKAGE_INSTALL_DIRECTORY "Yerbacon ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}") +set(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME} ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}") set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${CMAKE_PROJECT_VERSION}-${TIME}") include_directories(${CMAKE_CURRENT_LIST_DIR}) @@ -235,7 +235,7 @@ elseif(MINGW OR MSVC) set(CPACK_NSIS_MANIFEST_DPI_AWARE TRUE) set(CPACK_NSIS_PACKAGE_NAME "${PROJECT_NAME} ${CODENAME}-${PROJECT_VERSION}") set(CPACK_NSIS_WELCOME_TITLE_3LINES ON) - set(CPACK_NSIS_URL_INFO_ABOUT "https://gits.username404.fr/Username404-59/Yerbacon") + set(CPACK_NSIS_URL_INFO_ABOUT "https://gits.username404.fr/Username404-59/${PROJECT_NAME}") set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/resources/${PROJECT_NAME}.ico") set(CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_SOURCE_DIR}/resources/${PROJECT_NAME}.ico") set(CPACK_NSIS_DEFINES "RequestExecutionLevel highest") @@ -245,7 +245,7 @@ elseif(MINGW OR MSVC) set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON) if (CMAKE_HOST_WIN32) # The two following variables require CMake 3.20 or higher - set(CPACK_NSIS_BRANDING_TEXT "NSIS Installer for the yerbacon compiler") + set(CPACK_NSIS_BRANDING_TEXT "NSIS Installer for ${PROJECT_NAME}") set(CPACK_NSIS_BRANDING_TEXT_TRIM_POSITION CENTER) endif() # CMake 3.22+ is required to ignore the NSIS license page From 97fa5fbb27df5086d5e13b9b1fc3309d65b21e49 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 3 Jul 2022 01:02:18 +0200 Subject: [PATCH 198/254] main.cpp: Simplify the condition used for text or files arguments Signed-off-by: Username404 --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 9efd448..29e77c1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -38,7 +38,7 @@ int main(int argc, char* argv[]) { } else goto invalid_argument; } else if (currentArgument == ArgumentShort("text")) { text_provided = true; printResult = true; } - else if ((currentArgument.ends_with(".ybcon") && !text_provided) || text_provided) + else if (text_provided || currentArgument.ends_with(".ybcon")) Units.insert_or_assign(currentArgument, async(not parallel ? launch::deferred : launch::async, [currentArgument, &text_provided, &target, &newLines]() { unit_result resultingPair; try { From 2ebb1d5239300b408fedc437a2c8616ed9a5d43a Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 3 Jul 2022 01:14:49 +0200 Subject: [PATCH 199/254] main.cpp: Shorten the assignment of printResult and text_provided Signed-off-by: Username404 --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 29e77c1..a96e7e9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -37,7 +37,7 @@ int main(int argc, char* argv[]) { newLines = true; } else goto invalid_argument; } - else if (currentArgument == ArgumentShort("text")) { text_provided = true; printResult = true; } + else if (currentArgument == ArgumentShort("text")) printResult = text_provided = true; else if (text_provided || currentArgument.ends_with(".ybcon")) Units.insert_or_assign(currentArgument, async(not parallel ? launch::deferred : launch::async, [currentArgument, &text_provided, &target, &newLines]() { unit_result resultingPair; From 4e08c0cf05490d79274c6511d3165468b74aea4a Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 6 Jul 2022 15:35:16 +0200 Subject: [PATCH 200/254] Implement reserved identifiers Signed-off-by: Username404 --- CMakeLists.txt | 2 +- src/headers/parsing/ParseComponents.hpp | 29 ++-- src/headers/parsing/Parser.hpp | 151 ++++++++++---------- src/headers/parsing/ReservedIdentifiers.hpp | 25 ++++ src/headers/transpiler/Target.hpp | 3 +- 5 files changed, 123 insertions(+), 87 deletions(-) create mode 100644 src/headers/parsing/ReservedIdentifiers.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 40178de..9898617 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -145,7 +145,7 @@ set(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME} ${CMAKE_PROJECT_VERSION_MAJ set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${CMAKE_PROJECT_VERSION}-${TIME}") include_directories(${CMAKE_CURRENT_LIST_DIR}) -add_executable(${EXENAME} src/main.cpp ${CMAKE_CURRENT_BINARY_DIR}/processed/${PROJECT_NAME}.rc src/etc/filefuncs.cpp src/etc/lexer.cpp src/headers/lex.hpp src/headers/misc.hpp src/headers/parsing/ParseComponents.hpp src/headers/transpiler/Target.hpp src/headers/transpiler/implementations/Lua.hpp src/headers/transpiler/implementations/Js.hpp src/headers/transpiler/implementations/Py.hpp src/headers/parsing/Parser.hpp src/headers/arguments.hpp) +add_executable(${EXENAME} src/main.cpp ${CMAKE_CURRENT_BINARY_DIR}/processed/${PROJECT_NAME}.rc src/etc/filefuncs.cpp src/etc/lexer.cpp src/headers/lex.hpp src/headers/misc.hpp src/headers/parsing/ParseComponents.hpp src/headers/transpiler/Target.hpp src/headers/transpiler/implementations/Lua.hpp src/headers/transpiler/implementations/Js.hpp src/headers/transpiler/implementations/Py.hpp src/headers/parsing/Parser.hpp src/headers/arguments.hpp src/headers/parsing/ReservedIdentifiers.hpp) target_compile_definitions(${EXENAME} PRIVATE YBCON_VERSION="${CODENAME} ${PROJECT_VERSION}") target_precompile_headers(${EXENAME} PRIVATE src/headers/Yerbacon.hpp) if (Threads_FOUND) diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index 603052a..3919b82 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -9,6 +9,7 @@ #include #include #include +#include "ReservedIdentifiers.hpp" using namespace std; #include "../lex.hpp" @@ -19,16 +20,22 @@ struct ParseComponent { [[nodiscard]] inline const type_info& getId() const { return typeid(*this); } virtual ~ParseComponent() = default; }; - +template struct NamedIdentifier: virtual ParseComponent { + struct identifier_reserved_exception: exception {}; const string name; - explicit NamedIdentifier(string_view nameText): name(nameText) {} - NamedIdentifier() = default; + explicit NamedIdentifier(const string_view nameText): name(nameText) { + if (disallow_reserved and reserved(name)) { + throw identifier_reserved_exception(); + } + } + NamedIdentifier() = delete; }; typedef unique_ptr component_ptr; #define IS_PARSECOMPONENT IS(ParseComponent) +#define IS_IDENTIFIER enable_if_t, T> or is_base_of_v, T>, T> class ParseTree: public virtual ParseComponent { mutable vector subComponents; using array_type = decltype(subComponents); @@ -68,8 +75,8 @@ public: }); return filteredComponents; } - IS(NamedIdentifier) - optional> findReferenceByName(const string& name) const { + template + optional> findReferenceByName(const string& name) const { const vector identifiers = findById(); for (T* identifier: identifiers) { if (identifier->getId() == typeid(T) && identifier->name == name) { @@ -80,8 +87,8 @@ public: }; inline component_ptr& operator[](const unsigned int& index) const { return subComponents[index]; } inline component_ptr& at(const unsigned int& index) const { return subComponents.at(index); } - IS(NamedIdentifier) - inline auto operator[](const string& key) const { return findReferenceByName(key); } + template + inline auto operator[](const string& key) const { return findReferenceByName(key); } IS_PARSECOMPONENT inline void add(const T& component) { addComponent(component); } IS_PARSECOMPONENT inline void addAll(const initializer_list& components) { addAllComponents(components); } IS_PARSECOMPONENT inline ParseTree& operator<<(const T& component) { add(component); return *this; } @@ -96,14 +103,14 @@ public: #undef IS_PARSECOMPONENT namespace StandardComponents { - struct Define: NamedIdentifier { + struct Define: NamedIdentifier { const bool final; ParseTree content; explicit Define(const bool& isFinal, string_view nameText, ParseTree&& content): NamedIdentifier(nameText), final(isFinal), content(move(content)) {} explicit Define(string_view nameText, ParseTree&& content): Define(false, nameText, move(content)) {} Define(Define&& define) noexcept: Define(define.final, define.name, move(define.content)) {} }; - struct Reference: NamedIdentifier { + struct Reference: NamedIdentifier { using NamedIdentifier::NamedIdentifier; }; namespace types { @@ -122,11 +129,11 @@ namespace StandardComponents { using Reference::Reference; }; - struct Function: NamedIdentifier, ParseTree { + struct Function: NamedIdentifier, ParseTree { ParseTree parameters; using NamedIdentifier::NamedIdentifier; }; - struct Class: NamedIdentifier, ParseTree { + struct Class: NamedIdentifier, ParseTree { using NamedIdentifier::NamedIdentifier; }; } diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 1d7f58c..86f45a1 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -8,6 +8,7 @@ #include #include #include +#include "ReservedIdentifiers.hpp" namespace Parser { typedef Yerbacon::Exception ParsingException; @@ -58,92 +59,94 @@ namespace Parser { const bool hasNext = (i + 1) < lexed.size(); const tok& current = lexed[i], next = hasNext ? lexed[i + 1] : tok(UNEXPECTED, current.line); - switch (current.toktype) { - case NUMBER: { - long double v = stoul(current.toktext); - if (i != 0 && lexed[i - 1].toktype == HYPHEN) v = -v; - types::Integer::precision_type p = 0; - if (nextAre({DOT, NUMBER})) { - i += 2; - const string& right = lexed[i].toktext; - p = min(static_cast(right.size()), numeric_limits::digits10); - v += copysign(stold(right.substr(0, p)) / powl(deca::num, p), v); - } - parseTree << types::Integer(v, p); - break; - } - case STRING: parseTree << current.toktext; break; - case IDENTIFIER: { - if (current.toktext == "class" || current.toktext == "structure") { - if (next.toktype == IDENTIFIER) { - parseTree << Class(next.toktext); ++i; - } else { - parsingError(next, hasNext ? " is not a valid class identifier" : "A class identifier is required", hasNext); - } - } else { - unsigned int parametersDistance = 0; - if (next.toktype == LPAR) { - const auto closing = find_if(lexed.begin() + i, lexed.end(), [](const tok& token){ return token.toktype == RPAR; }); - parametersDistance = distance(lexed.begin() + i, closing); - i += parametersDistance; - } - if (nextAre({LCOMP, LCOMP, LBRACE})) { - Function function(current.toktext); - if (parametersDistance > 2) - function.parameters = parse(filter_comma_list(lexed.begin() + ((i + 2) - parametersDistance), lexed.begin() + i)); - parseTree << function; + try { + switch (current.toktype) { + case NUMBER: { + long double v = stoul(current.toktext); + if (i != 0 && lexed[i - 1].toktype == HYPHEN) v = -v; + types::Integer::precision_type p = 0; + if (nextAre({DOT, NUMBER})) { i += 2; - break; - } else i -= parametersDistance; + const string& right = lexed[i].toktext; + p = min(static_cast(right.size()), numeric_limits::digits10); + v += copysign(stold(right.substr(0, p)) / powl(deca::num, p), v); + } + parseTree << types::Integer(v, p); + break; + } + case STRING: parseTree << current.toktext; break; + case IDENTIFIER: { + using enum ReservedIdentifier; + if (current.toktext == ID(CLASS) || current.toktext == ID(STRUCT)) { + if (next.toktype == IDENTIFIER) { + parseTree << Class(next.toktext); ++i; + } else { + parsingError(next, hasNext ? " is not a valid class identifier" : "A class identifier is required", hasNext); + } + } else { + unsigned int parametersDistance = 0; + if (next.toktype == LPAR) { + const auto closing = find_if(lexed.begin() + i, lexed.end(), [](const tok& token){ return token.toktype == RPAR; }); + parametersDistance = distance(lexed.begin() + i, closing); + i += parametersDistance; + } + if (nextAre({LCOMP, LCOMP, LBRACE})) { + Function function(current.toktext); + if (parametersDistance > 2) + function.parameters = parse(filter_comma_list(lexed.begin() + ((i + 2) - parametersDistance), lexed.begin() + i)); + parseTree << function; + i += 2; + break; + } else i -= parametersDistance; - bool isFinalDefine = nextAre({TAG, DEFINE}); - if (isFinalDefine || next.toktype == DEFINE) { - const optional previousDefinition = parseTree.template findReferenceByName(current.toktext); - if (previousDefinition.has_value() && (previousDefinition.value().get().final || isFinalDefine)) - parsingError(current, previousDefinition->get().final ? " cannot be redefined as it is final" : " cannot be made final after it has been declared", true); - const unsigned increment = 2 + isFinalDefine; - const auto beginning = lexed.begin() + i + increment; - const auto end = find_if(beginning, lexed.end(), [¤t](const tok& it){ - return it.toktype == SEMICOLON || it.line != current.line; - }); - parseTree << Define(isFinalDefine, current.toktext, parse(beginning, end)); - i += 1 + isFinalDefine + distance(beginning, end); - } else if (next.toktype == LPAR) { - parseTree << Call(current.toktext); - } else - parseTree << Reference(current.toktext); + bool isFinalDefine = nextAre({TAG, DEFINE}); + if (isFinalDefine || next.toktype == DEFINE) { + const optional previousDefinition = parseTree.template findReferenceByName(current.toktext); + if (previousDefinition.has_value() && (previousDefinition.value().get().final || isFinalDefine)) + parsingError(current, previousDefinition->get().final ? " cannot be redefined as it is final" : " cannot be made final after it has been declared", true); + const unsigned increment = 2 + isFinalDefine; + const auto beginning = lexed.begin() + i + increment; + const auto end = find_if(beginning, lexed.end(), [¤t](const tok& it){ + return it.toktype == SEMICOLON || it.line != current.line; + }); + parseTree << Define(isFinalDefine, current.toktext, parse(beginning, end)); + i += 1 + isFinalDefine + distance(beginning, end); + } else if (next.toktype == LPAR) { + parseTree << Call(current.toktext); + } else parseTree << Reference(current.toktext); } } - case SEMICOLON: break; - case LPAR: case LBRACE: case LBRACKET: { - const auto closingCharacter = find_corresponding(lexed.begin() + i + 1, lexed.end(), current.toktype, tok::inverseLCharacter(current.toktype)); - vector subTokens(lexed.begin() + i + 1, closingCharacter); - if (current.toktype == LPAR || current.toktype == LBRACKET) filter_comma_list(subTokens); - if (not parseTree.empty()) { - try { - auto& previous = dynamic_cast(*parseTree.at(parseTree.size() - 1)); - if (find_if(reverse_iterator(lexed.begin() + i), lexed.rend(), [](const tok& token){ - return token.toktype != SEMICOLON; - })->toktype != *closingCharacter) { - previous = parse(subTokens); - i = distance(lexed.begin(), closingCharacter); - break; - } - } catch (const out_of_range&) {} catch (const bad_cast&) {} + case SEMICOLON: break; + case LPAR: case LBRACE: case LBRACKET: { + const auto closingCharacter = find_corresponding(lexed.begin() + i + 1, lexed.end(), current.toktype, tok::inverseLCharacter(current.toktype)); + vector subTokens(lexed.begin() + i + 1, closingCharacter); + if (current.toktype == LPAR || current.toktype == LBRACKET) filter_comma_list(subTokens); + if (not parseTree.empty()) { + try { + auto& previous = dynamic_cast(*parseTree.at(parseTree.size() - 1)); + if (find_if(reverse_iterator(lexed.begin() + i), lexed.rend(), [](const tok& token){ + return token.toktype != SEMICOLON; + })->toktype != *closingCharacter) { + previous = parse(subTokens); + i = distance(lexed.begin(), closingCharacter); + break; + } + } catch (const out_of_range&) {} catch (const bad_cast&) {} + } } + default: parsingError(current, " \u27F5 Unexpected character", true); } - default: parsingError(current, " \u27F5 Unexpected character", true); + } catch (const NamedIdentifier::identifier_reserved_exception&) { + parsingError(current, " is a reserved identifier", true); } try { const auto& last = parseTree.cend() - 1; const type_info& lastId = last->get()->getId(); - const auto& last_identifier = dynamic_cast(**last); - if (lastId != typeid(Reference) && - lastId != typeid(Call) && - lastId != typeid(Define) and + const auto& last_identifier = dynamic_cast&>(**last); + if (lastId != typeid(Define) and any_of(parseTree.cbegin(), last, [&last_identifier](const component_ptr& pointer){ try { - return dynamic_cast(*pointer).name == last_identifier.name; + return dynamic_cast&>(*pointer).name == last_identifier.name; } catch (const bad_cast&) { return false; } diff --git a/src/headers/parsing/ReservedIdentifiers.hpp b/src/headers/parsing/ReservedIdentifiers.hpp new file mode 100644 index 0000000..0801838 --- /dev/null +++ b/src/headers/parsing/ReservedIdentifiers.hpp @@ -0,0 +1,25 @@ +#ifndef YERBACON_RESERVEDIDENTIFIERS_HPP +#define YERBACON_RESERVEDIDENTIFIERS_HPP + +#include +#include +#include "../Yerbacon.hpp" +#include + +static const array identifiers { + "class", "structure", "print", "print_line" +}; + +enum class ReservedIdentifier: size_t { + CLASS, STRUCT, PRINT_FUNCTION, PRINT_LINE_FUNCTION +}; + +inline const char* ID(const ReservedIdentifier& identifier) { + return identifiers.at(reinterpret_cast(identifier)); +} + +bool reserved(const string_view words) { + return find(identifiers.cbegin(), identifiers.cend(), words) != identifiers.cend(); +} + +#endif //YERBACON_RESERVEDIDENTIFIERS_HPP diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 9e84a84..434a341 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -132,7 +132,8 @@ public: make_task(StandardComponents::Reference, output << parseComponent.name;), make_task(StandardComponents::Call, const auto print_functions = printFunctions(); - output << ((parseComponent.name == "print") ? print_functions.first : (parseComponent.name == "print_line") ? print_functions.second : parseComponent.name) << '('; + using enum ReservedIdentifier; + output << ((parseComponent.name == ID(PRINT_FUNCTION)) ? print_functions.first : (parseComponent.name == ID(PRINT_LINE_FUNCTION)) ? print_functions.second : parseComponent.name) << '('; separate_transpileTree(parseComponent, ", "); output << ')'; ), From 22d159923760d76fd06cce81974f1754abb06152 Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 7 Jul 2022 17:21:59 +0200 Subject: [PATCH 201/254] Add a GodotScript target Signed-off-by: Username404 --- src/headers/transpiler/Target.hpp | 2 ++ .../implementations/GodotScript.hpp | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/headers/transpiler/implementations/GodotScript.hpp diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 434a341..859aa19 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -156,12 +156,14 @@ public: #include "implementations/Lua.hpp" #include "implementations/Js.hpp" #include "implementations/Py.hpp" +#include "implementations/GodotScript.hpp" unique_ptr Target::forName(string_view name, const bool newLines = true) { #define ADDTARGET(X, target_class) if (name == X) return unique_ptr(new target_class(newLines)) ADDTARGET("lua", LuaTarget); ADDTARGET("js", JsTarget); ADDTARGET("py", PyTarget); + ADDTARGET("gd", GsTarget); #undef ADDTARGET #undef make_nonlocal_task #undef make_task_noR diff --git a/src/headers/transpiler/implementations/GodotScript.hpp b/src/headers/transpiler/implementations/GodotScript.hpp new file mode 100644 index 0000000..d658f71 --- /dev/null +++ b/src/headers/transpiler/implementations/GodotScript.hpp @@ -0,0 +1,25 @@ +#ifndef GODOTSCRIPT_HPP +#define GODOTSCRIPT_HPP + +struct GsTarget: Target { + print_functions_pair printFunctions() final { return make_pair("printraw", "print"); } + unordered_task_map getTaskMap() final { + return { + make_task(Define, + output << (parseComponent.final ? "const " : "var ") << parseComponent.name << " = "; + transpileTree(parseComponent.content); + ), + make_task(types::String, stringInterpolation(R"(""")", parseComponent.content);), + make_task(Function, + output << "func " << parseComponent.name << '('; + separate_transpileTree(parseComponent.parameters, ", "); + output << "):" << separator << indentation; + if (parseComponent.empty()) output << "pass"; + separate_transpileTree(parseComponent, 1); + ) + }; + } + using Target::Target; +}; + +#endif \ No newline at end of file From ac4df6d09088c09b7ce2a3205a8e1051a83e5d7e Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 7 Jul 2022 17:22:41 +0200 Subject: [PATCH 202/254] Update README.md Signed-off-by: Username404 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4d46185..80c13ef 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Yerbacon logo -### ► A language that transpiles into lua, javascript (ES6) or python code. +### ► A language that transpiles into another programming language, like Lua, JavaScript (ES6) or Python. ``` main >> { print_line("Hello, World!") From bd48d270bec64b5011a604f17c0a02887cf7a2b3 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 8 Jul 2022 11:06:16 +0200 Subject: [PATCH 203/254] Parser.hpp: Make sure the T typename propagates to the function call in the parse overload Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 86f45a1..1f1788e 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -157,7 +157,7 @@ namespace Parser { return parseTree; } template T> - inline T parse(const input_iterator auto& begin, const input_iterator auto& end) { return parse(span(begin, end)); } + inline T parse(const input_iterator auto& begin, const input_iterator auto& end) { return parse(span(begin, end)); } } #endif //YERBACON_PARSER_HPP \ No newline at end of file From 4fa72c045963ad63b2d9040361d8d85f223abe9c Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 16 Jul 2022 12:36:39 +0200 Subject: [PATCH 204/254] Parser.hpp: Parse properties and methods Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 1f1788e..e953378 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -26,7 +26,9 @@ namespace Parser { const auto nextIterator = iterator + 1; if (nextIterator->toktype == tok::COMMA) { tokens.erase(nextIterator); - } else throw ParsingException("Missing comma after \"" + iterator->toktext + '"'); + } else if (nextIterator->toktype != tok::DOT && iterator->toktype != tok::DOT) { + throw ParsingException("Missing comma after \"" + iterator->toktext + '"'); + } } } } @@ -111,9 +113,17 @@ namespace Parser { }); parseTree << Define(isFinalDefine, current.toktext, parse(beginning, end)); i += 1 + isFinalDefine + distance(beginning, end); - } else if (next.toktype == LPAR) { - parseTree << Call(current.toktext); - } else parseTree << Reference(current.toktext); + } else { + const bool method = nextAre({DOT, IDENTIFIER, LPAR}); + const bool property = not method && nextAre({DOT, IDENTIFIER}); + const string name = property or method ? current.toktext + '.' + lexed[i + 2].toktext : current.toktext; + if (method or next.toktype == LPAR) { + parseTree << Call(name); + } else if (property) { + parseTree << Reference(name); + } + if (property or method) i += 2; + } } } case SEMICOLON: break; From 3ca51f450f767583c98c251f6d602d8b1fc9713c Mon Sep 17 00:00:00 2001 From: Username404 Date: Mon, 25 Jul 2022 12:33:00 +0200 Subject: [PATCH 205/254] CMakeLists.txt: Make sure MINIMAL_RUNTIME is set to 0 when emscripten is in use Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9898617..837d838 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,7 +61,7 @@ if (${IS_GNU} OR ${IS_CLANG}) if (NOT DEFINED EMSCRIPTEN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong -fstack-clash-protection") else() - set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 -sSTRICT=1 ${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 -sSTRICT=1 -sMINIMAL_RUNTIME=0 ${CMAKE_EXE_LINKER_FLAGS}") if (CMAKE_USE_PTHREADS_INIT) set(CMAKE_CXX_FLAGS "-pthread ${CMAKE_CXX_FLAGS}") # Emscripten requires the -pthread flag set(CMAKE_EXE_LINKER_FLAGS "--closure-args=\"--compilation_level SIMPLE\" -sPROXY_TO_PTHREAD=1 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706 From b648a8baba65b721916623024162b639364f1c42 Mon Sep 17 00:00:00 2001 From: Username404 Date: Mon, 25 Jul 2022 12:33:54 +0200 Subject: [PATCH 206/254] CMakeLists.txt: Make sure exceptions are enabled when emscripten is in use Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 837d838..254447b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,7 +61,7 @@ if (${IS_GNU} OR ${IS_CLANG}) if (NOT DEFINED EMSCRIPTEN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong -fstack-clash-protection") else() - set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 -sSTRICT=1 -sMINIMAL_RUNTIME=0 ${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 -sSTRICT=1 -sMINIMAL_RUNTIME=0 -sDISABLE_EXCEPTION_CATCHING=0 ${CMAKE_EXE_LINKER_FLAGS}") if (CMAKE_USE_PTHREADS_INIT) set(CMAKE_CXX_FLAGS "-pthread ${CMAKE_CXX_FLAGS}") # Emscripten requires the -pthread flag set(CMAKE_EXE_LINKER_FLAGS "--closure-args=\"--compilation_level SIMPLE\" -sPROXY_TO_PTHREAD=1 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706 From 2104f6e804b89378d1f703fc0dc20b3018c8b09a Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 29 Jul 2022 10:22:29 +0000 Subject: [PATCH 207/254] CMakeLists.txt: Fix the SELF_PACKER_FOR_EXECUTABLE check --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 254447b..6936fd2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -158,7 +158,7 @@ if (NOT (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDeb if (SELF_PACKER_FOR_EXECUTABLE MATCHES upx) set(SELF_PACKER_FOR_EXECUTABLE_FLAGS ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} --ultra-brute --best) endif() - if (NOT SELF_PACKER_FOR_EXECUTABLE EQUAL "") + if (NOT SELF_PACKER_FOR_EXECUTABLE STREQUAL "SELF_PACKER_FOR_EXECUTABLE-NOTFOUND") add_custom_command(TARGET ${EXENAME} POST_BUILD COMMAND "${SELF_PACKER_FOR_EXECUTABLE}" ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} $ VERBATIM) endif() endif() From 7b28ff50b80f0908bf2393b9d8740888690988c5 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 29 Jul 2022 10:40:47 +0000 Subject: [PATCH 208/254] CMakeLists.txt: Use strings when doing STREQUAL comparisons, and compare variables instead of their content for IS_GNU and IS_CLANG --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6936fd2..7bac623 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,8 +34,8 @@ set(MINIMAL_GNU "11.0") set(MINIMAL_CLANG "14.0.1") set(MINIMAL_MSVC "19.30") option(IGNORE_MINIMAL_COMPILER_VERSION "Whether or not to ignore the minimal compiler versions") -set(IS_GNU (${CMAKE_CXX_COMPILER_ID} STREQUAL GNU)) -set(IS_CLANG (${CMAKE_CXX_COMPILER_ID} STREQUAL Clang)) +set(IS_GNU (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")) +set(IS_CLANG (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) option(NO_CCACHE "Disables CCache") if (NOT NO_CCACHE) @@ -111,7 +111,7 @@ elseif(MSVC) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") endif() string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPERCASE_BUILD_TYPE) -if (UPPERCASE_BUILD_TYPE STREQUAL RELEASE) +if (UPPERCASE_BUILD_TYPE STREQUAL "RELEASE") add_definitions(-DYBCON_FLAGS="${CMAKE_CXX_FLAGS_RELEASE}") endif() add_definitions(-DYBCON_COMPILER="${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") @@ -153,7 +153,7 @@ if (Threads_FOUND) endif() option(NO_SELF_PACKER "Disables usage of a self-packer") -if (NOT (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo OR NO_SELF_PACKER OR DEFINED EMSCRIPTEN OR MINGW)) +if (NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" OR NO_SELF_PACKER OR DEFINED EMSCRIPTEN OR MINGW)) include(FindSelfPackers) if (SELF_PACKER_FOR_EXECUTABLE MATCHES upx) set(SELF_PACKER_FOR_EXECUTABLE_FLAGS ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} --ultra-brute --best) From 70326958676327d320a61a037485518f28f239e0 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 29 Jul 2022 10:47:07 +0000 Subject: [PATCH 209/254] CMakeLists.txt: Always use the uppercase build type for comparisons --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7bac623..affc07d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,7 +153,7 @@ if (Threads_FOUND) endif() option(NO_SELF_PACKER "Disables usage of a self-packer") -if (NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" OR NO_SELF_PACKER OR DEFINED EMSCRIPTEN OR MINGW)) +if (NOT (UPPERCASE_BUILD_TYPE STREQUAL "DEBUG" OR UPPERCASE_BUILD_TYPE STREQUAL "RELWITHDEBINFO" OR NO_SELF_PACKER OR DEFINED EMSCRIPTEN OR MINGW)) include(FindSelfPackers) if (SELF_PACKER_FOR_EXECUTABLE MATCHES upx) set(SELF_PACKER_FOR_EXECUTABLE_FLAGS ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} --ultra-brute --best) From a21eecb0b3f06feeb152c99f52918e3e0c8cc0d8 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 30 Jul 2022 00:01:04 +0200 Subject: [PATCH 210/254] CMakeLists.txt: Fix two indentation errors Signed-off-by: Username404 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index affc07d..f2690d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,7 +87,7 @@ if (${IS_GNU}) if (Threads_FOUND) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ftree-parallelize-loops=2") endif() - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvect-cost-model=unlimited -foptimize-strlen -fsched-pressure -flive-range-shrinkage -fpredictive-commoning -ftree-partial-pre -fzero-call-used-regs=used-gpr-arg -fira-loop-pressure -ftree-loop-distribution -floop-interchange -fsplit-paths -fgcse-las -fgcse-sm -fipa-pta -fstdarg-opt -fivopts -fweb") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvect-cost-model=unlimited -foptimize-strlen -fsched-pressure -flive-range-shrinkage -fpredictive-commoning -ftree-partial-pre -fzero-call-used-regs=used-gpr-arg -fira-loop-pressure -ftree-loop-distribution -floop-interchange -fsplit-paths -fgcse-las -fgcse-sm -fipa-pta -fstdarg-opt -fivopts -fweb") if (${CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE}) set(CMAKE_CXX_FLAGS_RELEASE "-fwhole-program -flto-partition=none ${CMAKE_CXX_FLAGS_RELEASE}") endif() @@ -172,7 +172,7 @@ if (UNIX AND NOT (MINGW OR CMAKE_HOST_WIN32)) set(CPACK_PACKAGE_FILE_NAME "${PNAME}_lpkg") set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/postinst" "processed/postinst" @ONLY) - set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_BINARY_DIR}/processed/postinst") + set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_BINARY_DIR}/processed/postinst") set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA ${CPACK_RPM_POST_INSTALL_SCRIPT_FILE}) set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) set(CPACK_DEBIAN_COMPRESSION_TYPE xz) From da3af239c92f79fc4711817c696b2180f4dbdfa9 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 2 Aug 2022 18:36:14 +0200 Subject: [PATCH 211/254] CMakeLists.txt: Add a note about UPX Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f2690d6..cd3873e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,7 +155,7 @@ endif() option(NO_SELF_PACKER "Disables usage of a self-packer") if (NOT (UPPERCASE_BUILD_TYPE STREQUAL "DEBUG" OR UPPERCASE_BUILD_TYPE STREQUAL "RELWITHDEBINFO" OR NO_SELF_PACKER OR DEFINED EMSCRIPTEN OR MINGW)) include(FindSelfPackers) - if (SELF_PACKER_FOR_EXECUTABLE MATCHES upx) + if (SELF_PACKER_FOR_EXECUTABLE MATCHES upx) # UPX version d61edc9 or higher is required when using a cross-compiler to target the musl C library set(SELF_PACKER_FOR_EXECUTABLE_FLAGS ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} --ultra-brute --best) endif() if (NOT SELF_PACKER_FOR_EXECUTABLE STREQUAL "SELF_PACKER_FOR_EXECUTABLE-NOTFOUND") From 44d4ffb2ee74bc23a2def8a9bb97ee3378f915e3 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 2 Aug 2022 19:53:14 +0200 Subject: [PATCH 212/254] CMakeLists.txt: Always strip executables when the build type is release Signed-off-by: Username404 --- CMakeLists.txt | 2 +- Jenkinsfile | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cd3873e..9a647c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,7 +68,7 @@ if (${IS_GNU} OR ${IS_CLANG}) endif() endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstrict-enums -pipe -funwind-tables -fasynchronous-unwind-tables -frtti -fexceptions") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections -fmerge-all-constants -ftree-vectorize -fno-math-errno") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections -fmerge-all-constants -ftree-vectorize -fno-math-errno -s") include(CheckCXXCompilerFlag) set(CF_PROTECTION "-fcf-protection") check_cxx_compiler_flag("${CF_PROTECTION}" CF_PROTECTION_SUPPORTED) diff --git a/Jenkinsfile b/Jenkinsfile index c2b219f..0ef62f7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -5,7 +5,6 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch final String packageArch = isPackageArchDeb ? debArch : rpmArch; final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' final String linker = "/usr/bin/${path}-ld" - final String strip = "/usr/bin/${path}-strip" final String build_directory = "cmake-build-${packageArch}${suffix}" final boolean upx_exists = fileExists('/usr/bin/upx') final boolean is_riscv = path.contains('riscv') @@ -14,9 +13,6 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DNO_SELF_PACKER=ON -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", generator: cmake_generator() cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' - if (fileExists(strip)) { - sh "$strip -s ./$build_directory/ybcon*" - } cpack installation: 'Latest', workingDir: build_directory } From 62fa2451963acaaabe6d2db79316adde241d337c Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 2 Aug 2022 19:58:49 +0200 Subject: [PATCH 213/254] Jenkinsfile: Remove the upx_exists variable (which has been useless since commit 219fb02a) Signed-off-by: Username404 --- Jenkinsfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 0ef62f7..b218200 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -6,7 +6,6 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' final String linker = "/usr/bin/${path}-ld" final String build_directory = "cmake-build-${packageArch}${suffix}" - final boolean upx_exists = fileExists('/usr/bin/upx') final boolean is_riscv = path.contains('riscv') // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', From ae8dc4295005ccdb29ef845d2fa315e27da960ca Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 2 Aug 2022 20:04:46 +0200 Subject: [PATCH 214/254] Jenkinsfile: Enable UPX since it now works with stripped executables targeting the musl C library Signed-off-by: Username404 --- Jenkinsfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index b218200..ec099d2 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -9,7 +9,7 @@ def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch final boolean is_riscv = path.contains('riscv') // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DNO_SELF_PACKER=ON -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", + cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DNO_SELF_PACKER=${!is_riscv ? "OFF" : "ON"} -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", generator: cmake_generator() cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' cpack installation: 'Latest', workingDir: build_directory @@ -28,6 +28,7 @@ final String windowsSuffix = '-windows' - MinGW32 G++/Clang (https://github.com/mstorsjo/llvm-mingw) for x86_64, i686, armhf and aarch64, (unzip the content of the folder in the tar.xz file) in /usr/, along with soft links from /usr/bin/ to the binaries Optional Tools: - Ninja + - UPX (d61edc9 or higher) */ pipeline { @@ -50,7 +51,7 @@ pipeline { buildTarget('x86_64-linux-musl', 'x86_64', 'amd64') buildTarget('i686-linux-musl', 'i386', 'i386') cmakeBuild buildDir: "cmake-build-release-emscripten", buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "-DCMAKE_TOOLCHAIN_FILE=\"/usr/share/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake\" ${no_compilation_cache_flags()}", + cmakeArgs: "-DCMAKE_TOOLCHAIN_FILE=\"/usr/share/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake\" ${no_compilation_cache_flags()} -DNO_SELF_PACKER=ON", generator: cmake_generator() cmake arguments: "--build ./cmake-build-release-emscripten", installation: 'Latest' } From f8010ea2b06c6bbad578c153edc0b6bd978370bc Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 3 Aug 2022 11:37:33 +0200 Subject: [PATCH 215/254] CMakeLists.txt: Pass "-s" to the linker instead of passing it to the compiler Signed-off-by: Username404 --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a647c5..1016fb4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,8 +67,9 @@ if (${IS_GNU} OR ${IS_CLANG}) set(CMAKE_EXE_LINKER_FLAGS "--closure-args=\"--compilation_level SIMPLE\" -sPROXY_TO_PTHREAD=1 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706 endif() endif() + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -s") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstrict-enums -pipe -funwind-tables -fasynchronous-unwind-tables -frtti -fexceptions") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections -fmerge-all-constants -ftree-vectorize -fno-math-errno -s") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections -fmerge-all-constants -ftree-vectorize -fno-math-errno") include(CheckCXXCompilerFlag) set(CF_PROTECTION "-fcf-protection") check_cxx_compiler_flag("${CF_PROTECTION}" CF_PROTECTION_SUPPORTED) From a9d460d0960926990fc6ffc2f4b9c0a9e880ced4 Mon Sep 17 00:00:00 2001 From: Username404 Date: Mon, 8 Aug 2022 11:22:30 +0200 Subject: [PATCH 216/254] CMakeLists.txt: Set CMAKE_COLOR_DIAGNOSTICS to ON Signed-off-by: Username404 --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1016fb4..94377d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ else() endif() set(CMAKE_CXX_FLAGS "-Wall") set(CMAKE_CXX_FLAGS_RELEASE "-Os") +set(CMAKE_COLOR_DIAGNOSTICS ON) set(MINIMAL_GNU "11.0") set(MINIMAL_CLANG "14.0.1") set(MINIMAL_MSVC "19.30") From efe7d8ca57637690578ccaa7893d3bd4bbee6ec4 Mon Sep 17 00:00:00 2001 From: Username404 Date: Mon, 8 Aug 2022 14:19:00 +0200 Subject: [PATCH 217/254] CMakeLists.txt: Disable PIE when using UPX since executables seem to crash on some systems when it is enabled Signed-off-by: Username404 --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 94377d9..5781bf8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -159,6 +159,8 @@ if (NOT (UPPERCASE_BUILD_TYPE STREQUAL "DEBUG" OR UPPERCASE_BUILD_TYPE STREQUAL include(FindSelfPackers) if (SELF_PACKER_FOR_EXECUTABLE MATCHES upx) # UPX version d61edc9 or higher is required when using a cross-compiler to target the musl C library set(SELF_PACKER_FOR_EXECUTABLE_FLAGS ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} --ultra-brute --best) + set(CMAKE_POSITION_INDEPENDENT_CODE FALSE) + set_target_properties(${EXENAME} PROPERTIES POSITION_INDEPENDENT_CODE ${CMAKE_POSITION_INDEPENDENT_CODE}) endif() if (NOT SELF_PACKER_FOR_EXECUTABLE STREQUAL "SELF_PACKER_FOR_EXECUTABLE-NOTFOUND") add_custom_command(TARGET ${EXENAME} POST_BUILD COMMAND "${SELF_PACKER_FOR_EXECUTABLE}" ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} $ VERBATIM) From 510e7a24f3a7560c8ecdd3e4fc42862e78e76cfe Mon Sep 17 00:00:00 2001 From: Username404 Date: Mon, 8 Aug 2022 12:26:34 +0200 Subject: [PATCH 218/254] CMakeLists.txt: Don't set CMAKE_POSITION_INDEPENDENT_CODE to TRUE if it is already defined Signed-off-by: Username404 --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5781bf8..1288473 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,9 @@ set(CMAKE_CXX_EXTENSIONS OFF) include(CheckPIESupported) check_pie_supported(LANGUAGES CXX) if (CMAKE_CXX_LINK_PIE_SUPPORTED) - set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) + if (NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE) + set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) + endif() else() message(NOTICE "Position-Independent Code (PIC) is not supported by the current toolchain") endif() From fec8a2c4bd22f03b87467af47e4841e39931101c Mon Sep 17 00:00:00 2001 From: Username404 Date: Mon, 8 Aug 2022 12:42:39 +0200 Subject: [PATCH 219/254] CMakeLists.txt: Notify the user when CMAKE_POSITION_INDEPENDENT_CODE was defined on the command line although UPX is in use Signed-off-by: Username404 --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1288473..ed8a818 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,8 +23,9 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) include(CheckPIESupported) check_pie_supported(LANGUAGES CXX) +set(USER_DEFINED_PIE (DEFINED CMAKE_POSITION_INDEPENDENT_CODE)) if (CMAKE_CXX_LINK_PIE_SUPPORTED) - if (NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE) + if (NOT USER_DEFINED_PIE) set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) endif() else() @@ -161,6 +162,9 @@ if (NOT (UPPERCASE_BUILD_TYPE STREQUAL "DEBUG" OR UPPERCASE_BUILD_TYPE STREQUAL include(FindSelfPackers) if (SELF_PACKER_FOR_EXECUTABLE MATCHES upx) # UPX version d61edc9 or higher is required when using a cross-compiler to target the musl C library set(SELF_PACKER_FOR_EXECUTABLE_FLAGS ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} --ultra-brute --best) + if (USER_DEFINED_PIE AND CMAKE_POSITION_INDEPENDENT_CODE) + message(NOTICE "-- Could NOT manually enable PIE (UPX is in use)") + endif() set(CMAKE_POSITION_INDEPENDENT_CODE FALSE) set_target_properties(${EXENAME} PROPERTIES POSITION_INDEPENDENT_CODE ${CMAKE_POSITION_INDEPENDENT_CODE}) endif() From 3e6b6f95606763ffef8e3b3476857aef33fdc917 Mon Sep 17 00:00:00 2001 From: Username404 Date: Mon, 8 Aug 2022 12:52:44 +0200 Subject: [PATCH 220/254] CMakeLists.txt: Notify the user about position-independent code being unsupported only when it has been manually enabled Signed-off-by: Username404 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ed8a818..3dd8a3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,8 +28,8 @@ if (CMAKE_CXX_LINK_PIE_SUPPORTED) if (NOT USER_DEFINED_PIE) set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) endif() -else() - message(NOTICE "Position-Independent Code (PIC) is not supported by the current toolchain") +elseif(USER_DEFINED_PIE AND CMAKE_POSITION_INDEPENDENT_CODE) + message(NOTICE "-- Could NOT manually enable Position-Independent Code (PIC) because it is not supported by the current toolchain") endif() set(CMAKE_CXX_FLAGS "-Wall") set(CMAKE_CXX_FLAGS_RELEASE "-Os") From b8bb1181d123c930e78d6e5b1db9d9a2c7244401 Mon Sep 17 00:00:00 2001 From: Username404 Date: Mon, 8 Aug 2022 13:15:58 +0200 Subject: [PATCH 221/254] CMakeLists.txt: Disable UPX when position-dependent executables are not supported by the compiler Signed-off-by: Username404 --- CMakeLists.txt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3dd8a3b..14d66cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -161,12 +161,17 @@ option(NO_SELF_PACKER "Disables usage of a self-packer") if (NOT (UPPERCASE_BUILD_TYPE STREQUAL "DEBUG" OR UPPERCASE_BUILD_TYPE STREQUAL "RELWITHDEBINFO" OR NO_SELF_PACKER OR DEFINED EMSCRIPTEN OR MINGW)) include(FindSelfPackers) if (SELF_PACKER_FOR_EXECUTABLE MATCHES upx) # UPX version d61edc9 or higher is required when using a cross-compiler to target the musl C library - set(SELF_PACKER_FOR_EXECUTABLE_FLAGS ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} --ultra-brute --best) - if (USER_DEFINED_PIE AND CMAKE_POSITION_INDEPENDENT_CODE) - message(NOTICE "-- Could NOT manually enable PIE (UPX is in use)") + if (CMAKE_CXX_LINK_NO_PIE_SUPPORTED) + set(SELF_PACKER_FOR_EXECUTABLE_FLAGS ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} --ultra-brute --best) + if (USER_DEFINED_PIE AND CMAKE_POSITION_INDEPENDENT_CODE) + message(NOTICE "-- Could NOT manually enable PIE (UPX is in use)") + endif() + set(CMAKE_POSITION_INDEPENDENT_CODE FALSE) + set_target_properties(${EXENAME} PROPERTIES POSITION_INDEPENDENT_CODE ${CMAKE_POSITION_INDEPENDENT_CODE}) + else() + set(SELF_PACKER_FOR_EXECUTABLE "SELF_PACKER_FOR_EXECUTABLE-NOTFOUND") + message(NOTICE "UPX usage has been disabled because position-dependent executables are unsupported by the current compiler") endif() - set(CMAKE_POSITION_INDEPENDENT_CODE FALSE) - set_target_properties(${EXENAME} PROPERTIES POSITION_INDEPENDENT_CODE ${CMAKE_POSITION_INDEPENDENT_CODE}) endif() if (NOT SELF_PACKER_FOR_EXECUTABLE STREQUAL "SELF_PACKER_FOR_EXECUTABLE-NOTFOUND") add_custom_command(TARGET ${EXENAME} POST_BUILD COMMAND "${SELF_PACKER_FOR_EXECUTABLE}" ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} $ VERBATIM) From a98cd3e534801f25b103d6bc829c0e090aa1cabf Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 9 Aug 2022 10:18:00 +0200 Subject: [PATCH 222/254] CMakeLists.txt: Set CMAKE_UNITY_BUILD to TRUE by default Signed-off-by: Username404 --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 14d66cf..b2740f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,9 @@ configure_file("resources/${PROJECT_NAME}.rc" "processed/${PROJECT_NAME}.rc" @ON set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +if (NOT DEFINED CMAKE_UNITY_BUILD) + set(CMAKE_UNITY_BUILD TRUE) +endif() include(CheckPIESupported) check_pie_supported(LANGUAGES CXX) set(USER_DEFINED_PIE (DEFINED CMAKE_POSITION_INDEPENDENT_CODE)) From c720769305289e82ebf98d991b21d83c1463f607 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 9 Aug 2022 12:12:41 +0200 Subject: [PATCH 223/254] Jenkinsfile: Catch errors from emscripten Signed-off-by: Username404 --- Jenkinsfile | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index ec099d2..57d058e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -50,10 +50,12 @@ pipeline { echo "Building the ${env.BRANCH_NAME} branch.." buildTarget('x86_64-linux-musl', 'x86_64', 'amd64') buildTarget('i686-linux-musl', 'i386', 'i386') - cmakeBuild buildDir: "cmake-build-release-emscripten", buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "-DCMAKE_TOOLCHAIN_FILE=\"/usr/share/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake\" ${no_compilation_cache_flags()} -DNO_SELF_PACKER=ON", - generator: cmake_generator() - cmake arguments: "--build ./cmake-build-release-emscripten", installation: 'Latest' + catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') { + cmakeBuild buildDir: "cmake-build-release-emscripten", buildType: 'release', cleanBuild: true, installation: 'Latest', + cmakeArgs: "-DCMAKE_TOOLCHAIN_FILE=\"/usr/share/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake\" ${no_compilation_cache_flags()} -DNO_SELF_PACKER=ON", + generator: cmake_generator() + cmake arguments: "--build ./cmake-build-release-emscripten", installation: 'Latest' + } } } stage('Build for other architectures') { From 4795bd54a099e0f51c00aefd221cde488e908e89 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 20 Aug 2022 13:24:05 +0200 Subject: [PATCH 224/254] Parser.hpp: Replace the try-catch statement at line 152 with a condition since this seems to fix bad_cast not being caught when running a windows executable which has been compressed using upx CMakeLists.txt: Revert the 89888113 commit and don't check CMAKE_CXX_LINK_NO_PIE_SUPPORTED when mingw is in use Signed-off-by: Username404 --- CMakeLists.txt | 4 ++-- src/headers/parsing/Parser.hpp | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b2740f7..2373699 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -161,10 +161,10 @@ if (Threads_FOUND) endif() option(NO_SELF_PACKER "Disables usage of a self-packer") -if (NOT (UPPERCASE_BUILD_TYPE STREQUAL "DEBUG" OR UPPERCASE_BUILD_TYPE STREQUAL "RELWITHDEBINFO" OR NO_SELF_PACKER OR DEFINED EMSCRIPTEN OR MINGW)) +if (NOT (UPPERCASE_BUILD_TYPE STREQUAL "DEBUG" OR UPPERCASE_BUILD_TYPE STREQUAL "RELWITHDEBINFO" OR NO_SELF_PACKER OR DEFINED EMSCRIPTEN)) include(FindSelfPackers) if (SELF_PACKER_FOR_EXECUTABLE MATCHES upx) # UPX version d61edc9 or higher is required when using a cross-compiler to target the musl C library - if (CMAKE_CXX_LINK_NO_PIE_SUPPORTED) + if (CMAKE_CXX_LINK_NO_PIE_SUPPORTED OR MINGW) # MINGW does not support PIE, yet the variable is set to NO. set(SELF_PACKER_FOR_EXECUTABLE_FLAGS ${SELF_PACKER_FOR_EXECUTABLE_FLAGS} --ultra-brute --best) if (USER_DEFINED_PIE AND CMAKE_POSITION_INDEPENDENT_CODE) message(NOTICE "-- Could NOT manually enable PIE (UPX is in use)") diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index e953378..5a9f23d 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -149,20 +149,20 @@ namespace Parser { } catch (const NamedIdentifier::identifier_reserved_exception&) { parsingError(current, " is a reserved identifier", true); } - try { - const auto& last = parseTree.cend() - 1; - const type_info& lastId = last->get()->getId(); - const auto& last_identifier = dynamic_cast&>(**last); + const auto& last = parseTree.cend() - 1; + const type_info& lastId = last->get()->getId(); + const auto& last_identifier = dynamic_cast*>(last->get()); + if (last_identifier != nullptr) { if (lastId != typeid(Define) and any_of(parseTree.cbegin(), last, [&last_identifier](const component_ptr& pointer){ try { - return dynamic_cast&>(*pointer).name == last_identifier.name; + return dynamic_cast&>(*pointer).name == last_identifier->name; } catch (const bad_cast&) { return false; } })) { parsingError(current, " has already been defined previously", true); } - } catch (const bad_cast&) {} + } } return parseTree; } From 8e74bff30bb30e815984b9f8525658b9e5bfae41 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 20 Aug 2022 13:45:27 +0200 Subject: [PATCH 225/254] Parser.hpp: Fix a tiny typo at line 154 Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 5a9f23d..7a7448b 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -151,7 +151,7 @@ namespace Parser { } const auto& last = parseTree.cend() - 1; const type_info& lastId = last->get()->getId(); - const auto& last_identifier = dynamic_cast*>(last->get()); + const auto* last_identifier = dynamic_cast*>(last->get()); if (last_identifier != nullptr) { if (lastId != typeid(Define) and any_of(parseTree.cbegin(), last, [&last_identifier](const component_ptr& pointer){ From 0fbe69ba917d6b1cbfd143bb9a308f71261f0074 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 23 Aug 2022 19:18:39 +0200 Subject: [PATCH 226/254] Don't reuse CMAKE_EXE_LINKER_FLAGS_RELEASE when setting it to "-s" Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2373699..cad0bdc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,7 +74,7 @@ if (${IS_GNU} OR ${IS_CLANG}) set(CMAKE_EXE_LINKER_FLAGS "--closure-args=\"--compilation_level SIMPLE\" -sPROXY_TO_PTHREAD=1 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706 endif() endif() - set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -s") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-s") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstrict-enums -pipe -funwind-tables -fasynchronous-unwind-tables -frtti -fexceptions") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections -fmerge-all-constants -ftree-vectorize -fno-math-errno") include(CheckCXXCompilerFlag) From 784663416505d0c7e51230b77010ce19680c38a4 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 24 Aug 2022 00:25:14 +0200 Subject: [PATCH 227/254] CMakeLists.txt: Remove PNAME + CXX_TARGET, set CPACK_PACKAGE_FILE_NAME only once and let rpmbuild and the CPack Deb generator decide what file name to use Jenkinsfile: Remove the buildTarget function's architecture-related parameters Signed-off-by: Username404 --- CMakeLists.txt | 15 ++++++--------- Jenkinsfile | 31 ++++++++++++++----------------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cad0bdc..5949f93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,9 @@ if (CMAKE_CXX_LINK_PIE_SUPPORTED) elseif(USER_DEFINED_PIE AND CMAKE_POSITION_INDEPENDENT_CODE) message(NOTICE "-- Could NOT manually enable Position-Independent Code (PIC) because it is not supported by the current toolchain") endif() +if (CMAKE_SYSTEM_PROCESSOR STREQUAL "") + set(CMAKE_SYSTEM_PROCESSOR "${CMAKE_HOST_SYSTEM_PROCESSOR}") +endif() set(CMAKE_CXX_FLAGS "-Wall") set(CMAKE_CXX_FLAGS_RELEASE "-Os") set(CMAKE_COLOR_DIAGNOSTICS ON) @@ -150,7 +153,7 @@ set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt") set(CPACK_PACKAGE_CONTACT "Username404 ") set(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME} ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}") -set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${CMAKE_PROJECT_VERSION}-${TIME}") +set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${CODENAME}-${TIME}_${CMAKE_SYSTEM_NAME}.${CMAKE_SYSTEM_PROCESSOR}") include_directories(${CMAKE_CURRENT_LIST_DIR}) add_executable(${EXENAME} src/main.cpp ${CMAKE_CURRENT_BINARY_DIR}/processed/${PROJECT_NAME}.rc src/etc/filefuncs.cpp src/etc/lexer.cpp src/headers/lex.hpp src/headers/misc.hpp src/headers/parsing/ParseComponents.hpp src/headers/transpiler/Target.hpp src/headers/transpiler/implementations/Lua.hpp src/headers/transpiler/implementations/Js.hpp src/headers/transpiler/implementations/Py.hpp src/headers/parsing/Parser.hpp src/headers/arguments.hpp src/headers/parsing/ReservedIdentifiers.hpp) @@ -181,21 +184,20 @@ if (NOT (UPPERCASE_BUILD_TYPE STREQUAL "DEBUG" OR UPPERCASE_BUILD_TYPE STREQUAL endif() endif() -# lpkg = linux package, wpkg = windows package -set(PNAME ${PROJECT_NAME}-${CODENAME}-${TIME}) if (UNIX AND NOT (MINGW OR CMAKE_HOST_WIN32)) include(GNUInstallDirs) set(CMAKE_INSTALL_PREFIX "/usr") set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") - set(CPACK_PACKAGE_FILE_NAME "${PNAME}_lpkg") set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/postinst" "processed/postinst" @ONLY) set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_BINARY_DIR}/processed/postinst") set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA ${CPACK_RPM_POST_INSTALL_SCRIPT_FILE}) set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) + set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT") set(CPACK_DEBIAN_COMPRESSION_TYPE xz) set(CPACK_RPM_COMPRESSION_TYPE ${CPACK_DEBIAN_COMPRESSION_TYPE}) set(CPACK_RPM_PACKAGE_AUTOREQ YES) + set(CPACK_RPM_FILE_NAME "RPM-DEFAULT") set(CPACK_RPM_PACKAGE_LICENSE "MPL-2.0") set(CPACK_RPM_CHANGELOG_FILE "${CMAKE_CURRENT_SOURCE_DIR}/changelog") if (CMAKE_VERSION STREQUAL "3.21.1") @@ -248,7 +250,6 @@ elseif(MINGW OR MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-command-line-argument") set(CMAKE_EXE_LINKER_FLAGS "-static -static-libstdc++ -static-libgcc ${CMAKE_EXE_LINKER_FLAGS}") endif() - set(CPACK_PACKAGE_FILE_NAME "${PNAME}_wpkg") set(CPACK_NSIS_COMPRESSOR "/SOLID lzma") set(CPACK_NSIS_MANIFEST_DPI_AWARE TRUE) set(CPACK_NSIS_PACKAGE_NAME "${PROJECT_NAME} ${CODENAME}-${PROJECT_VERSION}") @@ -271,8 +272,4 @@ elseif(MINGW OR MSVC) set(CPACK_GENERATOR ZIP;NSIS) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${EXENAME}.exe DESTINATION bin) endif() -if (NOT DEFINED CXX_TARGET) - set(CXX_TARGET ${CMAKE_HOST_SYSTEM_PROCESSOR}) -endif() -set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.${CXX_TARGET}") include(CPack) \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile index 57d058e..2d336f5 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,22 +1,19 @@ String cmake_generator() { return fileExists('/usr/bin/ninja') ? 'Ninja' : 'Unix Makefiles' } String no_compilation_cache_flags() { return '-DNO_CCACHE=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON' } -def buildTarget(String path, String rpmArch = 'noarch', String debArch = 'noarch', boolean isPackageArchDeb = true, String suffix = '') { - final String packageArch = isPackageArchDeb ? debArch : rpmArch; +def buildTarget(String path) { final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' final String linker = "/usr/bin/${path}-ld" - final String build_directory = "cmake-build-${packageArch}${suffix}" + final String build_directory = "cmake-build-${path}" final boolean is_riscv = path.contains('riscv') // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCXX_TARGET=${packageArch} -DCMAKE_EXE_LINKER_FLAGS=-static -DNO_SELF_PACKER=${!is_riscv ? "OFF" : "ON"} -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", + cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_SYSTEM_PROCESSOR=\"${path.substring(0, path.indexOf('-'))}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCMAKE_EXE_LINKER_FLAGS=-static -DNO_SELF_PACKER=${!is_riscv ? "OFF" : "ON"} -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", generator: cmake_generator() cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' cpack installation: 'Latest', workingDir: build_directory } -final String windowsSuffix = '-windows' - /* Required Plugins: - CMake - Sidebar Link @@ -48,8 +45,8 @@ pipeline { stage('Build') { steps { echo "Building the ${env.BRANCH_NAME} branch.." - buildTarget('x86_64-linux-musl', 'x86_64', 'amd64') - buildTarget('i686-linux-musl', 'i386', 'i386') + buildTarget('x86_64-linux-musl') + buildTarget('i686-linux-musl') catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') { cmakeBuild buildDir: "cmake-build-release-emscripten", buildType: 'release', cleanBuild: true, installation: 'Latest', cmakeArgs: "-DCMAKE_TOOLCHAIN_FILE=\"/usr/share/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake\" ${no_compilation_cache_flags()} -DNO_SELF_PACKER=ON", @@ -61,22 +58,22 @@ pipeline { stage('Build for other architectures') { steps { catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { - buildTarget('armel-linux-musleabi', 'armv4l', 'armel') - buildTarget('armv7l-linux-musleabihf', 'armv7hl', 'armhf') - buildTarget('aarch64-linux-musl', 'aarch64', 'arm64', false) - buildTarget('riscv64-linux-gnu', 'riscv64', 'riscv64') + buildTarget('armel-linux-musleabi') + buildTarget('armv7l-linux-musleabihf') + buildTarget('aarch64-linux-musl') + buildTarget('riscv64-linux-gnu') } } } stage('Build for other platforms') { steps { catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') { - buildTarget('armv7-w64-mingw32', 'armv7hl', 'armhf', true, windowsSuffix) - buildTarget('aarch64-w64-mingw32', 'aarch64', 'arm64', false, windowsSuffix) + buildTarget('armv7-w64-mingw32') + buildTarget('aarch64-w64-mingw32') } catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { - buildTarget('x86_64-w64-mingw32', 'x86_64', 'amd64', true, windowsSuffix) - buildTarget('i686-w64-mingw32', 'i386', 'i386', true, windowsSuffix) + buildTarget('x86_64-w64-mingw32') + buildTarget('i686-w64-mingw32') } } } @@ -85,7 +82,7 @@ pipeline { echo 'Deploying....' archiveArtifacts artifacts: 'cmake-build-*/*.deb, cmake-build-*/*.rpm, cmake-build-*/*.tar.gz, cmake-build-*/*.sh, cmake-build-release-emscripten/*.js', fingerprint: false catchError(buildResult: 'SUCCESS', stageResult: 'SUCCESS') { - archiveArtifacts artifacts: 'cmake-build-*/*wpkg.*.exe, cmake-build-*/*.zip' + archiveArtifacts artifacts: 'cmake-build-*/*Windows.*.exe, cmake-build-*/*.zip' } } } From 5fc16d7d416ee66a4b0e78aa882603b197d05bcf Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 24 Aug 2022 00:50:16 +0200 Subject: [PATCH 228/254] Jenkinsfile: Add two parameters to buildTarget to simplify the script Signed-off-by: Username404 --- Jenkinsfile | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 2d336f5..109e3f0 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,17 +1,19 @@ String cmake_generator() { return fileExists('/usr/bin/ninja') ? 'Ninja' : 'Unix Makefiles' } -String no_compilation_cache_flags() { return '-DNO_CCACHE=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON' } -def buildTarget(String path) { +def buildTarget(String path, String cmake_toolchain = '', boolean should_package = true) { final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' final String linker = "/usr/bin/${path}-ld" final String build_directory = "cmake-build-${path}" final boolean is_riscv = path.contains('riscv') + final boolean use_toolchain = cmake_toolchain != '' // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli -DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_SYSTEM_PROCESSOR=\"${path.substring(0, path.indexOf('-'))}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCMAKE_EXE_LINKER_FLAGS=-static -DNO_SELF_PACKER=${!is_riscv ? "OFF" : "ON"} -DIGNORE_MINIMAL_COMPILER_VERSION=ON ${no_compilation_cache_flags()}", + cmakeArgs: "--no-warn-unused-cli ${use_toolchain ? "-DCMAKE_TOOLCHAIN_FILE=${cmake_toolchain}" : "-DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_SYSTEM_PROCESSOR=\"${path.substring(0, path.indexOf('-'))}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCMAKE_EXE_LINKER_FLAGS=-static"} -DNO_SELF_PACKER=${!(is_riscv || use_toolchain) ? "OFF" : "ON"} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DNO_CCACHE=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON", generator: cmake_generator() cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' - cpack installation: 'Latest', workingDir: build_directory + if (should_package) { + cpack installation: 'Latest', workingDir: build_directory + } } /* Required Plugins: @@ -47,12 +49,7 @@ pipeline { echo "Building the ${env.BRANCH_NAME} branch.." buildTarget('x86_64-linux-musl') buildTarget('i686-linux-musl') - catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') { - cmakeBuild buildDir: "cmake-build-release-emscripten", buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "-DCMAKE_TOOLCHAIN_FILE=\"/usr/share/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake\" ${no_compilation_cache_flags()} -DNO_SELF_PACKER=ON", - generator: cmake_generator() - cmake arguments: "--build ./cmake-build-release-emscripten", installation: 'Latest' - } + buildTarget('emscripten', '/usr/share/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake', false) } } stage('Build for other architectures') { @@ -80,7 +77,7 @@ pipeline { stage('Deploy') { steps { echo 'Deploying....' - archiveArtifacts artifacts: 'cmake-build-*/*.deb, cmake-build-*/*.rpm, cmake-build-*/*.tar.gz, cmake-build-*/*.sh, cmake-build-release-emscripten/*.js', fingerprint: false + archiveArtifacts artifacts: 'cmake-build-*/*.deb, cmake-build-*/*.rpm, cmake-build-*/*.tar.gz, cmake-build-*/*.sh, cmake-build-*/*.js', fingerprint: false catchError(buildResult: 'SUCCESS', stageResult: 'SUCCESS') { archiveArtifacts artifacts: 'cmake-build-*/*Windows.*.exe, cmake-build-*/*.zip' } From 9d64f53728a63b6813dc89169d05348abac53c98 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 24 Aug 2022 01:17:49 +0200 Subject: [PATCH 229/254] Jenkinsfile: Fix the "Deploy" stage setting the build result to success when matching files are not found Signed-off-by: Username404 --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 109e3f0..12068df 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -78,7 +78,7 @@ pipeline { steps { echo 'Deploying....' archiveArtifacts artifacts: 'cmake-build-*/*.deb, cmake-build-*/*.rpm, cmake-build-*/*.tar.gz, cmake-build-*/*.sh, cmake-build-*/*.js', fingerprint: false - catchError(buildResult: 'SUCCESS', stageResult: 'SUCCESS') { + catchError(buildResult: currentBuild.result, stageResult: 'SUCCESS') { archiveArtifacts artifacts: 'cmake-build-*/*Windows.*.exe, cmake-build-*/*.zip' } } From 3cf67d34456ed52b7824bca1b33c8ecada58c892 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 24 Aug 2022 02:45:31 +0200 Subject: [PATCH 230/254] Jenkinsfile: Don't run upx on aarch64 windows executables Signed-off-by: Username404 --- Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 12068df..731faf6 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -4,11 +4,11 @@ def buildTarget(String path, String cmake_toolchain = '', boolean should_package final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' final String linker = "/usr/bin/${path}-ld" final String build_directory = "cmake-build-${path}" - final boolean is_riscv = path.contains('riscv') + final boolean not_packer_compatible = path.contains('riscv') || (path.contains('aarch64') && path.contains('mingw')) final boolean use_toolchain = cmake_toolchain != '' // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli ${use_toolchain ? "-DCMAKE_TOOLCHAIN_FILE=${cmake_toolchain}" : "-DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_SYSTEM_PROCESSOR=\"${path.substring(0, path.indexOf('-'))}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCMAKE_EXE_LINKER_FLAGS=-static"} -DNO_SELF_PACKER=${!(is_riscv || use_toolchain) ? "OFF" : "ON"} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DNO_CCACHE=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON", + cmakeArgs: "--no-warn-unused-cli ${use_toolchain ? "-DCMAKE_TOOLCHAIN_FILE=${cmake_toolchain}" : "-DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_SYSTEM_PROCESSOR=\"${path.substring(0, path.indexOf('-'))}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCMAKE_EXE_LINKER_FLAGS=-static"} -DNO_SELF_PACKER=${!(not_packer_compatible || use_toolchain) ? "OFF" : "ON"} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DNO_CCACHE=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON", generator: cmake_generator() cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' if (should_package) { From bf1cea3e77ac527828a3e21d1cec058cd89d1a5d Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 24 Aug 2022 03:16:06 +0200 Subject: [PATCH 231/254] Jenkinsfile: Use the matrix directive Signed-off-by: Username404 --- Jenkinsfile | 85 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 731faf6..c57ae60 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -6,16 +6,22 @@ def buildTarget(String path, String cmake_toolchain = '', boolean should_package final String build_directory = "cmake-build-${path}" final boolean not_packer_compatible = path.contains('riscv') || (path.contains('aarch64') && path.contains('mingw')) final boolean use_toolchain = cmake_toolchain != '' - // Note: CMake 3.20 or higher is needed - cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli ${use_toolchain ? "-DCMAKE_TOOLCHAIN_FILE=${cmake_toolchain}" : "-DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_SYSTEM_PROCESSOR=\"${path.substring(0, path.indexOf('-'))}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCMAKE_EXE_LINKER_FLAGS=-static"} -DNO_SELF_PACKER=${!(not_packer_compatible || use_toolchain) ? "OFF" : "ON"} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DNO_CCACHE=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON", - generator: cmake_generator() - cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' - if (should_package) { - cpack installation: 'Latest', workingDir: build_directory + catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') { + // Note: CMake 3.20 or higher is needed + cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', + cmakeArgs: "--no-warn-unused-cli ${use_toolchain ? "-DCMAKE_TOOLCHAIN_FILE=${cmake_toolchain}" : "-DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_SYSTEM_PROCESSOR=\"${path.substring(0, path.indexOf('-'))}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCMAKE_EXE_LINKER_FLAGS=-static"} -DNO_SELF_PACKER=${!(not_packer_compatible || use_toolchain) ? "OFF" : "ON"} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DNO_CCACHE=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON", + generator: cmake_generator() + cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' + if (should_package) { + cpack installation: 'Latest', workingDir: build_directory + } } } +def upload_archives() { + archiveArtifacts artifacts: 'cmake-build-*/*.deb, cmake-build-*/*.rpm, cmake-build-*/*.tar.gz, cmake-build-*/*.sh, cmake-build-*/*.js, cmake-build-*/*Windows.*.exe, cmake-build-*/*.zip', fingerprint: false +} + /* Required Plugins: - CMake - Sidebar Link @@ -45,42 +51,49 @@ pipeline { } stages { stage('Build') { + matrix { + agent any + axes { + axis { + name 'TARGET' + values( + 'x86_64-linux-musl', + 'i686-linux-musl', + 'armel-linux-musleabi', + 'armv7l-linux-musleabihf', + 'aarch64-linux-musl', + 'riscv64-linux-gnu', + 'x86_64-w64-mingw32', + 'i686-w64-mingw32', + 'armv7-w64-mingw32', + 'aarch64-w64-mingw32' + ) + } + } + stages { + stage('Compile and package') { + steps { + buildTarget("${TARGET}") + } + } + stage('Deploy') { + steps { + echo 'Deploying....' + upload_archives() + } + } + } + } + } + stage('Build using Emscripten') { steps { - echo "Building the ${env.BRANCH_NAME} branch.." - buildTarget('x86_64-linux-musl') - buildTarget('i686-linux-musl') buildTarget('emscripten', '/usr/share/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake', false) } } - stage('Build for other architectures') { - steps { - catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { - buildTarget('armel-linux-musleabi') - buildTarget('armv7l-linux-musleabihf') - buildTarget('aarch64-linux-musl') - buildTarget('riscv64-linux-gnu') - } - } - } - stage('Build for other platforms') { - steps { - catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') { - buildTarget('armv7-w64-mingw32') - buildTarget('aarch64-w64-mingw32') - } - catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { - buildTarget('x86_64-w64-mingw32') - buildTarget('i686-w64-mingw32') - } - } - } stage('Deploy') { steps { echo 'Deploying....' - archiveArtifacts artifacts: 'cmake-build-*/*.deb, cmake-build-*/*.rpm, cmake-build-*/*.tar.gz, cmake-build-*/*.sh, cmake-build-*/*.js', fingerprint: false - catchError(buildResult: currentBuild.result, stageResult: 'SUCCESS') { - archiveArtifacts artifacts: 'cmake-build-*/*Windows.*.exe, cmake-build-*/*.zip' - } + upload_archives() } } } From 8004d3a2838210eae49a7a68f34fa686c08019b5 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 24 Aug 2022 11:14:04 +0200 Subject: [PATCH 232/254] Jenkinsfile: Separate compilation and packaging, move the buildTarget function's content into the "Compile" stage, and clean the workspace of the matrix too Signed-off-by: Username404 --- Jenkinsfile | 74 +++++++++++++++++++++++------------------------------ 1 file changed, 32 insertions(+), 42 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index c57ae60..f543294 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,26 +1,5 @@ String cmake_generator() { return fileExists('/usr/bin/ninja') ? 'Ninja' : 'Unix Makefiles' } - -def buildTarget(String path, String cmake_toolchain = '', boolean should_package = true) { - final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' - final String linker = "/usr/bin/${path}-ld" - final String build_directory = "cmake-build-${path}" - final boolean not_packer_compatible = path.contains('riscv') || (path.contains('aarch64') && path.contains('mingw')) - final boolean use_toolchain = cmake_toolchain != '' - catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') { - // Note: CMake 3.20 or higher is needed - cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli ${use_toolchain ? "-DCMAKE_TOOLCHAIN_FILE=${cmake_toolchain}" : "-DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_SYSTEM_PROCESSOR=\"${path.substring(0, path.indexOf('-'))}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCMAKE_EXE_LINKER_FLAGS=-static"} -DNO_SELF_PACKER=${!(not_packer_compatible || use_toolchain) ? "OFF" : "ON"} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DNO_CCACHE=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON", - generator: cmake_generator() - cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' - if (should_package) { - cpack installation: 'Latest', workingDir: build_directory - } - } -} - -def upload_archives() { - archiveArtifacts artifacts: 'cmake-build-*/*.deb, cmake-build-*/*.rpm, cmake-build-*/*.tar.gz, cmake-build-*/*.sh, cmake-build-*/*.js, cmake-build-*/*Windows.*.exe, cmake-build-*/*.zip', fingerprint: false -} +def clean_workspace() { cleanWs(cleanWhenNotBuilt: false, deleteDirs: true, disableDeferredWipeout: false, notFailBuild: true, skipWhenFailed: false) } /* Required Plugins: - CMake @@ -66,40 +45,51 @@ pipeline { 'x86_64-w64-mingw32', 'i686-w64-mingw32', 'armv7-w64-mingw32', - 'aarch64-w64-mingw32' + 'aarch64-w64-mingw32', + '/usr/share/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake' ) } } stages { - stage('Compile and package') { + stage('Compile') { steps { - buildTarget("${TARGET}") + script { + final String path = "${TARGET}" + final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' + final String linker = "/usr/bin/${path}-ld" + final boolean not_packer_compatible = path.contains('riscv') || (path.contains('aarch64') && path.contains('mingw')) + final boolean use_toolchain = path.endsWith('.cmake') + final String build_directory = "cmake-build-${use_toolchain ? path.substring(path.lastIndexOf('/') + 1, path.length() - 6) : path}".toLowerCase() + catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') { + // Note: CMake 3.20 or higher is needed + cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', + cmakeArgs: "--no-warn-unused-cli ${use_toolchain ? "-DCMAKE_TOOLCHAIN_FILE=${path}" : "-DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_SYSTEM_PROCESSOR=\"${path.substring(0, path.indexOf('-'))}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCMAKE_EXE_LINKER_FLAGS=-static"} -DNO_SELF_PACKER=${!(not_packer_compatible || use_toolchain) ? "OFF" : "ON"} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DNO_CCACHE=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON", + generator: cmake_generator() + cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' + } + } + } + } + stage('Package') { + when { equals expected: true, actual: !"${TARGET}".endsWith('.cmake') } + steps { + catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') { + cpack installation: 'Latest', workingDir: "cmake-build-${TARGET}" + } } } stage('Deploy') { steps { echo 'Deploying....' - upload_archives() + catchError(buildResult: "${TARGET}".endsWith('.cmake') ? 'FAILURE' : 'UNSTABLE', stageResult: 'FAILURE') { + archiveArtifacts artifacts: 'cmake-build-*/*.deb, cmake-build-*/*.rpm, cmake-build-*/*.tar.gz, cmake-build-*/*.sh, cmake-build-*/*.js, cmake-build-*/*Windows.*.exe, cmake-build-*/*.zip', fingerprint: false + } } } } - } - } - stage('Build using Emscripten') { - steps { - buildTarget('emscripten', '/usr/share/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake', false) - } - } - stage('Deploy') { - steps { - echo 'Deploying....' - upload_archives() + post { always { clean_workspace() } } } } } - post { - always { - cleanWs(cleanWhenNotBuilt: false, deleteDirs: true, disableDeferredWipeout: false, notFailBuild: true, skipWhenFailed: false) - } - } + post { always { clean_workspace() } } } \ No newline at end of file From ab2b666dd33b7db2e744be1c60e255766ac08332 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 24 Aug 2022 12:49:14 +0200 Subject: [PATCH 233/254] CMakeLists.txt: Improve CPACK_PACKAGE_FILE_NAME Signed-off-by: Username404 --- CMakeLists.txt | 3 ++- Jenkinsfile | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5949f93..8782fbf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.18) project(Yerbacon VERSION 0.0.1 LANGUAGES C CXX) set(EXENAME "ybcon") +string(TOLOWER "${PROJECT_NAME}" LOWERCASE_PROJECT_NAME) if (NOT DEFINED CODENAME) set(CODENAME "Unknown") @@ -153,7 +154,7 @@ set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt") set(CPACK_PACKAGE_CONTACT "Username404 ") set(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME} ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}") -set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${CODENAME}-${TIME}_${CMAKE_SYSTEM_NAME}.${CMAKE_SYSTEM_PROCESSOR}") +set(CPACK_PACKAGE_FILE_NAME "${LOWERCASE_PROJECT_NAME}-${PROJECT_VERSION}-${TIME}.${CMAKE_SYSTEM_PROCESSOR}") include_directories(${CMAKE_CURRENT_LIST_DIR}) add_executable(${EXENAME} src/main.cpp ${CMAKE_CURRENT_BINARY_DIR}/processed/${PROJECT_NAME}.rc src/etc/filefuncs.cpp src/etc/lexer.cpp src/headers/lex.hpp src/headers/misc.hpp src/headers/parsing/ParseComponents.hpp src/headers/transpiler/Target.hpp src/headers/transpiler/implementations/Lua.hpp src/headers/transpiler/implementations/Js.hpp src/headers/transpiler/implementations/Py.hpp src/headers/parsing/Parser.hpp src/headers/arguments.hpp src/headers/parsing/ReservedIdentifiers.hpp) diff --git a/Jenkinsfile b/Jenkinsfile index f543294..4f23a62 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -82,7 +82,7 @@ pipeline { steps { echo 'Deploying....' catchError(buildResult: "${TARGET}".endsWith('.cmake') ? 'FAILURE' : 'UNSTABLE', stageResult: 'FAILURE') { - archiveArtifacts artifacts: 'cmake-build-*/*.deb, cmake-build-*/*.rpm, cmake-build-*/*.tar.gz, cmake-build-*/*.sh, cmake-build-*/*.js, cmake-build-*/*Windows.*.exe, cmake-build-*/*.zip', fingerprint: false + archiveArtifacts artifacts: 'cmake-build-*/*.deb, cmake-build-*/*.rpm, cmake-build-*/*.tar.gz, cmake-build-*/*.sh, cmake-build-*/*.js, cmake-build-*/*.exe, cmake-build-*/*.zip', fingerprint: false } } } From c55dbb25a6a088fb68e356b424dd26847b04b64b Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 24 Aug 2022 17:33:20 +0200 Subject: [PATCH 234/254] CMakeLists.txt: Reintroduce CXX_TARGET Signed-off-by: Username404 --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8782fbf..951d5ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,9 @@ if (CMAKE_CXX_LINK_PIE_SUPPORTED) elseif(USER_DEFINED_PIE AND CMAKE_POSITION_INDEPENDENT_CODE) message(NOTICE "-- Could NOT manually enable Position-Independent Code (PIC) because it is not supported by the current toolchain") endif() -if (CMAKE_SYSTEM_PROCESSOR STREQUAL "") +if (DEFINED CXX_TARGET) + set(CMAKE_SYSTEM_PROCESSOR "${CXX_TARGET}") +elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "") set(CMAKE_SYSTEM_PROCESSOR "${CMAKE_HOST_SYSTEM_PROCESSOR}") endif() set(CMAKE_CXX_FLAGS "-Wall") From 344b810f12437fc64dd8040f89a361fa7f59d007 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 24 Aug 2022 17:58:12 +0200 Subject: [PATCH 235/254] Jenkinsfile: Reintroduce RPM and DEB package architectures Signed-off-by: Username404 --- Jenkinsfile | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 4f23a62..1fdb621 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -36,16 +36,16 @@ pipeline { axis { name 'TARGET' values( - 'x86_64-linux-musl', - 'i686-linux-musl', - 'armel-linux-musleabi', - 'armv7l-linux-musleabihf', - 'aarch64-linux-musl', - 'riscv64-linux-gnu', - 'x86_64-w64-mingw32', - 'i686-w64-mingw32', - 'armv7-w64-mingw32', - 'aarch64-w64-mingw32', + 'x86_64-linux-musl (RPM=x86_64, DEB=amd64)', + 'i686-linux-musl (RPM=i386, DEB=i386)', + 'armel-linux-musleabi (RPM=armv4l, DEB=armel)', + 'armv7l-linux-musleabihf (RPM=armv7hl, DEB=armhf)', + 'aarch64-linux-musl (RPM=aarch64, DEB=arm64)', + 'riscv64-linux-gnu (RPM=riscv64, DEB=riscv64)', + 'x86_64-w64-mingw32 (RPM=x86_64, DEB=amd64)', + 'i686-w64-mingw32 (RPM=i386, DEB=i386)', + 'armv7-w64-mingw32 (RPM=armv7hl, DEB=armhf)', + 'aarch64-w64-mingw32 (RPM=aarch64, DEB=arm64)', '/usr/share/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake' ) } @@ -54,16 +54,18 @@ pipeline { stage('Compile') { steps { script { - final String path = "${TARGET}" + final boolean use_toolchain = "${TARGET}".endsWith('.cmake') + final String path = use_toolchain ? "${TARGET}" : "${TARGET}".substring(0, "${TARGET}".indexOf(' (')) + final String rpmArch = use_toolchain ? 'noarch' : "${TARGET}".substring("${TARGET}".indexOf('(RPM=') + 5, "${TARGET}".indexOf(',')) + final String debArch = use_toolchain ? 'noarch' : "${TARGET}".substring("${TARGET}".indexOf('DEB=') + 4, "${TARGET}".indexOf(')')) final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' final String linker = "/usr/bin/${path}-ld" final boolean not_packer_compatible = path.contains('riscv') || (path.contains('aarch64') && path.contains('mingw')) - final boolean use_toolchain = path.endsWith('.cmake') final String build_directory = "cmake-build-${use_toolchain ? path.substring(path.lastIndexOf('/') + 1, path.length() - 6) : path}".toLowerCase() catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') { // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli ${use_toolchain ? "-DCMAKE_TOOLCHAIN_FILE=${path}" : "-DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCMAKE_SYSTEM_PROCESSOR=\"${path.substring(0, path.indexOf('-'))}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCMAKE_EXE_LINKER_FLAGS=-static"} -DNO_SELF_PACKER=${!(not_packer_compatible || use_toolchain) ? "OFF" : "ON"} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DNO_CCACHE=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON", + cmakeArgs: "--no-warn-unused-cli ${use_toolchain ? "-DCMAKE_TOOLCHAIN_FILE=${path}" : "-DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCXX_TARGET=\"${use_toolchain ? 'noarch' : debArch}\" -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCMAKE_SYSTEM_PROCESSOR=\"${path.substring(0, path.indexOf('-'))}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCMAKE_EXE_LINKER_FLAGS=-static"} -DNO_SELF_PACKER=${!(not_packer_compatible || use_toolchain) ? "OFF" : "ON"} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DNO_CCACHE=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON", generator: cmake_generator() cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' } @@ -74,7 +76,9 @@ pipeline { when { equals expected: true, actual: !"${TARGET}".endsWith('.cmake') } steps { catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') { - cpack installation: 'Latest', workingDir: "cmake-build-${TARGET}" + script { + cpack installation: 'Latest', workingDir: "cmake-build-${"${TARGET}".substring(0, "${TARGET}".indexOf(' ('))}" + } } } } From d2a83a2f5e84bc7315a36526dfdd401a046ca33f Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 27 Aug 2022 21:33:40 +0200 Subject: [PATCH 236/254] CMakeLists.txt: Use ThinLTO instead of full LTO when Clang is present Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 951d5ee..933e367 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -110,7 +110,7 @@ elseif(${IS_CLANG}) message(FATAL_ERROR "Clang ${MINIMAL_CLANG} or higher is required.") endif() if (${CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE} OR MINGW) # CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE is false on llvm-mingw toolchains even though it is supported - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto=full") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto=thin") if (NOT DEFINED EMSCRIPTEN) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fwhole-program-vtables") endif() From 62652ad9a4fbd3083b2a617a170620be7e92789b Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 27 Aug 2022 21:59:32 +0200 Subject: [PATCH 237/254] CMakeLists.txt: Don't redefine CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE if it has already been defined Signed-off-by: Username404 --- CMakeLists.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 933e367..de79677 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,8 +91,13 @@ if (${IS_GNU} OR ${IS_CLANG}) endif() endif() -include(CheckIPOSupported) -check_ipo_supported(RESULT CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE LANGUAGES CXX) +if (NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE) + set(USER_DEFINED_INTERPROCEDURAL_OPTIMIZATION_RELEASE NO) + include(CheckIPOSupported) + check_ipo_supported(RESULT CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE LANGUAGES CXX) +else() + set(USER_DEFINED_INTERPROCEDURAL_OPTIMIZATION_RELEASE YES) +endif() if (${IS_GNU}) if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_GNU} AND NOT ${IGNORE_MINIMAL_COMPILER_VERSION}) @@ -109,7 +114,7 @@ elseif(${IS_CLANG}) if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_CLANG} AND NOT ${IGNORE_MINIMAL_COMPILER_VERSION}) message(FATAL_ERROR "Clang ${MINIMAL_CLANG} or higher is required.") endif() - if (${CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE} OR MINGW) # CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE is false on llvm-mingw toolchains even though it is supported + if (${CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE} OR (MINGW AND NOT USER_DEFINED_INTERPROCEDURAL_OPTIMIZATION_RELEASE)) # CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE is false on llvm-mingw toolchains even though it is supported set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto=thin") if (NOT DEFINED EMSCRIPTEN) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fwhole-program-vtables") From 94e71ef61eabf454c6384ffe60648f279e48d8ff Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 27 Aug 2022 22:44:33 +0200 Subject: [PATCH 238/254] Jenkinsfile: Disable LTO and UPX for the 'armv7-w64-mingw32' target Signed-off-by: Username404 --- Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 1fdb621..84b616d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -60,12 +60,12 @@ pipeline { final String debArch = use_toolchain ? 'noarch' : "${TARGET}".substring("${TARGET}".indexOf('DEB=') + 4, "${TARGET}".indexOf(')')) final String system_name = !path.contains('mingw') ? sh(returnStdout: true, script: 'uname -s').trim() : 'Windows' final String linker = "/usr/bin/${path}-ld" - final boolean not_packer_compatible = path.contains('riscv') || (path.contains('aarch64') && path.contains('mingw')) + final boolean not_packer_compatible = path.contains('riscv') || ((path.contains('aarch64') || path.contains('arm')) && path.contains('mingw')) final String build_directory = "cmake-build-${use_toolchain ? path.substring(path.lastIndexOf('/') + 1, path.length() - 6) : path}".toLowerCase() catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') { // Note: CMake 3.20 or higher is needed cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', - cmakeArgs: "--no-warn-unused-cli ${use_toolchain ? "-DCMAKE_TOOLCHAIN_FILE=${path}" : "-DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCXX_TARGET=\"${use_toolchain ? 'noarch' : debArch}\" -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCMAKE_SYSTEM_PROCESSOR=\"${path.substring(0, path.indexOf('-'))}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCMAKE_EXE_LINKER_FLAGS=-static"} -DNO_SELF_PACKER=${!(not_packer_compatible || use_toolchain) ? "OFF" : "ON"} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DNO_CCACHE=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON", + cmakeArgs: "--no-warn-unused-cli ${use_toolchain ? "-DCMAKE_TOOLCHAIN_FILE=${path}" : "-DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCXX_TARGET=\"${use_toolchain ? 'noarch' : debArch}\" -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCMAKE_SYSTEM_PROCESSOR=\"${path.substring(0, path.indexOf('-'))}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCMAKE_EXE_LINKER_FLAGS=-static"} -DNO_SELF_PACKER=${!(not_packer_compatible || use_toolchain) ? "OFF" : "ON"} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DNO_CCACHE=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON${path.endsWith('armv7-w64-mingw32') ? ' -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=NO' : ''}", generator: cmake_generator() cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' } From 23f24e55b1d52ba4e4956d209b8f76274402c907 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 28 Aug 2022 10:51:35 +0200 Subject: [PATCH 239/254] Parser.hpp: Fix a segmentation fault happening when parseTree is empty Signed-off-by: Username404 --- src/headers/parsing/Parser.hpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 7a7448b..3020ad5 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -149,19 +149,21 @@ namespace Parser { } catch (const NamedIdentifier::identifier_reserved_exception&) { parsingError(current, " is a reserved identifier", true); } - const auto& last = parseTree.cend() - 1; - const type_info& lastId = last->get()->getId(); - const auto* last_identifier = dynamic_cast*>(last->get()); - if (last_identifier != nullptr) { - if (lastId != typeid(Define) and - any_of(parseTree.cbegin(), last, [&last_identifier](const component_ptr& pointer){ - try { - return dynamic_cast&>(*pointer).name == last_identifier->name; - } catch (const bad_cast&) { - return false; - } - })) - { parsingError(current, " has already been defined previously", true); } + if (not parseTree.empty()) { + const auto& last = parseTree.cend() - 1; + const type_info& lastId = last->get()->getId(); + const auto* last_identifier = dynamic_cast*>(last->get()); + if (last_identifier != nullptr) { + if (lastId != typeid(Define) and + any_of(parseTree.cbegin(), last, [&last_identifier](const component_ptr& pointer){ + try { + return dynamic_cast&>(*pointer).name == last_identifier->name; + } catch (const bad_cast&) { + return false; + } + })) + { parsingError(current, " has already been defined previously", true); } + } } } return parseTree; From 8091d929330cd66cf7ecf19cd83babdfaad50a8b Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 28 Aug 2022 15:14:51 +0200 Subject: [PATCH 240/254] CMakeLists.txt: Set CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE to YES when using a llvm-mingw toolchain Signed-off-by: Username404 --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index de79677..ff3c464 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,7 +114,10 @@ elseif(${IS_CLANG}) if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_CLANG} AND NOT ${IGNORE_MINIMAL_COMPILER_VERSION}) message(FATAL_ERROR "Clang ${MINIMAL_CLANG} or higher is required.") endif() - if (${CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE} OR (MINGW AND NOT USER_DEFINED_INTERPROCEDURAL_OPTIMIZATION_RELEASE)) # CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE is false on llvm-mingw toolchains even though it is supported + if (MINGW AND NOT USER_DEFINED_INTERPROCEDURAL_OPTIMIZATION_RELEASE) # CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE is false on llvm-mingw toolchains even though it is supported + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE YES) + endif() + if (CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto=thin") if (NOT DEFINED EMSCRIPTEN) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fwhole-program-vtables") From cd7d7f6337ff59392fa7cf77b4954b60ed67900f Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 28 Aug 2022 15:59:58 +0200 Subject: [PATCH 241/254] Jenkinsfile: Don't publish windows executables which are not packaged Signed-off-by: Username404 --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 84b616d..5a37926 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -86,7 +86,7 @@ pipeline { steps { echo 'Deploying....' catchError(buildResult: "${TARGET}".endsWith('.cmake') ? 'FAILURE' : 'UNSTABLE', stageResult: 'FAILURE') { - archiveArtifacts artifacts: 'cmake-build-*/*.deb, cmake-build-*/*.rpm, cmake-build-*/*.tar.gz, cmake-build-*/*.sh, cmake-build-*/*.js, cmake-build-*/*.exe, cmake-build-*/*.zip', fingerprint: false + archiveArtifacts artifacts: 'cmake-build-*/*.deb, cmake-build-*/*.rpm, cmake-build-*/*.tar.gz, cmake-build-*/*.sh, cmake-build-*/*.js, cmake-build-*/*.*.exe, cmake-build-*/*.zip', fingerprint: false } } } From c3e3d46cce5b08a296e6277c312371ad76a628b9 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 28 Aug 2022 21:45:09 +0200 Subject: [PATCH 242/254] Add Dockerfile and .dockerignore Signed-off-by: Username404 --- .dockerignore | 6 ++++++ Dockerfile | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..b04a8c9 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +Dockerfile +.dockerignore +docs +examples +Jenkinsfile +cmake-build-* \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8c04964 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +FROM alpine:3.16.2 +RUN apk add --no-cache gcc g++ musl-dev libc-dev cmake git samurai coreutils rpm dpkg dpkg-dev xz file + +RUN mkdir -p /usr/src/yerbacon +WORKDIR /usr/src/ +RUN git clone --quiet -n --branch devel4 https://github.com/upx/upx/ +ARG CMAKE_BUILD_TYPE="Release" +WORKDIR ./upx +RUN git checkout --quiet 73377971d48e88a99f53372f6520e1eec6ec453b +RUN git submodule --quiet update --init +RUN mkdir -p ./build/release +WORKDIR ./build/release +RUN cmake -G Ninja ../.. +RUN cmake --build . --parallel `nproc` + +WORKDIR /usr/src/yerbacon +COPY . ./ +RUN cmake -G Ninja -S . -B ./cmake-build-release -DCMAKE_EXE_LINKER_FLAGS="-static" -DSELF_PACKER_FOR_EXECUTABLE=/usr/src/upx/build/release/upx +RUN cmake --build ./cmake-build-release --parallel `nproc` +WORKDIR ./cmake-build-release +RUN cpack \ No newline at end of file From 0636f499799b5abdf224440f90a554555db683f8 Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 8 Sep 2022 20:34:02 +0200 Subject: [PATCH 243/254] Dockerfile: Always use the latest Alpine Linux and UPX versions Signed-off-by: Username404 --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8c04964..fc2bb29 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.16.2 +FROM alpine:edge RUN apk add --no-cache gcc g++ musl-dev libc-dev cmake git samurai coreutils rpm dpkg dpkg-dev xz file RUN mkdir -p /usr/src/yerbacon @@ -6,7 +6,7 @@ WORKDIR /usr/src/ RUN git clone --quiet -n --branch devel4 https://github.com/upx/upx/ ARG CMAKE_BUILD_TYPE="Release" WORKDIR ./upx -RUN git checkout --quiet 73377971d48e88a99f53372f6520e1eec6ec453b +RUN git checkout --quiet HEAD RUN git submodule --quiet update --init RUN mkdir -p ./build/release WORKDIR ./build/release From caf5bc338d97df147f327471eee8616e230a3e80 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sun, 18 Sep 2022 20:16:08 +0200 Subject: [PATCH 244/254] Yerbacon.hpp: Don't check for __cpp_using_enum Signed-off-by: Username404 --- src/headers/Yerbacon.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/headers/Yerbacon.hpp b/src/headers/Yerbacon.hpp index 4f19f1b..801deed 100644 --- a/src/headers/Yerbacon.hpp +++ b/src/headers/Yerbacon.hpp @@ -22,9 +22,6 @@ #if not defined(__cpp_lib_concepts) || not defined(__cpp_lib_integer_comparison_functions) #error "The current standard library is incomplete" #endif -#ifndef __cpp_using_enum -#error "The "using enum" syntax is not supported by this compiler" -#endif #define token_expansion(X) #X #define make_string(X) token_expansion(X) From 764f3287ff8e54525e71310dce010dd5e40efa36 Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 20 Sep 2022 22:28:40 +0200 Subject: [PATCH 245/254] Dockerfile: Make sure upx always works by setting a static version Signed-off-by: Username404 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index fc2bb29..1ccced1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ WORKDIR /usr/src/ RUN git clone --quiet -n --branch devel4 https://github.com/upx/upx/ ARG CMAKE_BUILD_TYPE="Release" WORKDIR ./upx -RUN git checkout --quiet HEAD +RUN git checkout --quiet 70f14101ed79642e39340fde8514aa19a99f32dc RUN git submodule --quiet update --init RUN mkdir -p ./build/release WORKDIR ./build/release From f348dc985f3d066721118149adf11ad94a043b77 Mon Sep 17 00:00:00 2001 From: Username404 Date: Wed, 21 Sep 2022 20:35:03 +0200 Subject: [PATCH 246/254] Target.hpp: Don't return a reference to a static thread-local map in the Target::getTaskMapInstance function It only worked properly with the "--parallel" flag Signed-off-by: Username404 --- src/headers/transpiler/Target.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 859aa19..96dcd6c 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -124,10 +124,10 @@ protected: string separator; static constexpr const char* indentation = " "; public: - const unordered_task_map& getTaskMapInstance() { - static thread_local unordered_task_map staticMap = getTaskMap(); + unordered_task_map getTaskMapInstance() { + unordered_task_map fullMap = getTaskMap(); // Default / Shared tasks: - staticMap.merge(unordered_task_map({ + fullMap.merge(unordered_task_map({ make_task(ParseTree, transpileTree(parseComponent);), make_task(StandardComponents::Reference, output << parseComponent.name;), make_task(StandardComponents::Call, @@ -139,7 +139,7 @@ public: ), make_task(StandardComponents::types::Integer, output << setprecision(parseComponent.precision) << fixed << parseComponent.value;) })); - return staticMap; + return fullMap; }; static unique_ptr forName(string_view name, bool newLines); string transpileWithTree(const ParseTree& tree) { From 319c30cd039a54343fb3622b1b043c021056797d Mon Sep 17 00:00:00 2001 From: Username404 Date: Tue, 27 Sep 2022 16:08:44 +0000 Subject: [PATCH 247/254] ReservedIdentifiers.hpp: Make the identifiers array's initialization strictly constant --- src/headers/parsing/ReservedIdentifiers.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/headers/parsing/ReservedIdentifiers.hpp b/src/headers/parsing/ReservedIdentifiers.hpp index 0801838..3bc29d1 100644 --- a/src/headers/parsing/ReservedIdentifiers.hpp +++ b/src/headers/parsing/ReservedIdentifiers.hpp @@ -6,7 +6,7 @@ #include "../Yerbacon.hpp" #include -static const array identifiers { +static constinit const array identifiers { "class", "structure", "print", "print_line" }; From cb3e1b75ae9522b93aa0496fefa8ef65be22c0b4 Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 29 Sep 2022 20:32:41 +0200 Subject: [PATCH 248/254] CMakeLists.txt: Disable SAFE_HEAP when using emscripten on Android Signed-off-by: Username404 --- CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ff3c464..36193ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,7 +74,12 @@ if (${IS_GNU} OR ${IS_CLANG}) if (NOT DEFINED EMSCRIPTEN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong -fstack-clash-protection") else() - set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=1 -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 -sSTRICT=1 -sMINIMAL_RUNTIME=0 -sDISABLE_EXCEPTION_CATCHING=0 ${CMAKE_EXE_LINKER_FLAGS}") + if (NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Android") # See https://github.com/WebAssembly/binaryen/issues/4519 + set(IS_HOST_NOT_ANDROID 1) + else() + set(IS_HOST_NOT_ANDROID 0) + endif() + set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=${IS_HOST_NOT_ANDROID} -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 -sSTRICT=1 -sMINIMAL_RUNTIME=0 -sDISABLE_EXCEPTION_CATCHING=0 ${CMAKE_EXE_LINKER_FLAGS}") if (CMAKE_USE_PTHREADS_INIT) set(CMAKE_CXX_FLAGS "-pthread ${CMAKE_CXX_FLAGS}") # Emscripten requires the -pthread flag set(CMAKE_EXE_LINKER_FLAGS "--closure-args=\"--compilation_level SIMPLE\" -sPROXY_TO_PTHREAD=1 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706 From d4af5fecd94bd9b5845365a6408b1624b5871412 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 30 Sep 2022 08:12:41 +0200 Subject: [PATCH 249/254] CMakeLists.txt: Allow memory growth on emscripten --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 36193ae..0697b83 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,7 +79,7 @@ if (${IS_GNU} OR ${IS_CLANG}) else() set(IS_HOST_NOT_ANDROID 0) endif() - set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=${IS_HOST_NOT_ANDROID} -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 -sSTRICT=1 -sMINIMAL_RUNTIME=0 -sDISABLE_EXCEPTION_CATCHING=0 ${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=${IS_HOST_NOT_ANDROID} -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 -sSTRICT=1 -sMINIMAL_RUNTIME=0 -sDISABLE_EXCEPTION_CATCHING=0 -sALLOW_MEMORY_GROWTH=1 -Wno-pthreads-mem-growth -sMEMORY_GROWTH_GEOMETRIC_STEP=0 ${CMAKE_EXE_LINKER_FLAGS}") if (CMAKE_USE_PTHREADS_INIT) set(CMAKE_CXX_FLAGS "-pthread ${CMAKE_CXX_FLAGS}") # Emscripten requires the -pthread flag set(CMAKE_EXE_LINKER_FLAGS "--closure-args=\"--compilation_level SIMPLE\" -sPROXY_TO_PTHREAD=1 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706 From ccff82dba0561eac1285d0d0cde53f99537fb9b2 Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 6 Oct 2022 15:52:28 +0200 Subject: [PATCH 250/254] Dockerfile: Make sure the upx repository is up-to-date Signed-off-by: Username404 --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 1ccced1..4a2bbf5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,9 @@ RUN apk add --no-cache gcc g++ musl-dev libc-dev cmake git samurai coreutils rpm RUN mkdir -p /usr/src/yerbacon WORKDIR /usr/src/ -RUN git clone --quiet -n --branch devel4 https://github.com/upx/upx/ +ARG BRANCH="devel4" +ADD https://api.github.com/repos/upx/upx/git/refs/heads/$BRANCH version.json +RUN git clone --quiet -n --branch $BRANCH https://github.com/upx/upx/ ARG CMAKE_BUILD_TYPE="Release" WORKDIR ./upx RUN git checkout --quiet 70f14101ed79642e39340fde8514aa19a99f32dc From a828280693a95ea3ee89345d1a9dcde48d804d56 Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 6 Oct 2022 15:57:38 +0200 Subject: [PATCH 251/254] Dockerfile: Update the UPX version Signed-off-by: Username404 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 4a2bbf5..c8fbde4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ ADD https://api.github.com/repos/upx/upx/git/refs/heads/$BRANCH version.json RUN git clone --quiet -n --branch $BRANCH https://github.com/upx/upx/ ARG CMAKE_BUILD_TYPE="Release" WORKDIR ./upx -RUN git checkout --quiet 70f14101ed79642e39340fde8514aa19a99f32dc +RUN git checkout --quiet 65707900bc92153349db9c7c3389ef2ba4e9e877 RUN git submodule --quiet update --init RUN mkdir -p ./build/release WORKDIR ./build/release From e7df484db021260412c28772ddecd6cb97f0915e Mon Sep 17 00:00:00 2001 From: Username404 Date: Thu, 6 Oct 2022 16:23:16 +0200 Subject: [PATCH 252/254] CMakeLists.txt: Disable DECLARE_ASM_MODULE_EXPORTS on emscripten Signed-off-by: Username404 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0697b83..648d0c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,7 +79,7 @@ if (${IS_GNU} OR ${IS_CLANG}) else() set(IS_HOST_NOT_ANDROID 0) endif() - set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=${IS_HOST_NOT_ANDROID} -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 -sSTRICT=1 -sMINIMAL_RUNTIME=0 -sDISABLE_EXCEPTION_CATCHING=0 -sALLOW_MEMORY_GROWTH=1 -Wno-pthreads-mem-growth -sMEMORY_GROWTH_GEOMETRIC_STEP=0 ${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=${IS_HOST_NOT_ANDROID} -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 -sSTRICT=1 -sMINIMAL_RUNTIME=0 -sDISABLE_EXCEPTION_CATCHING=0 -sALLOW_MEMORY_GROWTH=1 -Wno-pthreads-mem-growth -sMEMORY_GROWTH_GEOMETRIC_STEP=0 -sDECLARE_ASM_MODULE_EXPORTS=0 ${CMAKE_EXE_LINKER_FLAGS}") if (CMAKE_USE_PTHREADS_INIT) set(CMAKE_CXX_FLAGS "-pthread ${CMAKE_CXX_FLAGS}") # Emscripten requires the -pthread flag set(CMAKE_EXE_LINKER_FLAGS "--closure-args=\"--compilation_level SIMPLE\" -sPROXY_TO_PTHREAD=1 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706 From 022a0c6b62905ba5b0dd65b40e621f2ecd165eb0 Mon Sep 17 00:00:00 2001 From: Username404 Date: Fri, 7 Oct 2022 22:59:00 +0200 Subject: [PATCH 253/254] CMakeLists.txt: Add a vercel_pkg CMake target to package the JavaScript output into executables for macOS when using emscripten and yarn (or npm) Signed-off-by: Username404 --- CMakeLists.txt | 25 ++++++++++++++++++++++--- Jenkinsfile | 7 +++++-- resources/.npmrc | 1 + resources/package.json | 13 +++++++++++++ 4 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 resources/.npmrc create mode 100644 resources/package.json diff --git a/CMakeLists.txt b/CMakeLists.txt index 648d0c0..7c44d3f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,8 @@ set(EXEDESC "Transpiler for the yerbacon language.") string(TIMESTAMP SHORT_BUILD_TIMESTAMP "%Y%m") string(SUBSTRING ${SHORT_BUILD_TIMESTAMP} 2 4 SHORT_BUILD_TIMESTAMP) string(ASCII 169 CopyrightCharacter) -string(TIMESTAMP LEGAL-COPYRIGHT "Copyright ${CopyrightCharacter} 2020-%Y. Available under the MPL-2.0 license.") +set(CPACK_RPM_PACKAGE_LICENSE "MPL-2.0") +string(TIMESTAMP LEGAL-COPYRIGHT "Copyright ${CopyrightCharacter} 2020-%Y. Available under the ${CPACK_RPM_PACKAGE_LICENSE} license.") file(COPY "resources/${PROJECT_NAME}.ico" DESTINATION "processed") configure_file("resources/${PROJECT_NAME}.manifest" "processed/${PROJECT_NAME}.manifest" @ONLY) configure_file("resources/${PROJECT_NAME}.rc" "processed/${PROJECT_NAME}.rc" @ONLY) @@ -200,7 +201,26 @@ if (NOT (UPPERCASE_BUILD_TYPE STREQUAL "DEBUG" OR UPPERCASE_BUILD_TYPE STREQUAL endif() endif() -if (UNIX AND NOT (MINGW OR CMAKE_HOST_WIN32)) +if (EMSCRIPTEN) + find_program(NPM_PRESENT npm) + find_program(YARN_PRESENT yarn) + if (YARN_PRESENT) + set(NODE_PACKAGE_PROGRAM "${YARN_PRESENT}") + elseif(NPM_PRESENT) + set(NODE_PACKAGE_PROGRAM "${NPM_PRESENT}") + endif() + if (DEFINED NODE_PACKAGE_PROGRAM) + configure_file("resources/package.json" "processed/package.json" @ONLY) + file(COPY "${CMAKE_CURRENT_BINARY_DIR}/processed/package.json" DESTINATION ".") + file(COPY "resources/.npmrc" DESTINATION ".") + add_custom_target(vercel_pkg COMMAND ${NODE_PACKAGE_PROGRAM} install) + add_dependencies(vercel_pkg ${EXENAME}) + # Warning: https://github.com/sbingner/ldid has to be on the PATH, before packaging, for the arm64 macOS executable to work + add_custom_command(TARGET vercel_pkg POST_BUILD COMMAND node_modules/.bin/pkg --config processed/package.json -C Brotli $ --no-bytecode --public-packages "\"*\"" --public --output "${EXENAME}-mac" VERBATIM) + endif() +endif() + +if (UNIX AND NOT (MINGW OR CMAKE_HOST_WIN32 OR EMSCRIPTEN)) include(GNUInstallDirs) set(CMAKE_INSTALL_PREFIX "/usr") set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") @@ -214,7 +234,6 @@ if (UNIX AND NOT (MINGW OR CMAKE_HOST_WIN32)) set(CPACK_RPM_COMPRESSION_TYPE ${CPACK_DEBIAN_COMPRESSION_TYPE}) set(CPACK_RPM_PACKAGE_AUTOREQ YES) set(CPACK_RPM_FILE_NAME "RPM-DEFAULT") - set(CPACK_RPM_PACKAGE_LICENSE "MPL-2.0") set(CPACK_RPM_CHANGELOG_FILE "${CMAKE_CURRENT_SOURCE_DIR}/changelog") if (CMAKE_VERSION STREQUAL "3.21.1") message(WARNING "CPack ${CMAKE_VERSION} has a bug which causes rpm scripts to be unusable; please update or downgrade") diff --git a/Jenkinsfile b/Jenkinsfile index 5a37926..8066c55 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,5 +1,6 @@ String cmake_generator() { return fileExists('/usr/bin/ninja') ? 'Ninja' : 'Unix Makefiles' } def clean_workspace() { cleanWs(cleanWhenNotBuilt: false, deleteDirs: true, disableDeferredWipeout: false, notFailBuild: true, skipWhenFailed: false) } +boolean use_yarn_or_npm() { return fileExists('/usr/bin/yarn') || fileExists('/usr/bin/npm') } /* Required Plugins: - CMake @@ -13,6 +14,8 @@ def clean_workspace() { cleanWs(cleanWhenNotBuilt: false, deleteDirs: true, disa Optional Tools: - Ninja - UPX (d61edc9 or higher) + - Vercel PKG (https://github.com/vercel/pkg) + - LDID (https://github.com/sbingner/ldid) */ pipeline { @@ -67,7 +70,7 @@ pipeline { cmakeBuild buildDir: build_directory, buildType: 'release', cleanBuild: true, installation: 'Latest', cmakeArgs: "--no-warn-unused-cli ${use_toolchain ? "-DCMAKE_TOOLCHAIN_FILE=${path}" : "-DCMAKE_SYSTEM_NAME=\"${system_name}\" -DCXX_TARGET=\"${use_toolchain ? 'noarch' : debArch}\" -DCPACK_RPM_PACKAGE_ARCHITECTURE=${rpmArch} -DCPACK_DEBIAN_PACKAGE_ARCHITECTURE=${debArch} -DCMAKE_SYSTEM_PROCESSOR=\"${path.substring(0, path.indexOf('-'))}\" -DCMAKE_C_COMPILER=/usr/bin/${path}-gcc -DCMAKE_CXX_COMPILER=/usr/bin/${path}-g++ -DCMAKE_LINKER=${fileExists("${linker}.gold") ? "${linker}.gold" : linker} -DCMAKE_AR=/usr/bin/${path}-ar -DCMAKE_RC_COMPILER=/usr/bin/${path}-windres -DCMAKE_EXE_LINKER_FLAGS=-static"} -DNO_SELF_PACKER=${!(not_packer_compatible || use_toolchain) ? "OFF" : "ON"} -DIGNORE_MINIMAL_COMPILER_VERSION=ON -DNO_CCACHE=ON -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON${path.endsWith('armv7-w64-mingw32') ? ' -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=NO' : ''}", generator: cmake_generator() - cmake arguments: "--build ./$build_directory --target ybcon", installation: 'Latest' + cmake arguments: "--build ./$build_directory --target ${!("${TARGET}".endsWith('Emscripten.cmake') && use_yarn_or_npm()) ? 'ybcon' : 'vercel_pkg'}", installation: 'Latest' } } } @@ -86,7 +89,7 @@ pipeline { steps { echo 'Deploying....' catchError(buildResult: "${TARGET}".endsWith('.cmake') ? 'FAILURE' : 'UNSTABLE', stageResult: 'FAILURE') { - archiveArtifacts artifacts: 'cmake-build-*/*.deb, cmake-build-*/*.rpm, cmake-build-*/*.tar.gz, cmake-build-*/*.sh, cmake-build-*/*.js, cmake-build-*/*.*.exe, cmake-build-*/*.zip', fingerprint: false + archiveArtifacts artifacts: "cmake-build-*/*.deb, cmake-build-*/*.rpm, cmake-build-*/*.tar.gz, cmake-build-*/*.sh, cmake-build-*/*.js,${use_yarn_or_npm() ? 'cmake-build-*/*-mac-*,' : ''} cmake-build-*/*.*.exe, cmake-build-*/*.zip", fingerprint: false } } } diff --git a/resources/.npmrc b/resources/.npmrc new file mode 100644 index 0000000..9cf9495 --- /dev/null +++ b/resources/.npmrc @@ -0,0 +1 @@ +package-lock=false \ No newline at end of file diff --git a/resources/package.json b/resources/package.json new file mode 100644 index 0000000..c475403 --- /dev/null +++ b/resources/package.json @@ -0,0 +1,13 @@ +{ + "name": "@EXENAME@", + "bin": "@EXENAME@.js", + "license": "@CPACK_RPM_PACKAGE_LICENSE@", + "devDependencies": { "pkg": "^5.8.0" }, + "pkg": { + "assets": "../@EXENAME@.worker.js", + "targets": [ + "latest-macos-x64", + "latest-macos-arm64" + ] + } +} \ No newline at end of file From 4abd0408b7f3e072d3b04a8ee54042a0213b49ff Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 29 Oct 2022 00:54:40 +0200 Subject: [PATCH 254/254] Dockerfile: Use the latest released version of upx instead of a static commit hash Signed-off-by: Username404 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index c8fbde4..7201374 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ ADD https://api.github.com/repos/upx/upx/git/refs/heads/$BRANCH version.json RUN git clone --quiet -n --branch $BRANCH https://github.com/upx/upx/ ARG CMAKE_BUILD_TYPE="Release" WORKDIR ./upx -RUN git checkout --quiet 65707900bc92153349db9c7c3389ef2ba4e9e877 +RUN git checkout --quiet `git tag | sort -V | tail -1` RUN git submodule --quiet update --init RUN mkdir -p ./build/release WORKDIR ./build/release