diff --git a/src/etc/lexer.cpp b/src/etc/lexer.cpp index ba41bb2..fa6389c 100644 --- a/src/etc/lexer.cpp +++ b/src/etc/lexer.cpp @@ -21,7 +21,7 @@ vector lex(const string& in) 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), string(1, current), lineNumber, i); + resVal.emplace_back(static_cast(current), string(1, current), lineNumber); [[likely]] case ' ': case '\t': case '\r': break; [[likely]] case '\n': ++lineNumber; break; default: { @@ -39,13 +39,13 @@ vector lex(const string& in) formedString += string(1, in[i]); } else { if (not isTypeString) --i; - resVal.emplace_back(type, formedString, lineNumber, i); + resVal.emplace_back(type, formedString, lineNumber); break; } } } case UNEXPECTED: break; - default: resVal.emplace_back(type, string(1, current), lineNumber, i); + default: resVal.emplace_back(type, string(1, current), lineNumber); } break; } diff --git a/src/headers/lex.hpp b/src/headers/lex.hpp index 6c43ecd..e485197 100644 --- a/src/headers/lex.hpp +++ b/src/headers/lex.hpp @@ -21,8 +21,8 @@ struct tok { }; const type toktype; const std::string toktext; - const std::pair linePosition; - tok(type Type, std::string_view Text, auto line, auto position): toktype(Type), toktext(Text), linePosition(line, position) {} + const unsigned long line = 0; + tok(type Type, std::string_view Text, auto line): toktype(Type), toktext(Text), line(line) {} friend std::ostream& operator<<(std::ostream& output, const tok& it) { return output << it.toktext; } }; std::vector lex(const std::string& in); diff --git a/src/headers/misc.hpp b/src/headers/misc.hpp index 0962dee..b723cd1 100644 --- a/src/headers/misc.hpp +++ b/src/headers/misc.hpp @@ -2,7 +2,7 @@ #define YERBACON_MISC_HPP string getFileContent(const string& file); -void outputFileContent(const string& file, string_view content); +void outputFileContent(const string& file, const string_view content); #include "lex.hpp" #include "parsing/Parser.hpp" diff --git a/src/headers/parsing/ParseComponents.hpp b/src/headers/parsing/ParseComponents.hpp index 32561ed..b76bbc1 100644 --- a/src/headers/parsing/ParseComponents.hpp +++ b/src/headers/parsing/ParseComponents.hpp @@ -13,9 +13,7 @@ using namespace std; #include "../lex.hpp" - #define IS(X) template::value>::type* = nullptr> -#define IS_PARSECOMPONENT IS(ParseComponent) struct ParseComponent { [[nodiscard]] const type_info& getId() const { return typeid(*this); } virtual ~ParseComponent() = default; @@ -49,10 +47,18 @@ namespace StandardComponents { } } +#define IS_PARSECOMPONENT IS(ParseComponent) class ParseTree { protected: mutable vector> subComponents; + using array_type = decltype(subComponents); + using iterator = array_type::iterator; + using const_iterator = array_type::const_iterator; public: + inline iterator begin() const noexcept { return subComponents.begin(); } + inline const_iterator cbegin() const noexcept { return subComponents.cbegin(); } + inline iterator end() const noexcept { return subComponents.end(); } + inline const_iterator cend() const noexcept { return subComponents.cend(); } IS_PARSECOMPONENT auto findById() const { return subComponents | views::filter([](unique_ptr& it) { @@ -61,15 +67,11 @@ public: return reinterpret_cast(it.get()); }); } - IS_PARSECOMPONENT - inline auto findReferencesById() const { - return findById() | views::transform([](T* it) { - return ref(static_cast(*it)); - }); - } IS(StandardComponents::NamedIdentifier) optional> findReferenceByName(const string& name) const { - auto identifiers = findReferencesById(); + auto identifiers = findById() | views::transform([](T* it) { + return ref(static_cast(*it)); + }); for (const auto& identifier: identifiers) { if (identifier.get().getId() == typeid(T) && identifier.get().name == name) { return make_optional(identifier); @@ -78,8 +80,6 @@ public: return optional>(); }; inline size_t getCompCount() const { return subComponents.size(); } - auto& getComponents() { return subComponents; } - const auto& getComponents() const { return subComponents; } IS_PARSECOMPONENT void add(const T& component) const { subComponents.emplace_back(new T(component)); diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp index 0347843..fec7ed1 100644 --- a/src/headers/transpiler/Target.hpp +++ b/src/headers/transpiler/Target.hpp @@ -5,18 +5,35 @@ #include #include #include +#include #include "../parsing/ParseComponents.hpp" -struct Target { +#define GETCOMP(X) virtual void get(const X& parseComponent, std::stringstream& output) {} +class Target { +protected: + GETCOMP(StandardComponents::Define); + GETCOMP(StandardComponents::Reference); + GETCOMP(StandardComponents::Class); +public: static shared_ptr forName(string_view name); + #define with(X) if (id == typeid(X)) { this->get(reinterpret_cast(*component), result); continue; } string transpileWithTree(const ParseTree& tree) { - return ""; // TODO Call other methods + stringstream result; + for (const unique_ptr& component: tree) { + const type_info& id = (*component).getId(); + with(StandardComponents::Define); + with(StandardComponents::Reference); + with(StandardComponents::Class); + } + return result.str(); }; + #undef with }; +#undef GETCOMP -string transpile(const ParseTree& tree, const string_view& language) { +inline string transpile(const ParseTree& tree, const string_view& language) { return Target::forName(language)->transpileWithTree(tree); } diff --git a/src/headers/transpiler/implementations/Js.hpp b/src/headers/transpiler/implementations/Js.hpp index ab0aa2e..6aa95a6 100644 --- a/src/headers/transpiler/implementations/Js.hpp +++ b/src/headers/transpiler/implementations/Js.hpp @@ -1,6 +1,10 @@ #ifndef JS_HPP #define JS_HPP JsTarget -struct JsTarget: Target {}; +struct JsTarget: Target { + void get(const StandardComponents::Define &parseComponent, std::stringstream &output) override { + output << (parseComponent.final ? "const " : "let ") << parseComponent.name << " = "; + } +}; #endif \ No newline at end of file diff --git a/src/headers/transpiler/implementations/Lua.hpp b/src/headers/transpiler/implementations/Lua.hpp index b059062..1700910 100644 --- a/src/headers/transpiler/implementations/Lua.hpp +++ b/src/headers/transpiler/implementations/Lua.hpp @@ -1,6 +1,13 @@ #ifndef LUA_HPP #define LUA_HPP LuaTarget -struct LuaTarget: Target {}; +struct LuaTarget: Target { + void get(const StandardComponents::Define &parseComponent, std::stringstream& output) override { + if (parseComponent.final) output << "local "; + output << parseComponent.name; + if (parseComponent.final) output << " "; // TODO Find an alternative to for lua >5.4 + output << " = "; + } +}; #endif \ No newline at end of file diff --git a/src/headers/transpiler/implementations/Py.hpp b/src/headers/transpiler/implementations/Py.hpp index a5d14ec..0fd874e 100644 --- a/src/headers/transpiler/implementations/Py.hpp +++ b/src/headers/transpiler/implementations/Py.hpp @@ -1,6 +1,10 @@ #ifndef PY_HPP #define PY_HPP PyTarget -struct PyTarget: Target {}; +struct PyTarget: Target { + void get(const StandardComponents::Define &parseComponent, std::stringstream &output) override { + output << parseComponent.name << " = "; + } +}; #endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index d7c63fd..fccc427 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,7 +31,7 @@ int main(int argc, char* argv[]) { else if (currentArg.ends_with(".ybcon")) files.push_back(currentArg); } const auto compile = [&target](string_view name) { - string transpiledString = transpile(parseString(getFileContent(name.data())), target); + const string transpiledString = transpile(parseString(getFileContent(name.data())), target); name.remove_suffix(6); string outputFile; (outputFile = name).append(target);