From d4df3aa4ead8e4e30ee137fb8864e6de1e9ad895 Mon Sep 17 00:00:00 2001 From: Username404-59 Date: Wed, 7 Aug 2024 03:05:55 +0200 Subject: [PATCH] Add boilerplate for semantic analysis Signed-off-by: Username404-59 --- CMakeLists.txt | 8 +++++++- src/headers/SemanticAnalysis.hpp | 29 +++++++++++++++++++++++++++++ src/headers/Tasking.hpp | 20 ++++++++++++++++++++ src/headers/parsing/Parser.hpp | 4 +++- src/headers/transpiler/Target.hpp | 11 ++++------- src/main.cpp | 5 ++++- 6 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 src/headers/SemanticAnalysis.hpp create mode 100644 src/headers/Tasking.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 6196ff0..863e670 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -186,7 +186,13 @@ set(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME} ${CMAKE_PROJECT_VERSION_MAJ 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 src/headers/emscripten_compatibility.h) +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 src/headers/emscripten_compatibility.h + src/headers/Tasking.hpp + src/headers/SemanticAnalysis.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/SemanticAnalysis.hpp b/src/headers/SemanticAnalysis.hpp new file mode 100644 index 0000000..d86e0a5 --- /dev/null +++ b/src/headers/SemanticAnalysis.hpp @@ -0,0 +1,29 @@ +#ifndef YERBACON_SEMANTICANALYSIS_HPP +#define YERBACON_SEMANTICANALYSIS_HPP + +#include "parsing/ParseComponents.hpp" +#include "Tasking.hpp" + +#define make_task(T, C, F) make_task_base_R(T, C, F) + +struct SemanticAnalyser final: public Tasking { + const auto& analyseTree(const ParseTree& tree) { + const auto& task_map = getTaskMapInstance(); + for (unsigned int i = 0; i < tree.size(); ++i) { + try { + task_map.at(tree[i]->getId())(tree, i); + } catch (const out_of_range&) {} + } + return tree; + } +private: + unordered_task_map getTaskMapInstance() final { + return { + + }; + }; +}; + +#undef make_task + +#endif //YERBACON_SEMANTICANALYSIS_HPP diff --git a/src/headers/Tasking.hpp b/src/headers/Tasking.hpp new file mode 100644 index 0000000..a0f1320 --- /dev/null +++ b/src/headers/Tasking.hpp @@ -0,0 +1,20 @@ +#ifndef YERBACON_TASKING_HPP +#define YERBACON_TASKING_HPP + +#include +#include +#include "parsing/ParseComponents.hpp" + +#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 = reinterpret_cast(*parsedTree[index]), T, C, F) + +class Tasking { +protected: + typedef function task; + typedef unordered_map unordered_task_map; +public: + virtual unordered_task_map getTaskMapInstance() = 0; + virtual ~Tasking() = default; +}; + +#endif //YERBACON_TASKING_HPP diff --git a/src/headers/parsing/Parser.hpp b/src/headers/parsing/Parser.hpp index 81dc165..0b231c0 100644 --- a/src/headers/parsing/Parser.hpp +++ b/src/headers/parsing/Parser.hpp @@ -134,7 +134,8 @@ namespace Parser { i += 2; break; } else i -= parametersDistance; - + + // TODO Move this to semantic analysis bool isFinalDefine = nextAre({TAG, DEFINE}); if (isFinalDefine || next.toktype == DEFINE) { const optional previousDefinition = parseTree.template findReferenceByName(current.toktext); @@ -183,6 +184,7 @@ namespace Parser { } catch (const NamedIdentifier::identifier_reserved_exception&) { parsingError(current, " is a reserved identifier", true); } + // TODO Move this to semantic analysis if (not parseTree.empty()) { const auto& last = parseTree.cend() - 1; const type_info& lastId = last->get()->getId(); diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 687606c..9b89690 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -15,8 +15,9 @@ #endif #include "../parsing/ParseComponents.hpp" +#include "../Tasking.hpp" -class Target { +class Target: protected Tasking { constexpr static const char* const interpolationString = "${"; constexpr static const char* const interpolationCloseString = "}"; protected: @@ -65,13 +66,9 @@ protected: } } else output << openCharacters << view << closeCharacters; } - 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 = 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) - typedef unordered_map unordered_task_map; typedef pair print_functions_pair; virtual unordered_task_map getTaskMap() = 0; virtual print_functions_pair printFunctions() = 0; @@ -124,7 +121,7 @@ protected: string separator; static constexpr const char* indentation = " "; public: - unordered_task_map getTaskMapInstance() { + unordered_task_map getTaskMapInstance() final { unordered_task_map fullMap = getTaskMap(); // Default / Shared tasks: fullMap.merge(unordered_task_map({ @@ -151,7 +148,7 @@ public: }; explicit Target(const bool& newLines): output(), newLines(newLines), separator() {}; Target() = delete; - virtual ~Target() = default; + ~Target() override = default; }; #include "implementations/Lua.hpp" diff --git a/src/main.cpp b/src/main.cpp index c32bf8e..4423e5f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ using namespace std; #include "headers/misc.hpp" #include "headers/arguments.hpp" +#include "headers/SemanticAnalysis.hpp" #include "headers/transpiler/Target.hpp" #include "headers/emscripten_compatibility.h" @@ -58,7 +59,9 @@ int main(int argc, char* argv[]) { unit_result resultingPair; try { resultingPair.first = Target::forName(target, newLines)->transpileWithTree( - parseString(text_provided ? string(currentArgument) + '\n' : getFileContent(file_path.string(/* NOTE: This string is expected to finish with a line ending */))) + SemanticAnalyser().analyseTree( + parseString(text_provided ? string(currentArgument) + '\n' : getFileContent(file_path.string(/* NOTE: This string is expected to finish with a line ending */))) + ) ); if (!text_provided or output_directory.has_value()) outputFileContent(