Topcheto eu/struct resolving #3
@ -26,10 +26,9 @@ namespace ppc::comp::tree::ast {
|
||||
std::set<std::string> unnamed_parsers;
|
||||
std::map<std::string, parser_t> parsers;
|
||||
public:
|
||||
group_t &insert(const std::string &name, parser_t parser, const std::string &relative_to, bool after);
|
||||
group_t &add_last(const std::string &name, parser_t parser);
|
||||
group_t &replace(const std::string &name, parser_t parser);
|
||||
group_t &add_named(const std::string &name, parser_t parser, const lang::namespace_name_t &identifier);
|
||||
group_t &add(const std::string &name, parser_t parser);
|
||||
group_t &add(const std::string &name, const lang::namespace_name_t &identifier, parser_t parser);
|
||||
|
||||
bool operator()(ast_ctx_t &ctx, size_t &i, data::map_t &out) const;
|
||||
};
|
||||
@ -77,7 +76,7 @@ namespace ppc::comp::tree::ast {
|
||||
}
|
||||
|
||||
parser_func_t parse_glob, parse_nmsp, parse_identifier, parse_type, parse_exp, parse_stat_exp;
|
||||
parser_func_t parse_func, parse_field, parse_export;
|
||||
parser_func_t parse_func, parse_field, parse_export, parse_struct;
|
||||
parser_func_t parse_if, parse_while, parse_return, parse_break, parse_continue, parse_stat_comp;
|
||||
parser_func_t parse_exp_var, parse_exp_str_lit, parse_exp_int_lit, parse_exp_float_lit;
|
||||
}
|
@ -99,6 +99,10 @@ namespace ppc::data {
|
||||
return values.find(key) != values.end();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
values.clear();
|
||||
}
|
||||
|
||||
std::size_t size() const { return values.size(); }
|
||||
|
||||
auto begin() const { return values.begin(); }
|
||||
|
@ -12,20 +12,23 @@ group_t &ast_ctx_t::group(const std::string &name) {
|
||||
|
||||
ast_ctx_t::ast_ctx_t(msg_stack_t &messages, std::vector<token_t> &tokens): messages(messages), tokens(tokens) {
|
||||
group("$_exp_val")
|
||||
.add_last("$_var", parse_exp_var)
|
||||
.add_last("$_int", parse_exp_int_lit)
|
||||
.add_last("$_string", parse_exp_str_lit);
|
||||
.add("$_var", parse_exp_var)
|
||||
.add("$_int", parse_exp_int_lit)
|
||||
.add("$_string", parse_exp_str_lit);
|
||||
// .add_last("$_float", parse_exp_float_lit)
|
||||
group("$_stat")
|
||||
.add_named("$_while", parse_while, { "while" })
|
||||
.add_named("$_if", parse_if, { "if" })
|
||||
.add_named("$_return", parse_return, { "return" })
|
||||
.add_named("$_break", parse_break, { "break" })
|
||||
.add_named("$_continue", parse_continue, { "continue" })
|
||||
.add_last("$_comp", parse_stat_comp)
|
||||
.add_last("$_exp", parse_stat_exp);
|
||||
.add("$_while", { "while" }, parse_while)
|
||||
.add("$_if", { "if" }, parse_if)
|
||||
.add("$_return", { "return" }, parse_return)
|
||||
.add("$_break", { "break" }, parse_break)
|
||||
.add("$_continue", { "continue" }, parse_continue)
|
||||
.add("$_comp", parse_stat_comp)
|
||||
.add("$_exp", parse_stat_exp);
|
||||
group("$_def")
|
||||
.add_last("$_func", parse_func)
|
||||
.add_named("$_export", parse_export, { "export" })
|
||||
.add_last("$_field", parse_field);
|
||||
}
|
||||
.add("$_func", parse_func)
|
||||
.add("$_struct", { "struct" }, parse_struct)
|
||||
.add("$_field", parse_field);
|
||||
group("$_struct_def")
|
||||
.add("$_func", parse_func)
|
||||
.add("$_field", parse_field);
|
||||
}
|
||||
|
@ -3,10 +3,14 @@
|
||||
bool ast::parse_export(ast_ctx_t &ctx, size_t &res_i, map_t &out) {
|
||||
tree_helper_t h(ctx, res_i);
|
||||
|
||||
if (h.ended()) return false;
|
||||
if (!h.curr().is_identifier("export")) return false;
|
||||
h.advance("Unexpected end after export.");
|
||||
|
||||
if (out["exported"].is_true()) {
|
||||
ctx.messages.push(message_t(message_t::WARNING, "Export is alredy specified for this definition.", h.prev_loc()));
|
||||
}
|
||||
out["exported"] = true;
|
||||
|
||||
return ctx.group("$_def")(ctx, res_i, out);
|
||||
return h.submit(false);
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ bool ast::parse_field(ast_ctx_t &ctx, size_t &res_i, map_t &out) {
|
||||
|
||||
if (h.ended()) return false;
|
||||
|
||||
h.parse(parse_export, out);
|
||||
|
||||
if (!h.parse(parse_identifier, out["name"].map({}))) return false;
|
||||
|
||||
bool type = false, defval = false;
|
||||
|
@ -5,6 +5,8 @@ static bool parse_arg(ast_ctx_t &ctx, size_t &res_i, map_t &out) {
|
||||
|
||||
if (h.ended()) return false;
|
||||
|
||||
h.parse(parse_export, out);
|
||||
|
||||
if (!h.parse(parse_identifier, out["name"].map({}))) return false;
|
||||
|
||||
bool type = false, defval = false;
|
||||
@ -34,6 +36,8 @@ bool ast::parse_func(ast_ctx_t &ctx, size_t &res_i, map_t &out) {
|
||||
|
||||
if (h.ended()) return false;
|
||||
|
||||
h.parse(parse_export, out);
|
||||
|
||||
if (!h.parse(parse_identifier, out["name"].map({}))) return false;
|
||||
if (h.ended()) return false;
|
||||
if (!h.curr().is_operator(operator_t::PAREN_OPEN)) return false;
|
||||
|
@ -21,22 +21,6 @@ static bool read_nmsp(ast_ctx_t &ctx, size_t &i, lang::loc_namespace_name_t &nam
|
||||
}
|
||||
|
||||
|
||||
group_t &group_t::insert(const std::string &name, parser_t parser, const std::string &relative_to, bool after) {
|
||||
if (parsers.find(name) != parsers.end()) {
|
||||
throw "The parser '" + name + "' is already in the group.";
|
||||
}
|
||||
|
||||
auto it = unnamed_parsers.find(relative_to);
|
||||
if (it == unnamed_parsers.end()) {
|
||||
throw "The parser '" + relative_to + "' isn't in the group or isn't unnamed.";
|
||||
}
|
||||
|
||||
if (after) it++;
|
||||
|
||||
unnamed_parsers.insert(it, name);
|
||||
|
||||
return *this;
|
||||
}
|
||||
group_t &group_t::replace(const std::string &name, parser_t parser) {
|
||||
auto it = parsers.find(name);
|
||||
|
||||
@ -48,7 +32,7 @@ group_t &group_t::replace(const std::string &name, parser_t parser) {
|
||||
|
||||
return *this;
|
||||
}
|
||||
group_t &group_t::add_last(const std::string &name, parser_t parser) {
|
||||
group_t &group_t::add(const std::string &name, parser_t parser) {
|
||||
if (parsers.find(name) != parsers.end()) {
|
||||
throw "The parser '" + name + "' is already in the group.";
|
||||
}
|
||||
@ -58,7 +42,7 @@ group_t &group_t::add_last(const std::string &name, parser_t parser) {
|
||||
|
||||
return *this;
|
||||
}
|
||||
group_t &group_t::add_named(const std::string &name, parser_t parser, const lang::namespace_name_t &identifier) {
|
||||
group_t &group_t::add(const std::string &name, const lang::namespace_name_t &identifier, parser_t parser) {
|
||||
if (parsers.find(name) != parsers.end()) {
|
||||
throw "The parser '" + name + "' is already in the group.";
|
||||
}
|
||||
@ -87,6 +71,7 @@ bool group_t::operator()(ast_ctx_t &ctx, size_t &i, data::map_t &out) const {
|
||||
name.strip_location(), actual
|
||||
)) {
|
||||
auto parser = parsers.find(this->named_parsers.find(actual)->second);
|
||||
out.clear();
|
||||
out["$_name"] = parser->first;
|
||||
if (h.parse(parser->second, out)) return h.submit(false);
|
||||
else throw message_t::error("Unexpected construct specifier.", h.res_loc());
|
||||
@ -95,6 +80,7 @@ bool group_t::operator()(ast_ctx_t &ctx, size_t &i, data::map_t &out) const {
|
||||
|
||||
for (auto name : unnamed_parsers) {
|
||||
out["$_name"] = name;
|
||||
out.clear();
|
||||
if (parsers.at(name)(ctx, i, out)) return true;
|
||||
}
|
||||
|
||||
|
24
src/compiler/treeifier/ast/parsers/struct.cc
Normal file
24
src/compiler/treeifier/ast/parsers/struct.cc
Normal file
@ -0,0 +1,24 @@
|
||||
#include "compiler/treeifier/ast/helper.hh"
|
||||
|
||||
bool ast::parse_struct(ast_ctx_t &ctx, size_t &res_i, map_t &out) {
|
||||
tree_helper_t h(ctx, res_i);
|
||||
|
||||
if (h.ended()) return false;
|
||||
|
||||
if (!h.parse(parse_identifier, out["name"].map({}))) return false;
|
||||
|
||||
auto &content = out["content"].array({});
|
||||
|
||||
if (h.ended()) return false;
|
||||
if (h.curr().is_operator(operator_t::SEMICOLON)) return h.submit(true);
|
||||
if (!h.curr().is_operator(operator_t::BRACE_OPEN)) return false;
|
||||
h.advance("Expected a definition, a closing brace, or a semicolon.");
|
||||
|
||||
|
||||
while (!h.curr().is_operator(operator_t::BRACE_CLOSE)) {
|
||||
h.throw_ended("Expected a definition or a closing brace.");
|
||||
h.push_parse(ctx.group("$_struct_def"), content);
|
||||
}
|
||||
|
||||
return h.submit(true);
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <filesystem>
|
||||
|
||||
struct project_t {
|
||||
std::string output;
|
||||
|
Loading…
Reference in New Issue
Block a user