AST building #2
@ -16,15 +16,16 @@ using namespace ppc::messages;
|
|||||||
namespace ppc::comp::tree::ast {
|
namespace ppc::comp::tree::ast {
|
||||||
class parser_t;
|
class parser_t;
|
||||||
class group_parser_t;
|
class group_parser_t;
|
||||||
|
struct ast_ctx_t;
|
||||||
|
|
||||||
using parser_factory_t = parser_t *(*)();
|
using parser_adder_t = void (*)(ast_ctx_t &ctx);
|
||||||
using group_parser_factory_t = group_parser_t *(*)();
|
|
||||||
|
|
||||||
extern parser_factory_t glob_parser;
|
extern const parser_adder_t glob_adder;
|
||||||
extern parser_factory_t identifier_parser;
|
extern const parser_adder_t identifier_adder;
|
||||||
extern parser_factory_t nmsp_parser;
|
extern const parser_adder_t nmsp_adder;
|
||||||
extern parser_factory_t type_parser;
|
extern const parser_adder_t type_adder;
|
||||||
extern group_parser_factory_t def_parser;
|
extern const parser_adder_t exp_adder;
|
||||||
|
extern const parser_adder_t field_adder;
|
||||||
|
|
||||||
struct ast_ctx_t {
|
struct ast_ctx_t {
|
||||||
private:
|
private:
|
||||||
@ -40,23 +41,23 @@ namespace ppc::comp::tree::ast {
|
|||||||
private:
|
private:
|
||||||
ast_ctx_t *parent;
|
ast_ctx_t *parent;
|
||||||
public:
|
public:
|
||||||
const group_parser_t &operator[](const std::string &name) const;
|
group_parser_t &operator[](const std::string &name) const;
|
||||||
group_proxy_t(ast_ctx_t *parent): parent(parent) { }
|
group_proxy_t(ast_ctx_t *parent): parent(parent) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unordered_map<std::string, const parser_t*> parsers;
|
std::unordered_map<std::string, const parser_t*> parsers;
|
||||||
std::set<const parser_t*> groups;
|
std::set<group_parser_t*> groups;
|
||||||
|
|
||||||
void add_parser(const parser_t *parser);
|
|
||||||
void add_parser(const group_parser_t *parser);
|
|
||||||
public:
|
public:
|
||||||
msg_stack_t &messages;
|
msg_stack_t &messages;
|
||||||
std::vector<token_t> &tokens;
|
std::vector<token_t> &tokens;
|
||||||
std::set<loc_namespace_name_t> imports;
|
std::set<loc_namespace_name_t> imports;
|
||||||
loc_namespace_name_t nmsp;
|
loc_namespace_name_t nmsp;
|
||||||
|
|
||||||
void add_parser(parser_factory_t factory) { add_parser(factory()); }
|
void add_parser(const parser_t *parser);
|
||||||
void add_parser(group_parser_factory_t factory) { add_parser(factory()); }
|
void add_parser(const parser_t *parser, const std::string &group);
|
||||||
|
void add_group(const std::string &name);
|
||||||
|
|
||||||
|
void add_parser(parser_adder_t factory) { factory(*this); }
|
||||||
|
|
||||||
ast_ctx_t &operator=(const ast_ctx_t &other) = delete;
|
ast_ctx_t &operator=(const ast_ctx_t &other) = delete;
|
||||||
|
|
||||||
@ -64,11 +65,13 @@ namespace ppc::comp::tree::ast {
|
|||||||
const group_proxy_t group;
|
const group_proxy_t group;
|
||||||
|
|
||||||
ast_ctx_t &init() {
|
ast_ctx_t &init() {
|
||||||
add_parser(glob_parser);
|
add_parser(identifier_adder);
|
||||||
add_parser(identifier_parser);
|
add_parser(nmsp_adder);
|
||||||
add_parser(nmsp_parser);
|
add_parser(glob_adder);
|
||||||
add_parser(def_parser);
|
add_parser(type_adder);
|
||||||
add_parser(type_parser);
|
add_parser(exp_adder);
|
||||||
|
add_parser(field_adder);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,11 +105,11 @@ namespace ppc::comp::tree::ast {
|
|||||||
|
|
||||||
class group_parser_t : public parser_t {
|
class group_parser_t : public parser_t {
|
||||||
private:
|
private:
|
||||||
std::vector<std::pair<lang::namespace_name_t, parser_t*>> named_parsers;
|
std::vector<std::pair<lang::namespace_name_t, const parser_t*>> named_parsers;
|
||||||
std::vector<parser_t*> parsers;
|
std::vector<const parser_t*> parsers;
|
||||||
public:
|
public:
|
||||||
group_parser_t &add(parser_t &parser);
|
group_parser_t &add(const parser_t &parser);
|
||||||
group_parser_t &add(parser_t &parser, const lang::namespace_name_t &name);
|
group_parser_t &add(const parser_t &parser, const lang::namespace_name_t &name);
|
||||||
|
|
||||||
bool parse(ast_ctx_t &ctx, size_t &i, data::map_t &out) const;
|
bool parse(ast_ctx_t &ctx, size_t &i, data::map_t &out) const;
|
||||||
|
|
||||||
|
@ -12,14 +12,15 @@ namespace ppc::comp::tree::ast {
|
|||||||
ast_ctx_t &ctx;
|
ast_ctx_t &ctx;
|
||||||
size_t &res_i;
|
size_t &res_i;
|
||||||
|
|
||||||
|
public:
|
||||||
|
size_t i;
|
||||||
|
|
||||||
void throw_ended() {
|
void throw_ended() {
|
||||||
if (ended()) throw messages::message_t(message_t::ERROR, "Unexpected end.", loc());
|
if (ended()) throw messages::message_t(message_t::ERROR, "Unexpected end.", loc());
|
||||||
}
|
}
|
||||||
void throw_ended(const std::string &reason) {
|
void throw_ended(const std::string &reason) {
|
||||||
if (ended()) throw messages::message_t(message_t::ERROR, "Unexpected end: " + reason, loc());
|
if (ended()) throw messages::message_t(message_t::ERROR, "Unexpected end: " + reason, loc());
|
||||||
}
|
}
|
||||||
public:
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
location_t loc(size_t n) {
|
location_t loc(size_t n) {
|
||||||
location_t res = prev_loc();
|
location_t res = prev_loc();
|
||||||
@ -62,10 +63,10 @@ namespace ppc::comp::tree::ast {
|
|||||||
else return ctx.tokens[res_i].location.intersect(loc());
|
else return ctx.tokens[res_i].location.intersect(loc());
|
||||||
}
|
}
|
||||||
|
|
||||||
void err(std::string message) {
|
bool err(std::string message) {
|
||||||
throw message_t::error(message, loc());
|
throw message_t::error(message, loc());
|
||||||
}
|
}
|
||||||
void err(std::string message, size_t n) {
|
bool err(std::string message, size_t n) {
|
||||||
throw message_t::error(message, loc(n));
|
throw message_t::error(message, loc(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,6 +79,10 @@ namespace ppc::comp::tree::ast {
|
|||||||
return i == ctx.tokens.size();
|
return i == ctx.tokens.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
token_t &curr(const std::string &reason) {
|
||||||
|
throw_ended(reason);
|
||||||
|
return ctx.tokens[i];
|
||||||
|
}
|
||||||
token_t &curr() {
|
token_t &curr() {
|
||||||
throw_ended();
|
throw_ended();
|
||||||
return ctx.tokens[i];
|
return ctx.tokens[i];
|
||||||
@ -113,7 +118,7 @@ namespace ppc::comp::tree::ast {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void force_push_parse(const std::string &name, std::string message, data::array_t &out) {
|
void force_push_parse(const std::string &name, std::string message, data::array_t &out) {
|
||||||
advance(message);
|
throw_ended(message);
|
||||||
bool success;
|
bool success;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -127,7 +132,7 @@ namespace ppc::comp::tree::ast {
|
|||||||
if (!success) err(message);
|
if (!success) err(message);
|
||||||
}
|
}
|
||||||
void force_parse(const std::string &name, std::string message, data::map_t &out) {
|
void force_parse(const std::string &name, std::string message, data::map_t &out) {
|
||||||
advance(message);
|
throw_ended(message);
|
||||||
bool success;
|
bool success;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -39,16 +39,22 @@ namespace ppc::data {
|
|||||||
bool is_string() const;
|
bool is_string() const;
|
||||||
bool is_bool() const;
|
bool is_bool() const;
|
||||||
|
|
||||||
bool array(array_t &out) const;
|
array_t &array(const array_t &arr);
|
||||||
bool map(map_t &out) const;
|
map_t &map(const map_t &map);
|
||||||
bool number(number_t &out) const;
|
number_t &number(number_t num);
|
||||||
bool string(string_t &out) const;
|
string_t &string(const string_t &str);
|
||||||
bool boolean(bool_t &out) const;
|
bool_t &boolean(bool_t bl);
|
||||||
|
|
||||||
array_t &array() const;
|
array_t &array();
|
||||||
map_t &map() const;
|
map_t &map();
|
||||||
|
number_t &number();
|
||||||
|
string_t &string();
|
||||||
|
bool_t &boolean();
|
||||||
|
|
||||||
|
const array_t &array() const;
|
||||||
|
const map_t &map() const;
|
||||||
number_t number() const;
|
number_t number() const;
|
||||||
string_t &string() const;
|
const string_t &string() const;
|
||||||
bool_t boolean() const;
|
bool_t boolean() const;
|
||||||
|
|
||||||
value_t &operator=(const value_t &other);
|
value_t &operator=(const value_t &other);
|
||||||
@ -65,8 +71,6 @@ namespace ppc::data {
|
|||||||
value_t(bool_t val);
|
value_t(bool_t val);
|
||||||
value_t(const value_t &other);
|
value_t(const value_t &other);
|
||||||
|
|
||||||
static value_t mk_arr();
|
|
||||||
static value_t mk_map();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,7 +38,13 @@ namespace ppc::messages {
|
|||||||
inline auto begin() { return messages.begin(); }
|
inline auto begin() { return messages.begin(); }
|
||||||
inline auto end() { return messages.end(); }
|
inline auto end() { return messages.end(); }
|
||||||
|
|
||||||
|
inline auto begin() const { return messages.begin(); }
|
||||||
|
inline auto end() const { return messages.end(); }
|
||||||
|
|
||||||
void push(const message_t &msg) { messages.push_back(msg); }
|
void push(const message_t &msg) { messages.push_back(msg); }
|
||||||
|
void push(const msg_stack_t &other) {
|
||||||
|
for (const auto &msg : other) push(msg);
|
||||||
|
}
|
||||||
const message_t &peek() { return messages.back(); }
|
const message_t &peek() { return messages.back(); }
|
||||||
void clear() { messages.clear(); }
|
void clear() { messages.clear(); }
|
||||||
|
|
||||||
|
@ -8,10 +8,10 @@ namespace ppc::comp::tree::ast {
|
|||||||
if (it == parent->parsers.end()) throw "The parser '" + name + "' doesn't exist.";
|
if (it == parent->parsers.end()) throw "The parser '" + name + "' doesn't exist.";
|
||||||
return *it->second;
|
return *it->second;
|
||||||
}
|
}
|
||||||
const group_parser_t &ast_ctx_t::group_proxy_t::operator[](const std::string &name) const {
|
group_parser_t &ast_ctx_t::group_proxy_t::operator[](const std::string &name) const {
|
||||||
auto p = &parent->parser[name];
|
auto p = (group_parser_t*)&parent->parser[name];
|
||||||
if (parent->groups.find(p) == parent->groups.end()) throw "A parser '" + name + "' exists, but isn't a group.";
|
if (parent->groups.find(p) == parent->groups.end()) throw "A parser '" + name + "' exists, but isn't a group.";
|
||||||
return *(const group_parser_t*)p;
|
return *p;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_ctx_t::~ast_ctx_t() {
|
ast_ctx_t::~ast_ctx_t() {
|
||||||
@ -24,7 +24,12 @@ namespace ppc::comp::tree::ast {
|
|||||||
if (parsers.find(parser->name()) != parsers.end()) throw "The parser '" + parser->name() + "' already exists.";
|
if (parsers.find(parser->name()) != parsers.end()) throw "The parser '" + parser->name() + "' already exists.";
|
||||||
parsers[parser->name()] = parser;
|
parsers[parser->name()] = parser;
|
||||||
}
|
}
|
||||||
void ast_ctx_t::add_parser(const group_parser_t *parser) {
|
void ast_ctx_t::add_parser(const parser_t *parser, const std::string &group) {
|
||||||
|
add_parser(parser);
|
||||||
|
this->group[group].add(*parser);
|
||||||
|
}
|
||||||
|
void ast_ctx_t::add_group(const std::string &name) {
|
||||||
|
auto parser = new group_parser_t(name);
|
||||||
if (parsers.find(parser->name()) != parsers.end()) throw "The parser '" + parser->name() + "' already exists.";
|
if (parsers.find(parser->name()) != parsers.end()) throw "The parser '" + parser->name() + "' already exists.";
|
||||||
parsers[parser->name()] = parser;
|
parsers[parser->name()] = parser;
|
||||||
groups.emplace(parser);
|
groups.emplace(parser);
|
||||||
|
@ -51,7 +51,7 @@ namespace ppc::comp::tree::ast::conv {
|
|||||||
data::map_t nmsp_to_map(const loc_namespace_name_t &nmsp) {
|
data::map_t nmsp_to_map(const loc_namespace_name_t &nmsp) {
|
||||||
data::map_t res;
|
data::map_t res;
|
||||||
|
|
||||||
auto arr = (res["content"] = data::array_t()).array();
|
auto arr = res["content"].array({});
|
||||||
|
|
||||||
for (const auto &segment : nmsp) {
|
for (const auto &segment : nmsp) {
|
||||||
arr.push({
|
arr.push({
|
||||||
|
44
src/compiler/treeifier/ast/parsers/field.cc
Normal file
44
src/compiler/treeifier/ast/parsers/field.cc
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#include "compiler/treeifier/ast/helper.hh"
|
||||||
|
|
||||||
|
class field_parser_t : public parser_t {
|
||||||
|
bool parse(ast_ctx_t &ctx, size_t &res_i, map_t &out) const {
|
||||||
|
tree_helper_t h(ctx, res_i);
|
||||||
|
|
||||||
|
if (h.ended()) return false;
|
||||||
|
|
||||||
|
if (!h.parse("$_identifier", out["name"].map({}))) return false;
|
||||||
|
|
||||||
|
bool type, defval;
|
||||||
|
|
||||||
|
h.throw_ended("Expected a colon or an equals sign.");
|
||||||
|
|
||||||
|
if (h.curr().is_operator(operator_t::COLON)) {
|
||||||
|
h.advance();
|
||||||
|
h.force_parse("$_type", "Expected a type.", out["type"].map({}));
|
||||||
|
type = true;
|
||||||
|
}
|
||||||
|
if (h.curr().is_operator(operator_t::ASSIGN)) {
|
||||||
|
h.i++;
|
||||||
|
h.err("Default values are not yet supported.", 1);
|
||||||
|
h.advance();
|
||||||
|
h.force_parse("$_exp", "Expected an expression.", out["value"].map({}));
|
||||||
|
type = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h.curr().is_operator(operator_t::SEMICOLON)) {
|
||||||
|
if (type || defval) return h.submit();
|
||||||
|
else return h.err("A type or a default value must be specified ");
|
||||||
|
}
|
||||||
|
else if (type || defval) {
|
||||||
|
ctx.messages.push(message_t::error("Expected a semicolon.", h.loc(1)));
|
||||||
|
return h.submit(false);
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
|
|
||||||
|
return h.submit(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public: field_parser_t(): parser_t("$_field") { }
|
||||||
|
};
|
||||||
|
|
||||||
|
parser_adder_t ppc::comp::tree::ast::field_adder = [](ast_ctx_t &ctx) { ctx.add_parser(new field_parser_t(), "$_def"); };
|
@ -9,6 +9,7 @@ class nmsp_def_parser_t : public parser_t {
|
|||||||
if (h.ended()) return false;
|
if (h.ended()) return false;
|
||||||
|
|
||||||
if (!h.curr().is_identifier("namespace")) return false;
|
if (!h.curr().is_identifier("namespace")) return false;
|
||||||
|
h.advance("Expected a namespace");
|
||||||
h.force_parse("$_nmsp", "Expected a namespace.", res);
|
h.force_parse("$_nmsp", "Expected a namespace.", res);
|
||||||
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)));
|
||||||
@ -25,6 +26,7 @@ class import_parser_t : public parser_t {
|
|||||||
if (h.ended()) return false;
|
if (h.ended()) return false;
|
||||||
|
|
||||||
if (!h.curr().is_identifier("import")) return false;
|
if (!h.curr().is_identifier("import")) return false;
|
||||||
|
h.advance("Expected a namespace");
|
||||||
h.force_parse("$_nmsp", "Expected a namespace.", res);
|
h.force_parse("$_nmsp", "Expected a namespace.", res);
|
||||||
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)));
|
||||||
@ -49,7 +51,7 @@ class glob_parser_t : public parser_t {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto &imports = (out["imports"] = array_t()).array();
|
auto &imports = (out["imports"] = array_t()).array();
|
||||||
/* auto &contents = */ (out["content"] = array_t()).array();
|
auto &contents = (out["content"] = array_t()).array();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
map_t map;
|
map_t map;
|
||||||
@ -60,9 +62,16 @@ class glob_parser_t : public parser_t {
|
|||||||
if (!ctx.imports.emplace(nmsp).second) h.err("The namespace '" + nmsp.to_string() + "' is already imported.");
|
if (!ctx.imports.emplace(nmsp).second) h.err("The namespace '" + nmsp.to_string() + "' is already imported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (h.ended()) break;
|
||||||
|
if (!h.push_parse("$_def", contents)) {
|
||||||
|
ctx.messages.push(message_t::error("Invalid token.", h.loc()));
|
||||||
|
h.i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!h.ended()) h.err("Invalid token.");
|
if (!h.ended()) h.err("Invalid token.");
|
||||||
|
|
||||||
if (ctx.messages.is_failed()) return false;
|
|
||||||
return h.submit();
|
return h.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,5 +79,8 @@ public:
|
|||||||
glob_parser_t(): parser_t("$_glob") { }
|
glob_parser_t(): parser_t("$_glob") { }
|
||||||
};
|
};
|
||||||
|
|
||||||
parser_factory_t ppc::comp::tree::ast::glob_parser = []() { return (parser_t*)new glob_parser_t(); };
|
parser_adder_t ppc::comp::tree::ast::glob_adder = [](ast_ctx_t &ctx) {
|
||||||
group_parser_factory_t ppc::comp::tree::ast::def_parser = []() { return new group_parser_t("$_def"); };
|
ctx.add_parser(new group_parser_t("$_def"));
|
||||||
|
ctx.add_parser(new group_parser_t("$_expr_val"));
|
||||||
|
ctx.add_parser(new glob_parser_t());
|
||||||
|
};
|
||||||
|
@ -2,10 +2,13 @@
|
|||||||
#include "compiler/treeifier/tokenizer.hh"
|
#include "compiler/treeifier/tokenizer.hh"
|
||||||
#include "compiler/treeifier/ast/helper.hh"
|
#include "compiler/treeifier/ast/helper.hh"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
using namespace ppc::comp::tree;
|
using namespace ppc::comp::tree;
|
||||||
using namespace ppc::comp::tree::ast;
|
using namespace ppc::comp::tree::ast;
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
static bool read_nmsp(ast_ctx_t &ctx, size_t &i, const lang::namespace_name_t &name) {
|
static bool read_nmsp(ast_ctx_t &ctx, size_t &i, const lang::namespace_name_t &name) {
|
||||||
tree_helper_t h(ctx, i);
|
tree_helper_t h(ctx, i);
|
||||||
@ -33,29 +36,31 @@ static bool read_nmsp(ast_ctx_t &ctx, size_t &i, const lang::namespace_name_t &n
|
|||||||
bool group_parser_t::parse(ast_ctx_t &ctx, size_t &i, data::map_t &out) const {
|
bool group_parser_t::parse(ast_ctx_t &ctx, size_t &i, data::map_t &out) const {
|
||||||
tree_helper_t h(ctx, i);
|
tree_helper_t h(ctx, i);
|
||||||
|
|
||||||
|
if (h.ended()) return false;
|
||||||
|
|
||||||
for (auto &pair : named_parsers) {
|
for (auto &pair : named_parsers) {
|
||||||
if (!read_nmsp(ctx, i, pair.first)) continue;
|
if (!read_nmsp(ctx, i, pair.first)) continue;
|
||||||
auto &parser = *pair.second;
|
auto &parser = *pair.second;
|
||||||
return parser(ctx, i, out);
|
if (parser(ctx, i, out)) return true;
|
||||||
|
else throw message_t::error("Unexpected construct specifier.", h.res_loc());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unordered_map<string, message_t> errors;
|
||||||
|
|
||||||
for (auto parser : parsers) {
|
for (auto parser : parsers) {
|
||||||
try {
|
if ((*parser)(ctx, i, out)) return true;
|
||||||
return (*parser)(ctx, i, out);
|
|
||||||
}
|
|
||||||
catch (const message_t &err) {
|
|
||||||
ctx.messages.push(err);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stringstream m;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
group_parser_t &group_parser_t::add(parser_t &parser) {
|
group_parser_t &group_parser_t::add(const parser_t &parser) {
|
||||||
parsers.push_back(&parser);
|
parsers.push_back(&parser);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
group_parser_t &group_parser_t::add(parser_t &parser, const lang::namespace_name_t &name) {
|
group_parser_t &group_parser_t::add(const parser_t &parser, const lang::namespace_name_t &name) {
|
||||||
if (name.empty()) throw "Name can't be empty."s;
|
if (name.empty()) throw "Name can't be empty."s;
|
||||||
if (std::find(parsers.begin(), parsers.end(), &parser) != parsers.end()) {
|
if (std::find(parsers.begin(), parsers.end(), &parser) != parsers.end()) {
|
||||||
throw "Parser '" + name.to_string() + "' already in group.";
|
throw "Parser '" + name.to_string() + "' already in group.";
|
||||||
|
@ -18,4 +18,4 @@ class identifier_parser_t : public parser_t {
|
|||||||
public: identifier_parser_t(): parser_t("$_identifier") { }
|
public: identifier_parser_t(): parser_t("$_identifier") { }
|
||||||
};
|
};
|
||||||
|
|
||||||
parser_factory_t ppc::comp::tree::ast::identifier_parser = []() { return (parser_t*)new identifier_parser_t(); };
|
parser_adder_t ppc::comp::tree::ast::identifier_adder = [](ast_ctx_t &ctx) { ctx.add_parser(new identifier_parser_t()); };
|
||||||
|
@ -23,4 +23,4 @@ class nmsp_parser_t : public parser_t {
|
|||||||
public: nmsp_parser_t(): parser_t("$_nmsp") { }
|
public: nmsp_parser_t(): parser_t("$_nmsp") { }
|
||||||
};
|
};
|
||||||
|
|
||||||
parser_factory_t ppc::comp::tree::ast::nmsp_parser = []() { return (parser_t*)new nmsp_parser_t(); };
|
parser_adder_t ppc::comp::tree::ast::nmsp_adder = [](ast_ctx_t &ctx) { ctx.add_parser(new nmsp_parser_t()); };
|
||||||
|
@ -47,4 +47,4 @@ class type_parser_t : public parser_t {
|
|||||||
public: type_parser_t(): parser_t("$_type") { }
|
public: type_parser_t(): parser_t("$_type") { }
|
||||||
};
|
};
|
||||||
|
|
||||||
parser_factory_t ppc::comp::tree::ast::type_parser = []() { return (parser_t*)new type_parser_t(); };
|
parser_adder_t ppc::comp::tree::ast::type_adder = [](ast_ctx_t &ctx) { ctx.add_parser(new type_parser_t()); };
|
||||||
|
@ -20,47 +20,55 @@ namespace ppc::data {
|
|||||||
return type == type_t::Bool;
|
return type == type_t::Bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool value_t::array(array_t &out) const {
|
array_t &value_t::array(const array_t &val) {
|
||||||
if (is_array()) {
|
*this = val;
|
||||||
out = *val.arr;
|
return *this->val.arr;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
map_t &value_t::map(const map_t &val) {
|
||||||
|
*this = val;
|
||||||
|
return *this->val.map;
|
||||||
}
|
}
|
||||||
bool value_t::map(map_t &out) const {
|
number_t &value_t::number(number_t val) {
|
||||||
if (is_map()) {
|
*this = val;
|
||||||
out = *val.map;
|
return this->val.num;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
string_t &value_t::string(const string_t &val) {
|
||||||
|
*this = val;
|
||||||
|
return *this->val.str;
|
||||||
}
|
}
|
||||||
bool value_t::number(number_t &out) const {
|
bool_t &value_t::boolean(bool_t val) {
|
||||||
if (is_number()) {
|
*this = val;
|
||||||
out = val.num;
|
return this->val.bl;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool value_t::string(string_t &out) const {
|
|
||||||
if (is_string()) {
|
|
||||||
out = *val.str;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool value_t::boolean(bool_t &out) const {
|
|
||||||
if (is_bool()) {
|
|
||||||
out = val.bl;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
array_t &value_t::array() const {
|
|
||||||
|
array_t &value_t::array() {
|
||||||
if (is_array()) return *val.arr;
|
if (is_array()) return *val.arr;
|
||||||
else throw (std::string)"The value isn't an array.";
|
else throw (std::string)"The value isn't an array.";
|
||||||
}
|
}
|
||||||
map_t &value_t::map() const {
|
map_t &value_t::map() {
|
||||||
|
if (is_map()) return *val.map;
|
||||||
|
else throw (std::string)"The value isn't a map.";
|
||||||
|
}
|
||||||
|
number_t &value_t::number() {
|
||||||
|
if (is_number()) return val.num;
|
||||||
|
else throw (std::string)"The value isn't a number.";
|
||||||
|
}
|
||||||
|
string_t &value_t::string() {
|
||||||
|
if (is_string()) return *val.str;
|
||||||
|
else throw (std::string)"The value isn't a string.";
|
||||||
|
}
|
||||||
|
bool_t &value_t::boolean() {
|
||||||
|
if (is_bool()) return val.bl;
|
||||||
|
else throw (std::string)"The value isn't a bool.";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const array_t &value_t::array() const {
|
||||||
|
if (is_array()) return *val.arr;
|
||||||
|
else throw (std::string)"The value isn't an array.";
|
||||||
|
}
|
||||||
|
const map_t &value_t::map() const {
|
||||||
if (is_map()) return *val.map;
|
if (is_map()) return *val.map;
|
||||||
else throw (std::string)"The value isn't a map.";
|
else throw (std::string)"The value isn't a map.";
|
||||||
}
|
}
|
||||||
@ -68,7 +76,7 @@ namespace ppc::data {
|
|||||||
if (is_number()) return val.num;
|
if (is_number()) return val.num;
|
||||||
else throw (std::string)"The value isn't a number.";
|
else throw (std::string)"The value isn't a number.";
|
||||||
}
|
}
|
||||||
string_t &value_t::string() const {
|
const string_t &value_t::string() const {
|
||||||
if (is_string()) return *val.str;
|
if (is_string()) return *val.str;
|
||||||
else throw (std::string)"The value isn't a string.";
|
else throw (std::string)"The value isn't a string.";
|
||||||
}
|
}
|
||||||
@ -121,12 +129,6 @@ namespace ppc::data {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
value_t value_t::mk_arr() {
|
|
||||||
return value_t(array_t());
|
|
||||||
}
|
|
||||||
value_t value_t::mk_map() {
|
|
||||||
return value_t(map_t());
|
|
||||||
}
|
|
||||||
|
|
||||||
value_t::~value_t() {
|
value_t::~value_t() {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
Loading…
Reference in New Issue
Block a user