chore: a lot of file restructuring

This commit is contained in:
TopchetoEU 2023-01-26 10:06:39 +02:00
parent c8043fab9a
commit 2461ed1860
No known key found for this signature in database
GPG Key ID: 5ED5FFB2A3F5DB21
17 changed files with 199 additions and 381 deletions

View File

@ -4,29 +4,29 @@
#include <string>
namespace ppc::lang {
struct namespace_name_t: public std::vector<std::string> {
struct nmsp_t: public std::vector<std::string> {
using base = std::vector<std::string>;
int compare(const namespace_name_t &other) const;
int compare(const nmsp_t &other) const;
bool operator==(const namespace_name_t &other) const { return compare(other) == 0; }
bool operator!=(const namespace_name_t &other) const { return compare(other) != 0; }
bool operator<(const namespace_name_t &other) const { return compare(other) < 0; }
bool operator<=(const namespace_name_t &other) const { return compare(other) <= 0; }
bool operator>(const namespace_name_t &other) const { return compare(other) > 0; }
bool operator>=(const namespace_name_t &other) const { return compare(other) >= 0; }
bool operator==(const nmsp_t &other) const { return compare(other) == 0; }
bool operator!=(const nmsp_t &other) const { return compare(other) != 0; }
bool operator<(const nmsp_t &other) const { return compare(other) < 0; }
bool operator<=(const nmsp_t &other) const { return compare(other) <= 0; }
bool operator>(const nmsp_t &other) const { return compare(other) > 0; }
bool operator>=(const nmsp_t &other) const { return compare(other) >= 0; }
operator std::string() const { return to_string(); }
std::string to_string() const;
namespace_name_t() { }
namespace_name_t(std::initializer_list<std::string> segments): base(segments.begin(), segments.end()) { }
nmsp_t() { }
nmsp_t(std::initializer_list<std::string> segments): base(segments.begin(), segments.end()) { }
};
}
template <>
struct std::hash<ppc::lang::namespace_name_t> {
std::size_t operator()(const ppc::lang::namespace_name_t& k) const {
struct std::hash<ppc::lang::nmsp_t> {
std::size_t operator()(const ppc::lang::nmsp_t& k) const {
size_t res = 0;
for (auto &el : k) {
@ -41,55 +41,46 @@ struct std::hash<ppc::lang::namespace_name_t> {
#include "utils/location.hh"
namespace ppc::lang {
template <class T>
struct located_t: T {
template <class ParserT>
struct located_t: ParserT {
location_t location;
located_t(location_t loc, const T &val): T(val), location(loc) { }
located_t(const T &val): T(val), location(location_t::NONE) { }
located_t(location_t loc, const ParserT &val): ParserT(val), location(loc) { }
located_t(const ParserT &val): ParserT(val), location(location_t::NONE) { }
located_t() { }
};
template <class T>
struct slocated_t {
T value;
location_t location;
bool operator ==(const slocated_t<T> &other) {
return value == other.value && location == other.location;
}
bool operator !=(const slocated_t<T> &other) {
return !(*this == other);
}
slocated_t(location_t loc, const T &val): value(val), location(loc) { }
slocated_t(const T &val): value(val), location(location_t::NONE) { }
slocated_t() { }
};
struct loc_namespace_name_t: public std::vector<located_t<std::string>> {
struct loc_nmsp_t: public std::vector<located_t<std::string>> {
using base = std::vector<located_t<std::string>>;
int compare(const loc_namespace_name_t &other) const;
int compare(const loc_nmsp_t &other) const;
bool operator==(const loc_namespace_name_t &other) const { return compare(other) == 0; }
bool operator!=(const loc_namespace_name_t &other) const { return compare(other) != 0; }
bool operator<(const loc_namespace_name_t &other) const { return compare(other) < 0; }
bool operator<=(const loc_namespace_name_t &other) const { return compare(other) <= 0; }
bool operator>(const loc_namespace_name_t &other) const { return compare(other) > 0; }
bool operator>=(const loc_namespace_name_t &other) const { return compare(other) >= 0; }
bool operator==(const loc_nmsp_t &other) const { return compare(other) == 0; }
bool operator!=(const loc_nmsp_t &other) const { return compare(other) != 0; }
bool operator<(const loc_nmsp_t &other) const { return compare(other) < 0; }
bool operator<=(const loc_nmsp_t &other) const { return compare(other) <= 0; }
bool operator>(const loc_nmsp_t &other) const { return compare(other) > 0; }
bool operator>=(const loc_nmsp_t &other) const { return compare(other) >= 0; }
namespace_name_t strip_location() const;
nmsp_t strip_location() const;
operator nmsp_t() { return strip_location(); }
operator std::string() const { return to_string(); }
std::string to_string() const;
loc_namespace_name_t() { }
loc_namespace_name_t(std::initializer_list<located_t<std::string>> segments): base(segments.begin(), segments.end()) { }
loc_nmsp_t() { }
loc_nmsp_t(std::initializer_list<located_t<std::string>> segments): base(segments.begin(), segments.end()) { }
};
bool is_identifier_valid(messages::msg_stack_t &msg_stack, ppc::location_t location, const std::string &name);
inline bool is_identifier_valid(const std::string &name) {
messages::msg_stack_t ms;
return is_identifier_valid(ms, { }, name);
template <class SetT>
bool resolve_name(const SetT &defs, const nmsp_t &src, const nmsp_t &target) {
if (src == target) return true;
for (auto &it : defs) {
nmsp_t val = (nmsp_t)it;
val.insert(val.end(), src.begin(), src.end());
if (val == target) return true;
}
}
}

View File

@ -1,162 +0,0 @@
#include <set>
#include <unordered_map>
#include "lang/common.hh"
namespace ppc::lang {
struct type_t {
namespace_name_t name;
size_t ptr_n;
};
struct statement_t {
private:
enum kind_t {
CALL,
STACK,
RETURN,
} kind;
union val_t {
namespace_name_t *call;
int64_t stack;
} val;
~statement_t();
statement_t(kind_t kind, val_t val) {
this->kind = kind;
this->val = val;
}
statement_t(kind_t kind) {
this->kind = kind;
}
public:
bool is_call() const { return kind == CALL; }
bool is_stack() const { return kind == STACK; }
bool is_return() const { return kind == RETURN; }
auto &call() const {
if (!is_call()) throw (std::string)"Statement is not a call.";
return val.call;
}
auto stack() const {
if (!is_call()) throw (std::string)"Statement is not a stack.";
return val.stack;
}
static statement_t call(const namespace_name_t &func);
static statement_t stack(int64_t stack);
static statement_t ret();
};
struct field_t {
type_t type;
};
struct struct_t {
std::unordered_map<std::string, type_t> fields;
};
struct function_t {
std::unordered_map<std::string, type_t> args;
type_t type;
std::string get_signature();
};
struct definition_t {
private:
enum {
FUNCTION,
STRUCT,
FIELD,
} kind;
union {
field_t *field;
struct_t *str;
function_t *func;
} val;
public:
~definition_t();
definition_t(field_t val);
definition_t(struct_t val);
definition_t(function_t val);
definition_t(const definition_t &other);
bool is_func() const { return kind == FUNCTION; }
bool is_struct() const { return kind == STRUCT; }
bool is_field() const { return kind == FIELD; }
function_t &get_func();
struct_t &get_struct();
field_t &get_field();
const function_t &get_func() const { return ((definition_t&)*this).get_func(); }
const struct_t &get_struct() const { return ((definition_t&)*this).get_struct(); }
const field_t &get_field() const { return ((definition_t&)*this).get_field(); }
};
struct module_t {
private:
using fields_t = std::unordered_map<namespace_name_t, field_t>;
using structs_t = std::unordered_map<namespace_name_t, struct_t>;
using funcs_t = std::unordered_map<namespace_name_t, function_t>;
struct resolve_res_t {
namespace_name_t name;
definition_t def;
};
public:
fields_t fields;
structs_t structs;
funcs_t funcs;
const definition_t &def(namespace_name_t name);
void add_def(namespace_name_t name, const definition_t &def) {
if (def.is_field()) fields.emplace(name, def.get_field());
if (def.is_func()) funcs.emplace(name, def.get_func());
if (def.is_struct()) structs.emplace(name, def.get_struct());
}
bool exists(namespace_name_t name) {
return
fields.find(name) != fields.end() ||
structs.find(name) != structs.end() ||
funcs.find(name) != funcs.end();
}
};
template <class T>
struct resolve_res_t {
namespace_name_t name;
T value;
};
bool resolve_name(
const std::vector<namespace_name_t> &names, const std::set<namespace_name_t> &imports,
const namespace_name_t &name, namespace_name_t &res
);
template <class MapT>
bool resolve_name_map(
const MapT &defs, const std::set<namespace_name_t> &imports,
const namespace_name_t &name, namespace_name_t &res
) {
std::vector<namespace_name_t> names;
for (auto &it : defs) {
const namespace_name_t &val = it.first;
names.push_back(val);
}
return resolve_name(names, imports, name, res);
}
template <class MapT>
bool resolve(
const MapT &defs, const std::set<namespace_name_t> &imports,
const namespace_name_t &name, typename MapT::iterator &res
) {
if (resolve_name_map(defs, imports, name, res.name)) {
res.value = defs.find(res.name)->second;
return true;
}
return false;
}
}

View File

@ -20,20 +20,27 @@ namespace ppc::tree::constr {
struct ast_ctx_t;
struct glob_t {
loc_namespace_name_t nmsp;
std::vector<loc_namespace_name_t> imports;
loc_nmsp_t nmsp;
std::vector<loc_nmsp_t> imports;
#ifdef PROFILE_debug
void print() const {
std::cout << "Namespace: " << nmsp.to_string() << "\n";
std::cout << "Imports:\n";
for (auto &imp : imports) {
std::cout << " - " << imp.to_string() << "\n";
}
}
#endif
};
struct exp_t: public named_t {
};
template <class T, class GlobT = glob_t>
template <class ParserT, class GlobT = glob_t>
class parser_t {
public:
virtual bool operator()(ast_ctx_t &ctx, size_t &res_i, T &out) const = 0;
virtual bool simplify(ast_ctx_t &ctx, GlobT &glob, T &val) const = 0;
#ifdef PROFILE_debug
virtual void print(const T &val) {
std::cout << "(unknown)";
}
#endif
virtual bool operator()(ast_ctx_t &ctx, size_t &res_i, ParserT &out) const = 0;
virtual bool simplify(ast_ctx_t &ctx, GlobT &glob, ParserT &val) const = 0;
};
@ -41,50 +48,24 @@ namespace ppc::tree::constr {
public:
msg_stack_t &messages;
std::vector<token_t> &tokens;
loc_namespace_name_t nmsp;
loc_nmsp_t nmsp;
ast_ctx_t &operator=(const ast_ctx_t &other) = delete;
template <class T>
bool parse(const parser_t<T> &parser, size_t &i, T &out) {
return parser(*this, i, out);
}
template <class T>
static T parse(const parser_t<T> &glob, msg_stack_t &messages, std::vector<token_t> &tokens) {
ast_ctx_t ctx(messages, tokens);
T res;
size_t i = 0;
if (!ctx.parse(glob, i, res)) throw message_t::error("Failed to compile.");
return res;
}
ast_ctx_t(msg_stack_t &messages, std::vector<token_t> &tokens);
ast_ctx_t(msg_stack_t &messages, std::vector<token_t> &tokens):
messages(messages), tokens(tokens) { }
};
template <class T>
class inspoint_t {
private:
std::map<lang::namespace_name_t, std::string> named_parsers;
std::set<std::string> unnamed_parsers;
std::map<std::string, T *> parsers;
bool parse_identifier(ast_ctx_t &ctx, size_t &res_i, located_t<std::string> &out);
bool parse_nmsp(ast_ctx_t &ctx, size_t &res_i, loc_nmsp_t &out);
bool parse_nmsp_id(ast_ctx_t &ctx, size_t &res_i, nmsp_t nmsp);
class exp_parser_t {
public:
inspoint_t &replace(const std::string &name, const T &parser) {
auto it = parsers.find(name);
if (parsers.find(name) == parsers.end()) {
throw "The parser '" + name + "' isn't in the group.";
}
it->second = parser;
return *this;
}
inspoint_t &add(const std::string &name, const T &parser);
inspoint_t &add(const std::string &name, const lang::namespace_name_t &identifier, const T &parser);
bool operator()(ast_ctx_t &ctx, size_t &i, data::map_t &out) const;
bool operator()(ast_ctx_t &ctx, glob_t &out) const;
};
class glob_parser_t {
public:
bool operator()(ast_ctx_t &ctx, glob_t &out) const;
};
// parser_func_t parse_glob, parse_nmsp, parse_identifier, parse_type, parse_exp, parse_stat_exp;

View File

@ -1,9 +0,0 @@
#include "treeifier/constr.hh"
namespace ppc::tree::constr {
class glob_parser_t: public parser_t<glob_t> {
public:
bool operator()(ast_ctx_t &ctx, size_t &res_i, glob_t &out) const override;
bool simplify(ast_ctx_t &ctx, glob_t &glob, glob_t &val) const override { return false; }
};
}

View File

@ -7,7 +7,7 @@ using namespace ppc::tree;
using namespace ppc::tree::constr;
namespace ppc::tree::constr {
struct parse_helper_t {
struct helper_t {
private:
ast_ctx_t &ctx;
size_t &res_i;
@ -104,28 +104,25 @@ namespace ppc::tree::constr {
throw_ended(reason);
}
template <class T>
bool parse(const parser_t<T> &parser, T &out) {
return ctx.parse(parser, i, out);
template <class ParserT, class ...ArgsT>
bool parse(const ParserT &parser, ArgsT &...args) {
return parser(ctx, i, args...);
}
template <class T>
void force_parse(const parser_t<T> &parser, std::string message, T &out) {
template <class ParserT, class ...ArgsT>
void force_parse(const ParserT &parser, std::string message, ArgsT &...args) {
throw_ended(message);
bool success;
try {
success = parse(parser, out);
if (!parser(ctx, i, args...)) err(message);
}
catch (const message_t &msg) {
ctx.messages.push(msg);
success = false;
err(message);
}
if (!success) err(message);
}
parse_helper_t(ast_ctx_t &ctx, size_t &i): ctx(ctx), res_i(i) {
helper_t(ast_ctx_t &ctx, size_t &i): ctx(ctx), res_i(i) {
this->i = i;
}
};

View File

@ -1,8 +0,0 @@
#include "treeifier/constr.hh"
namespace ppc::tree::constr {
struct identifier_parser_t: public parser_t<located_t<std::string>> {
bool operator()(ast_ctx_t &ctx, size_t &res_i, located_t<std::string> &out) const override;
bool simplify(ast_ctx_t &ctx, glob_t &glob, located_t<std::string> &val) const override { return false; }
};
}

View File

@ -0,0 +1,51 @@
#include "treeifier/constr.hh"
#include "treeifier/constr/helper.hh"
#include "treeifier/constr/nmsp.hh"
namespace ppc::tree::constr {
struct named_t {
virtual std::string name() = 0;
virtual ~named_t() = default;
#ifdef PROFILE_debug
virtual void print() { std::cout << "(" << name() << ")"; }
#endif
};
template <class ParserT, class ResT>
class inspoint_t {
private:
std::map<std::string, std::unique_ptr<ParserT>> parsers;
public:
inspoint_t<ParserT, ResT> &add(const ParserT &parser, bool replace = false) {
const std::string &name = parser.name();
auto it = parsers.find(name);
if (it != parsers.end()) {
if (!replace) throw "The parser '" + name + "' is already in the group.";
it->second = std::make_unique(parser);
}
else {
parsers.emplace(name, std::make_unique(parser));
}
return *this;
}
bool operator()(ast_ctx_t &ctx, size_t &i, std::unique_ptr<ResT> &out) const override {
helper_t h(ctx, i);
if (h.ended()) return false;
for (std::pair<std::string, std::unique_ptr<ParserT>> &pair : parsers) {
ResT res;
if (pair.second(ctx, i, res)) {
out = std::make_unique<ResT>(res);
return true;
}
}
return false;
}
};
}

View File

@ -1,9 +0,0 @@
#include "treeifier/constr/identifier.hh"
#include "treeifier/constr.hh"
namespace ppc::tree::constr {
struct nmsp_parser_t: public parser_t<loc_namespace_name_t> {
bool operator()(ast_ctx_t &ctx, size_t &res_i, loc_namespace_name_t &out) const override;
bool simplify(ast_ctx_t &ctx, glob_t &glob, loc_namespace_name_t &val) const override { return false; }
};
}

View File

@ -7,8 +7,8 @@
#endif
namespace ppc::threading {
template <class T>
using thread_func_t = int (THREAD *)(T *data);
template <class ParserT>
using thread_func_t = int (THREAD *)(ParserT *data);
using empty_thread_func_t = int (THREAD *)();
struct thread_t {
@ -20,13 +20,13 @@ namespace ppc::threading {
int join() const;
thread_t(void *handle) { this->handle = handle; }
template <class T>
inline static thread_t start(thread_func_t<T> func, const T &args) {
T _args = args;
template <class ParserT>
inline static thread_t start(thread_func_t<ParserT> func, const ParserT &args) {
ParserT _args = args;
return start_impl((void*)func, &_args);
}
template <class T>
inline static thread_t start(thread_func_t<T> func, T &args) {
template <class ParserT>
inline static thread_t start(thread_func_t<ParserT> func, ParserT &args) {
return start_impl((void*)func, &args);
}
inline static thread_t start(empty_thread_func_t func) {

View File

@ -2,7 +2,7 @@
#include <sstream>
namespace ppc::lang {
std::string loc_namespace_name_t::to_string() const {
std::string loc_nmsp_t::to_string() const {
std::stringstream res;
for (size_t i = 0; i < size(); i++) {
@ -12,7 +12,7 @@ namespace ppc::lang {
return res.str();
}
std::string namespace_name_t::to_string() const {
std::string nmsp_t::to_string() const {
std::stringstream res;
for (size_t i = 0; i < size(); i++) {
@ -23,7 +23,7 @@ namespace ppc::lang {
return res.str();
}
int namespace_name_t::compare(const namespace_name_t &b) const {
int nmsp_t::compare(const nmsp_t &b) const {
const auto &a = *this;
for (size_t i = 0; i < a.size() && i < b.size(); i++) {
auto cmp = a[i].compare(b[i]);
@ -34,7 +34,7 @@ namespace ppc::lang {
else if (a.size() == b.size()) return 0;
else return -1;
}
int loc_namespace_name_t::compare(const loc_namespace_name_t &b) const {
int loc_nmsp_t::compare(const loc_nmsp_t &b) const {
const auto &a = *this;
for (size_t i = 0; i < a.size() && i < b.size(); i++) {
auto cmp = a[i].compare(b[i]);
@ -46,8 +46,8 @@ namespace ppc::lang {
else return -1;
}
namespace_name_t loc_namespace_name_t::strip_location() const {
namespace_name_t res;
nmsp_t loc_nmsp_t::strip_location() const {
nmsp_t res;
for (const auto &el : *this) {
res.push_back(el);

View File

@ -59,7 +59,7 @@ field_t &definition_t::get_field() {
}
statement_t statement_t::call(const namespace_name_t &func) {
statement_t statement_t::call(const nmsp_t &func) {
return { CALL, { .call = new auto(func) } };
}
statement_t statement_t::stack(int64_t stack) {
@ -68,26 +68,3 @@ statement_t statement_t::stack(int64_t stack) {
statement_t statement_t::ret() {
return { RETURN };
}
bool ppc::lang::resolve_name(
const std::vector<namespace_name_t> &names, const std::set<namespace_name_t> &imports,
const namespace_name_t &name, namespace_name_t &res
) {
for (auto &curr : names) {
if (curr == name) {
res = curr;
return true;
}
}
for (auto &import : imports) {
auto new_name = name;
new_name.insert(new_name.begin(), import.begin(), import.end());
for (auto &curr : names) {
if (curr == new_name) {
res = curr;
return true;
}
}
}
return false;
}

View File

@ -1,2 +1,2 @@
main
utils, treeifier
utils, treeifier, lang

View File

@ -164,7 +164,9 @@ int main(int argc, const char *argv[]) {
if (!f.is_open()) throw message_t::error("The file doesn't exist.", { file });
auto tokens = token_t::parse_many(msg_stack, lex::token_t::parse_file(msg_stack, file, f));
auto ast = ast_ctx_t::parse(constr::glob_parser_t(), msg_stack, tokens);
// std::cout << data::json::stringify(ast) << std::endl;
#ifdef PROFILE_debug
ast.print();
#endif
}
catch (const messages::message_t &msg) {
msg_stack.push(msg);

48
src/treeifier/constr.cc Normal file
View File

@ -0,0 +1,48 @@
#include "treeifier/constr.hh"
#include "treeifier/constr/helper.hh"
#include "lang/common.hh"
using namespace ppc::tree::constr;
bool ppc::tree::constr::parse_identifier(ast_ctx_t &ctx, size_t &res_i, located_t<std::string> &out) {
helper_t h(ctx, res_i);
if (h.ended()) return false;
if (h.curr().is_identifier()) {
out = located_t<std::string>(h.loc(), h.curr().identifier());
return h.submit();
}
else return false;
}
bool ppc::tree::constr::parse_nmsp(ast_ctx_t &ctx, size_t &res_i, loc_nmsp_t &out) {
helper_t h(ctx, res_i);
if (h.ended()) return false;
out.clear();
located_t<std::string> val;
if (!h.parse(parse_identifier, val)) return false;
else out.push_back(val);
while (true) {
if (h.ended()) break;
if (!h.curr().is_operator(operator_t::DOUBLE_COLON)) break;
h.advance("Expected an identifier.");
h.force_parse(parse_identifier, "Expected an identifier.", val);
out.push_back(val);
}
return h.submit(false);
}
bool ppc::tree::constr::parse_nmsp_id(ast_ctx_t &ctx, size_t &res_i, glob_t glob, nmsp_t nmsp) {
helper_t h(ctx, res_i);
nmsp_t src;
if (!h.parse(parse_nmsp, src)) return false;
if (resolve_name(glob.imports, src, nmsp)) return h.submit(false);
else return false;
}

View File

@ -4,15 +4,16 @@
using namespace ppc::tree::constr;
bool ppc::tree::constr::glob_parser_t::operator()(ast_ctx_t &ctx, size_t &res_i, glob_t &out) const {
parse_helper_t h(ctx, res_i);
bool ppc::tree::constr::glob_parser_t::operator()(ast_ctx_t &ctx, glob_t &out) const {
size_t res_i = 0;
helper_t h(ctx, res_i);
out = {};
if (h.ended()) return h.submit(false);
if (h.curr().is_identifier("namespace")) {
h.advance("Expected a namespace");
h.force_parse(nmsp_parser_t(), "Expected a namespace.", out.nmsp);
h.force_parse(parse_nmsp, "Expected a namespace.", out.nmsp);
if (!h.curr().is_operator(operator_t::SEMICOLON)) {
ctx.messages.push(message_t::error("Expected a semicolon.", h.loc(1)));
@ -22,7 +23,7 @@ bool ppc::tree::constr::glob_parser_t::operator()(ast_ctx_t &ctx, size_t &res_i,
}
while (h.curr().is_identifier("import")) {
loc_namespace_name_t res;
loc_nmsp_t res;
h.advance("Expected a namespace");
h.force_parse(nmsp_parser_t(), "Expected a namespace.", res);

View File

@ -1,16 +0,0 @@
#include "treeifier/constr/helper.hh"
#include "treeifier/constr/identifier.hh"
using namespace ppc::tree::constr;
bool identifier_parser_t::operator()(ast_ctx_t& ctx, size_t& res_i, located_t<std::string>& out) const {
parse_helper_t h(ctx, res_i);
if (h.ended()) return false;
if (h.curr().is_identifier()) {
out = located_t<std::string>(h.loc(), h.curr().identifier());
return h.submit();
}
else return false;
}

View File

@ -1,26 +0,0 @@
#include "treeifier/constr/helper.hh"
#include "treeifier/constr/nmsp.hh"
using namespace ppc::tree::constr;
bool nmsp_parser_t::operator()(ast_ctx_t &ctx, size_t &res_i, loc_namespace_name_t &out) const {
parse_helper_t h(ctx, res_i);
if (h.ended()) return false;
out.clear();
located_t<std::string> val;
if (!h.parse(identifier_parser_t(), val)) return false;
else out.push_back(val);
while (true) {
if (h.ended()) break;
if (!h.curr().is_operator(operator_t::DOUBLE_COLON)) break;
h.advance("Expected an identifier.");
h.force_parse(identifier_parser_t(), "Expected an identifier.", val);
out.push_back(val);
}
return h.submit(false);
}