2022-10-04 13:00:18 +00:00
|
|
|
#include "compiler/treeifier/ast.hh"
|
|
|
|
|
2022-10-09 11:18:38 +00:00
|
|
|
using namespace ppc;
|
|
|
|
using namespace ppc::lang;
|
|
|
|
using namespace ppc::data;
|
|
|
|
using namespace ppc::comp::tree;
|
|
|
|
using namespace ppc::comp::tree::ast;
|
|
|
|
|
2022-10-04 13:00:18 +00:00
|
|
|
namespace ppc::comp::tree::ast {
|
|
|
|
struct tree_helper_t {
|
|
|
|
private:
|
|
|
|
ast_ctx_t &ctx;
|
|
|
|
size_t &res_i;
|
2022-10-04 16:59:06 +00:00
|
|
|
|
|
|
|
void throw_ended() {
|
|
|
|
if (ended()) throw messages::message_t(message_t::ERROR, "Unexpected end.", loc());
|
|
|
|
}
|
2022-10-04 20:45:08 +00:00
|
|
|
void throw_ended(const std::string &reason) {
|
|
|
|
if (ended()) throw messages::message_t(message_t::ERROR, "Unexpected end: " + reason, loc());
|
|
|
|
}
|
2022-10-04 13:00:18 +00:00
|
|
|
public:
|
2022-10-04 20:45:08 +00:00
|
|
|
size_t i;
|
|
|
|
|
2022-10-04 13:00:18 +00:00
|
|
|
location_t next_loc(size_t n = 1) {
|
|
|
|
location_t res = loc();
|
|
|
|
res.start += res.length;
|
|
|
|
res.code_start += res.length;
|
|
|
|
res.length = n;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
location_t loc() {
|
|
|
|
if (ended()) {
|
|
|
|
if (i == 0) return location_t::NONE;
|
|
|
|
|
|
|
|
location_t loc = ctx.tokens[i - 1].location;
|
|
|
|
|
|
|
|
loc.start += loc.length;
|
|
|
|
loc.code_start += loc.length;
|
|
|
|
loc.length = 1;
|
|
|
|
|
|
|
|
return loc;
|
|
|
|
}
|
|
|
|
else return curr().location;
|
|
|
|
}
|
|
|
|
|
2022-10-04 16:59:06 +00:00
|
|
|
location_t res_loc() {
|
|
|
|
if (res_i >= ctx.tokens.size()) return loc();
|
|
|
|
else return ctx.tokens[res_i].location.intersect(loc());
|
|
|
|
}
|
|
|
|
|
2022-10-09 11:18:38 +00:00
|
|
|
void err(std::string message) {
|
|
|
|
throw message_t::error(message, loc());
|
2022-10-04 17:23:39 +00:00
|
|
|
}
|
2022-10-09 11:18:38 +00:00
|
|
|
|
|
|
|
bool submit(bool inc_i = true) {
|
|
|
|
res_i = (i += inc_i);
|
|
|
|
return true;
|
2022-10-04 13:00:18 +00:00
|
|
|
}
|
2022-10-09 11:18:38 +00:00
|
|
|
|
|
|
|
bool ended() {
|
|
|
|
return i == ctx.tokens.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
token_t &curr() {
|
|
|
|
throw_ended();
|
|
|
|
return ctx.tokens[i];
|
2022-10-04 13:00:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool try_advance() {
|
|
|
|
if (ended()) return false;
|
|
|
|
i++;
|
|
|
|
return !ended();
|
|
|
|
}
|
2022-10-04 16:59:06 +00:00
|
|
|
void advance() {
|
|
|
|
throw_ended();
|
2022-10-04 13:00:18 +00:00
|
|
|
i++;
|
2022-10-04 16:59:06 +00:00
|
|
|
throw_ended();
|
2022-10-04 13:00:18 +00:00
|
|
|
}
|
2022-10-04 20:45:08 +00:00
|
|
|
void advance(const std::string &reason) {
|
|
|
|
throw_ended(reason);
|
|
|
|
i++;
|
|
|
|
throw_ended(reason);
|
|
|
|
}
|
2022-10-04 13:00:18 +00:00
|
|
|
|
2022-10-09 13:34:02 +00:00
|
|
|
bool push_parse(const std::string &name, data::array_t &out) {
|
2022-10-09 11:18:38 +00:00
|
|
|
data::map_t res;
|
2022-10-09 13:34:02 +00:00
|
|
|
if (parse(name, res)) {
|
2022-10-09 11:18:38 +00:00
|
|
|
out.push(res);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else return false;
|
|
|
|
}
|
|
|
|
|
2022-10-09 13:34:02 +00:00
|
|
|
bool parse(const std::string &name, data::map_t &out) {
|
|
|
|
return ctx.parse(name, i, out);
|
2022-10-09 11:18:38 +00:00
|
|
|
}
|
|
|
|
|
2022-10-09 13:34:02 +00:00
|
|
|
void force_push_parse(const std::string &name, std::string message, data::array_t &out) {
|
2022-10-09 11:18:38 +00:00
|
|
|
advance(message);
|
|
|
|
bool success;
|
|
|
|
|
|
|
|
try {
|
2022-10-09 13:34:02 +00:00
|
|
|
success = push_parse(name, out);
|
2022-10-09 11:18:38 +00:00
|
|
|
}
|
|
|
|
catch (const message_t &msg) {
|
|
|
|
ctx.messages.push(msg);
|
|
|
|
success = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!success) err(message);
|
|
|
|
}
|
2022-10-09 13:34:02 +00:00
|
|
|
void force_parse(const std::string &name, std::string message, data::map_t &out) {
|
2022-10-09 11:18:38 +00:00
|
|
|
advance(message);
|
|
|
|
bool success;
|
|
|
|
|
|
|
|
try {
|
2022-10-09 13:34:02 +00:00
|
|
|
success = parse(name, out);
|
2022-10-09 11:18:38 +00:00
|
|
|
}
|
|
|
|
catch (const message_t &msg) {
|
|
|
|
ctx.messages.push(msg);
|
|
|
|
success = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!success) err(message);
|
|
|
|
}
|
|
|
|
|
2022-10-04 13:00:18 +00:00
|
|
|
tree_helper_t(ast_ctx_t &ctx, size_t &i): ctx(ctx), res_i(i) {
|
|
|
|
this->i = i;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|