Begin adding transpilation of basic elements

This commit is contained in:
Username404 2021-08-22 23:49:05 +02:00
parent 57f8f251bc
commit 664a6a92be
Signed by: Username404-59
GPG Key ID: 7AB361FBB257A5D1
9 changed files with 56 additions and 24 deletions

View File

@ -21,7 +21,7 @@ vector<tok> lex(const string& in)
case LBRACE: case RBRACE: case LBRACKET: case RBRACKET: case LBRACE: case RBRACE: case LBRACKET: case RBRACKET:
case PLUS: case HYPHEN: case LCOMP: case RCOMP: case PLUS: case HYPHEN: case LCOMP: case RCOMP:
case DOT: case DOLLAR_SIGN: case SQUOTE: case DOT: case DOLLAR_SIGN: case SQUOTE:
resVal.emplace_back(static_cast<tok::type>(current), string(1, current), lineNumber, i); resVal.emplace_back(static_cast<tok::type>(current), string(1, current), lineNumber);
[[likely]] case ' ': case '\t': case '\r': break; [[likely]] case ' ': case '\t': case '\r': break;
[[likely]] case '\n': ++lineNumber; break; [[likely]] case '\n': ++lineNumber; break;
default: { default: {
@ -39,13 +39,13 @@ vector<tok> lex(const string& in)
formedString += string(1, in[i]); formedString += string(1, in[i]);
} else { } else {
if (not isTypeString) --i; if (not isTypeString) --i;
resVal.emplace_back(type, formedString, lineNumber, i); resVal.emplace_back(type, formedString, lineNumber);
break; break;
} }
} }
} }
case UNEXPECTED: break; case UNEXPECTED: break;
default: resVal.emplace_back(type, string(1, current), lineNumber, i); default: resVal.emplace_back(type, string(1, current), lineNumber);
} }
break; break;
} }

View File

@ -21,8 +21,8 @@ struct tok {
}; };
const type toktype; const type toktype;
const std::string toktext; const std::string toktext;
const std::pair<unsigned long, unsigned int> linePosition; const unsigned long line = 0;
tok(type Type, std::string_view Text, auto line, auto position): toktype(Type), toktext(Text), linePosition(line, position) {} 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; } friend std::ostream& operator<<(std::ostream& output, const tok& it) { return output << it.toktext; }
}; };
std::vector<tok> lex(const std::string& in); std::vector<tok> lex(const std::string& in);

View File

@ -2,7 +2,7 @@
#define YERBACON_MISC_HPP #define YERBACON_MISC_HPP
string getFileContent(const string& file); 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 "lex.hpp"
#include "parsing/Parser.hpp" #include "parsing/Parser.hpp"

View File

@ -13,9 +13,7 @@ using namespace std;
#include "../lex.hpp" #include "../lex.hpp"
#define IS(X) template<typename T, typename std::enable_if<std::is_base_of<X, T>::value>::type* = nullptr> #define IS(X) template<typename T, typename std::enable_if<std::is_base_of<X, T>::value>::type* = nullptr>
#define IS_PARSECOMPONENT IS(ParseComponent)
struct ParseComponent { struct ParseComponent {
[[nodiscard]] const type_info& getId() const { return typeid(*this); } [[nodiscard]] const type_info& getId() const { return typeid(*this); }
virtual ~ParseComponent() = default; virtual ~ParseComponent() = default;
@ -49,10 +47,18 @@ namespace StandardComponents {
} }
} }
#define IS_PARSECOMPONENT IS(ParseComponent)
class ParseTree { class ParseTree {
protected: protected:
mutable vector<unique_ptr<ParseComponent>> subComponents; mutable vector<unique_ptr<ParseComponent>> subComponents;
using array_type = decltype(subComponents);
using iterator = array_type::iterator;
using const_iterator = array_type::const_iterator;
public: 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 IS_PARSECOMPONENT
auto findById() const { auto findById() const {
return subComponents | views::filter([](unique_ptr<ParseComponent>& it) { return subComponents | views::filter([](unique_ptr<ParseComponent>& it) {
@ -61,15 +67,11 @@ public:
return reinterpret_cast<T*>(it.get()); return reinterpret_cast<T*>(it.get());
}); });
} }
IS_PARSECOMPONENT
inline auto findReferencesById() const {
return findById<T>() | views::transform([](T* it) {
return ref(static_cast<T&>(*it));
});
}
IS(StandardComponents::NamedIdentifier) IS(StandardComponents::NamedIdentifier)
optional<reference_wrapper<T>> findReferenceByName(const string& name) const { optional<reference_wrapper<T>> findReferenceByName(const string& name) const {
auto identifiers = findReferencesById<T>(); auto identifiers = findById<T>() | views::transform([](T* it) {
return ref(static_cast<T&>(*it));
});
for (const auto& identifier: identifiers) { for (const auto& identifier: identifiers) {
if (identifier.get().getId() == typeid(T) && identifier.get().name == name) { if (identifier.get().getId() == typeid(T) && identifier.get().name == name) {
return make_optional(identifier); return make_optional(identifier);
@ -78,8 +80,6 @@ public:
return optional<reference_wrapper<T>>(); return optional<reference_wrapper<T>>();
}; };
inline size_t getCompCount() const { return subComponents.size(); } inline size_t getCompCount() const { return subComponents.size(); }
auto& getComponents() { return subComponents; }
const auto& getComponents() const { return subComponents; }
IS_PARSECOMPONENT IS_PARSECOMPONENT
void add(const T& component) const { void add(const T& component) const {
subComponents.emplace_back(new T(component)); subComponents.emplace_back(new T(component));

View File

@ -5,18 +5,35 @@
#include <string_view> #include <string_view>
#include <iostream> #include <iostream>
#include <memory> #include <memory>
#include <sstream>
#include "../parsing/ParseComponents.hpp" #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<Target> forName(string_view name); static shared_ptr<Target> forName(string_view name);
#define with(X) if (id == typeid(X)) { this->get(reinterpret_cast<X&>(*component), result); continue; }
string transpileWithTree(const ParseTree& tree) { string transpileWithTree(const ParseTree& tree) {
return ""; // TODO Call other methods stringstream result;
for (const unique_ptr<ParseComponent>& 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); return Target::forName(language)->transpileWithTree(tree);
} }

View File

@ -1,6 +1,10 @@
#ifndef JS_HPP #ifndef JS_HPP
#define JS_HPP JsTarget #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 #endif

View File

@ -1,6 +1,13 @@
#ifndef LUA_HPP #ifndef LUA_HPP
#define LUA_HPP LuaTarget #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 << " <const>"; // TODO Find an alternative to <const> for lua >5.4
output << " = ";
}
};
#endif #endif

View File

@ -1,6 +1,10 @@
#ifndef PY_HPP #ifndef PY_HPP
#define PY_HPP PyTarget #define PY_HPP PyTarget
struct PyTarget: Target {}; struct PyTarget: Target {
void get(const StandardComponents::Define &parseComponent, std::stringstream &output) override {
output << parseComponent.name << " = ";
}
};
#endif #endif

View File

@ -31,7 +31,7 @@ int main(int argc, char* argv[]) {
else if (currentArg.ends_with(".ybcon")) files.push_back(currentArg); else if (currentArg.ends_with(".ybcon")) files.push_back(currentArg);
} }
const auto compile = [&target](string_view name) { 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); name.remove_suffix(6);
string outputFile; string outputFile;
(outputFile = name).append(target); (outputFile = name).append(target);