Begin adding transpilation of basic elements
This commit is contained in:
parent
57f8f251bc
commit
664a6a92be
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue