AST reprogramming #5
@ -4,29 +4,29 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace ppc::lang {
|
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>;
|
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 nmsp_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 namespace_name_t &other) const { return compare(other) < 0; }
|
bool operator<(const nmsp_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 namespace_name_t &other) const { return compare(other) > 0; }
|
bool operator>(const nmsp_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; }
|
||||||
|
|
||||||
operator std::string() const { return to_string(); }
|
operator std::string() const { return to_string(); }
|
||||||
std::string to_string() const;
|
std::string to_string() const;
|
||||||
|
|
||||||
namespace_name_t() { }
|
nmsp_t() { }
|
||||||
namespace_name_t(std::initializer_list<std::string> segments): base(segments.begin(), segments.end()) { }
|
nmsp_t(std::initializer_list<std::string> segments): base(segments.begin(), segments.end()) { }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct std::hash<ppc::lang::namespace_name_t> {
|
struct std::hash<ppc::lang::nmsp_t> {
|
||||||
std::size_t operator()(const ppc::lang::namespace_name_t& k) const {
|
std::size_t operator()(const ppc::lang::nmsp_t& k) const {
|
||||||
size_t res = 0;
|
size_t res = 0;
|
||||||
|
|
||||||
for (auto &el : k) {
|
for (auto &el : k) {
|
||||||
@ -41,55 +41,46 @@ struct std::hash<ppc::lang::namespace_name_t> {
|
|||||||
#include "utils/location.hh"
|
#include "utils/location.hh"
|
||||||
|
|
||||||
namespace ppc::lang {
|
namespace ppc::lang {
|
||||||
template <class T>
|
template <class ParserT>
|
||||||
struct located_t: T {
|
struct located_t: ParserT {
|
||||||
location_t location;
|
location_t location;
|
||||||
|
|
||||||
located_t(location_t loc, const T &val): T(val), location(loc) { }
|
located_t(location_t loc, const ParserT &val): ParserT(val), location(loc) { }
|
||||||
located_t(const T &val): T(val), location(location_t::NONE) { }
|
located_t(const ParserT &val): ParserT(val), location(location_t::NONE) { }
|
||||||
located_t() { }
|
located_t() { }
|
||||||
};
|
};
|
||||||
template <class T>
|
|
||||||
struct slocated_t {
|
|
||||||
T value;
|
|
||||||
location_t location;
|
|
||||||
|
|
||||||
bool operator ==(const slocated_t<T> &other) {
|
struct loc_nmsp_t: public std::vector<located_t<std::string>> {
|
||||||
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>> {
|
|
||||||
using base = 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_nmsp_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_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_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_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_namespace_name_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(); }
|
operator std::string() const { return to_string(); }
|
||||||
std::string to_string() const;
|
std::string to_string() const;
|
||||||
|
|
||||||
loc_namespace_name_t() { }
|
loc_nmsp_t() { }
|
||||||
loc_namespace_name_t(std::initializer_list<located_t<std::string>> segments): base(segments.begin(), segments.end()) { }
|
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);
|
template <class SetT>
|
||||||
inline bool is_identifier_valid(const std::string &name) {
|
bool resolve_name(const SetT &defs, const nmsp_t &src, const nmsp_t &target) {
|
||||||
messages::msg_stack_t ms;
|
if (src == target) return true;
|
||||||
return is_identifier_valid(ms, { }, name);
|
|
||||||
|
for (auto &it : defs) {
|
||||||
|
nmsp_t val = (nmsp_t)it;
|
||||||
|
val.insert(val.end(), src.begin(), src.end());
|
||||||
|
|
||||||
|
if (val == target) return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -20,20 +20,27 @@ namespace ppc::tree::constr {
|
|||||||
struct ast_ctx_t;
|
struct ast_ctx_t;
|
||||||
|
|
||||||
struct glob_t {
|
struct glob_t {
|
||||||
loc_namespace_name_t nmsp;
|
loc_nmsp_t nmsp;
|
||||||
std::vector<loc_namespace_name_t> imports;
|
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 {
|
class parser_t {
|
||||||
public:
|
public:
|
||||||
virtual bool operator()(ast_ctx_t &ctx, size_t &res_i, T &out) const = 0;
|
virtual bool operator()(ast_ctx_t &ctx, size_t &res_i, ParserT &out) const = 0;
|
||||||
virtual bool simplify(ast_ctx_t &ctx, GlobT &glob, T &val) const = 0;
|
virtual bool simplify(ast_ctx_t &ctx, GlobT &glob, ParserT &val) const = 0;
|
||||||
#ifdef PROFILE_debug
|
|
||||||
virtual void print(const T &val) {
|
|
||||||
std::cout << "(unknown)";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -41,50 +48,24 @@ namespace ppc::tree::constr {
|
|||||||
public:
|
public:
|
||||||
msg_stack_t &messages;
|
msg_stack_t &messages;
|
||||||
std::vector<token_t> &tokens;
|
std::vector<token_t> &tokens;
|
||||||
loc_namespace_name_t nmsp;
|
loc_nmsp_t nmsp;
|
||||||
|
|
||||||
ast_ctx_t &operator=(const ast_ctx_t &other) = delete;
|
ast_ctx_t &operator=(const ast_ctx_t &other) = delete;
|
||||||
|
ast_ctx_t(msg_stack_t &messages, std::vector<token_t> &tokens):
|
||||||
template <class T>
|
messages(messages), tokens(tokens) { }
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
bool parse_identifier(ast_ctx_t &ctx, size_t &res_i, located_t<std::string> &out);
|
||||||
class inspoint_t {
|
bool parse_nmsp(ast_ctx_t &ctx, size_t &res_i, loc_nmsp_t &out);
|
||||||
private:
|
bool parse_nmsp_id(ast_ctx_t &ctx, size_t &res_i, nmsp_t nmsp);
|
||||||
std::map<lang::namespace_name_t, std::string> named_parsers;
|
|
||||||
std::set<std::string> unnamed_parsers;
|
class exp_parser_t {
|
||||||
std::map<std::string, T *> parsers;
|
|
||||||
public:
|
public:
|
||||||
inspoint_t &replace(const std::string &name, const T &parser) {
|
bool operator()(ast_ctx_t &ctx, glob_t &out) const;
|
||||||
auto it = parsers.find(name);
|
};
|
||||||
|
class glob_parser_t {
|
||||||
if (parsers.find(name) == parsers.end()) {
|
public:
|
||||||
throw "The parser '" + name + "' isn't in the group.";
|
bool operator()(ast_ctx_t &ctx, glob_t &out) const;
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// parser_func_t parse_glob, parse_nmsp, parse_identifier, parse_type, parse_exp, parse_stat_exp;
|
// parser_func_t parse_glob, parse_nmsp, parse_identifier, parse_type, parse_exp, parse_stat_exp;
|
||||||
|
@ -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; }
|
|
||||||
};
|
|
||||||
}
|
|
@ -7,7 +7,7 @@ using namespace ppc::tree;
|
|||||||
using namespace ppc::tree::constr;
|
using namespace ppc::tree::constr;
|
||||||
|
|
||||||
namespace ppc::tree::constr {
|
namespace ppc::tree::constr {
|
||||||
struct parse_helper_t {
|
struct helper_t {
|
||||||
private:
|
private:
|
||||||
ast_ctx_t &ctx;
|
ast_ctx_t &ctx;
|
||||||
size_t &res_i;
|
size_t &res_i;
|
||||||
@ -104,28 +104,25 @@ namespace ppc::tree::constr {
|
|||||||
throw_ended(reason);
|
throw_ended(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class ParserT, class ...ArgsT>
|
||||||
bool parse(const parser_t<T> &parser, T &out) {
|
bool parse(const ParserT &parser, ArgsT &...args) {
|
||||||
return ctx.parse(parser, i, out);
|
return parser(ctx, i, args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class ParserT, class ...ArgsT>
|
||||||
void force_parse(const parser_t<T> &parser, std::string message, T &out) {
|
void force_parse(const ParserT &parser, std::string message, ArgsT &...args) {
|
||||||
throw_ended(message);
|
throw_ended(message);
|
||||||
bool success;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
success = parse(parser, out);
|
if (!parser(ctx, i, args...)) err(message);
|
||||||
}
|
}
|
||||||
catch (const message_t &msg) {
|
catch (const message_t &msg) {
|
||||||
ctx.messages.push(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;
|
this->i = i;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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; }
|
|
||||||
};
|
|
||||||
}
|
|
51
include/treeifier/constr/inspoint.hh
Normal file
51
include/treeifier/constr/inspoint.hh
Normal 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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -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; }
|
|
||||||
};
|
|
||||||
}
|
|
@ -7,8 +7,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ppc::threading {
|
namespace ppc::threading {
|
||||||
template <class T>
|
template <class ParserT>
|
||||||
using thread_func_t = int (THREAD *)(T *data);
|
using thread_func_t = int (THREAD *)(ParserT *data);
|
||||||
using empty_thread_func_t = int (THREAD *)();
|
using empty_thread_func_t = int (THREAD *)();
|
||||||
|
|
||||||
struct thread_t {
|
struct thread_t {
|
||||||
@ -20,13 +20,13 @@ namespace ppc::threading {
|
|||||||
int join() const;
|
int join() const;
|
||||||
|
|
||||||
thread_t(void *handle) { this->handle = handle; }
|
thread_t(void *handle) { this->handle = handle; }
|
||||||
template <class T>
|
template <class ParserT>
|
||||||
inline static thread_t start(thread_func_t<T> func, const T &args) {
|
inline static thread_t start(thread_func_t<ParserT> func, const ParserT &args) {
|
||||||
T _args = args;
|
ParserT _args = args;
|
||||||
return start_impl((void*)func, &_args);
|
return start_impl((void*)func, &_args);
|
||||||
}
|
}
|
||||||
template <class T>
|
template <class ParserT>
|
||||||
inline static thread_t start(thread_func_t<T> func, T &args) {
|
inline static thread_t start(thread_func_t<ParserT> func, ParserT &args) {
|
||||||
return start_impl((void*)func, &args);
|
return start_impl((void*)func, &args);
|
||||||
}
|
}
|
||||||
inline static thread_t start(empty_thread_func_t func) {
|
inline static thread_t start(empty_thread_func_t func) {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace ppc::lang {
|
namespace ppc::lang {
|
||||||
std::string loc_namespace_name_t::to_string() const {
|
std::string loc_nmsp_t::to_string() const {
|
||||||
std::stringstream res;
|
std::stringstream res;
|
||||||
|
|
||||||
for (size_t i = 0; i < size(); i++) {
|
for (size_t i = 0; i < size(); i++) {
|
||||||
@ -12,7 +12,7 @@ namespace ppc::lang {
|
|||||||
|
|
||||||
return res.str();
|
return res.str();
|
||||||
}
|
}
|
||||||
std::string namespace_name_t::to_string() const {
|
std::string nmsp_t::to_string() const {
|
||||||
std::stringstream res;
|
std::stringstream res;
|
||||||
|
|
||||||
for (size_t i = 0; i < size(); i++) {
|
for (size_t i = 0; i < size(); i++) {
|
||||||
@ -23,7 +23,7 @@ namespace ppc::lang {
|
|||||||
return res.str();
|
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;
|
const auto &a = *this;
|
||||||
for (size_t i = 0; i < a.size() && i < b.size(); i++) {
|
for (size_t i = 0; i < a.size() && i < b.size(); i++) {
|
||||||
auto cmp = a[i].compare(b[i]);
|
auto cmp = a[i].compare(b[i]);
|
||||||
@ -34,7 +34,7 @@ namespace ppc::lang {
|
|||||||
else if (a.size() == b.size()) return 0;
|
else if (a.size() == b.size()) return 0;
|
||||||
else return -1;
|
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;
|
const auto &a = *this;
|
||||||
for (size_t i = 0; i < a.size() && i < b.size(); i++) {
|
for (size_t i = 0; i < a.size() && i < b.size(); i++) {
|
||||||
auto cmp = a[i].compare(b[i]);
|
auto cmp = a[i].compare(b[i]);
|
||||||
@ -46,8 +46,8 @@ namespace ppc::lang {
|
|||||||
else return -1;
|
else return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace_name_t loc_namespace_name_t::strip_location() const {
|
nmsp_t loc_nmsp_t::strip_location() const {
|
||||||
namespace_name_t res;
|
nmsp_t res;
|
||||||
|
|
||||||
for (const auto &el : *this) {
|
for (const auto &el : *this) {
|
||||||
res.push_back(el);
|
res.push_back(el);
|
||||||
|
@ -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) } };
|
return { CALL, { .call = new auto(func) } };
|
||||||
}
|
}
|
||||||
statement_t statement_t::stack(int64_t stack) {
|
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() {
|
statement_t statement_t::ret() {
|
||||||
return { RETURN };
|
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;
|
|
||||||
}
|
|
@ -1,2 +1,2 @@
|
|||||||
main
|
main
|
||||||
utils, treeifier
|
utils, treeifier, lang
|
@ -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 });
|
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 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);
|
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) {
|
catch (const messages::message_t &msg) {
|
||||||
msg_stack.push(msg);
|
msg_stack.push(msg);
|
||||||
|
48
src/treeifier/constr.cc
Normal file
48
src/treeifier/constr.cc
Normal 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;
|
||||||
|
}
|
@ -4,15 +4,16 @@
|
|||||||
|
|
||||||
using namespace ppc::tree::constr;
|
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 {
|
bool ppc::tree::constr::glob_parser_t::operator()(ast_ctx_t &ctx, glob_t &out) const {
|
||||||
parse_helper_t h(ctx, res_i);
|
size_t res_i = 0;
|
||||||
|
helper_t h(ctx, res_i);
|
||||||
out = {};
|
out = {};
|
||||||
|
|
||||||
if (h.ended()) return h.submit(false);
|
if (h.ended()) return h.submit(false);
|
||||||
|
|
||||||
if (h.curr().is_identifier("namespace")) {
|
if (h.curr().is_identifier("namespace")) {
|
||||||
h.advance("Expected a 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)) {
|
if (!h.curr().is_operator(operator_t::SEMICOLON)) {
|
||||||
ctx.messages.push(message_t::error("Expected a semicolon.", h.loc(1)));
|
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")) {
|
while (h.curr().is_identifier("import")) {
|
||||||
loc_namespace_name_t res;
|
loc_nmsp_t res;
|
||||||
|
|
||||||
h.advance("Expected a namespace");
|
h.advance("Expected a namespace");
|
||||||
h.force_parse(nmsp_parser_t(), "Expected a namespace.", res);
|
h.force_parse(nmsp_parser_t(), "Expected a namespace.", res);
|
||||||
|
@ -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;
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user