diff --git a/include/compiler.hh b/include/compiler.hh index a1c6d0c..133323b 100644 --- a/include/compiler.hh +++ b/include/compiler.hh @@ -1,6 +1,6 @@ #ifndef PPC_COMPILER_H #define PPC_COMPILER_H 1 -#include "compiler/treeifier.hh" +#include "treeifier.hh" #endif \ No newline at end of file diff --git a/include/compiler/treeifier.hh b/include/compiler/treeifier.hh deleted file mode 100644 index c4b4d44..0000000 --- a/include/compiler/treeifier.hh +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef PPC_TREEIFIER_H -#define PPC_TREEIFIER_H 1 - -#include "utils/message.hh" - -namespace ppc::compiler { - // bool treeify(ppc::messages::msg_stack_t &msg_stack, const std::string &filename, const std::string &source, namespace_t *pout); - // bool treeify_file(const std::string &filename, ppc::messages::msg_stack_t &pmsg_stack, namespace_t *pout); -} - -#endif \ No newline at end of file diff --git a/include/compiler/treeifier/ast.hh b/include/compiler/treeifier/ast.hh deleted file mode 100644 index e998f67..0000000 --- a/include/compiler/treeifier/ast.hh +++ /dev/null @@ -1,105 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "compiler/treeifier/tokenizer.hh" -#include "lang/common.hh" -#include "utils/data.hh" - -using namespace std::string_literals; -using namespace ppc; -using namespace ppc::lang; -using namespace ppc::messages; - -namespace ppc::comp::tree::ast { - struct ast_ctx_t; - using parser_func_t = bool(ast_ctx_t &ctx, size_t &res_i, data::map_t &out); - using parser_t = parser_func_t *; - - class group_t { - private: - std::map named_parsers; - std::set unnamed_parsers; - std::map parsers; - public: - group_t &replace(const std::string &name, parser_t parser); - 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; - }; - - struct ast_ctx_t { - private: - std::unordered_map groups; - public: - msg_stack_t &messages; - std::vector &tokens; - std::set imports; - loc_namespace_name_t nmsp; - - ast_ctx_t &operator=(const ast_ctx_t &other) = delete; - - template - bool parse(const T &parser, size_t &i, data::map_t &out) { - return parser(*this, i, out); - } - - group_t &group(const std::string &name); - - template - static data::map_t parse(const T &glob, msg_stack_t &messages, std::vector &tokens) { - ast_ctx_t ctx(messages, tokens); - data::map_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 &tokens); - }; - - namespace conv { - data::map_t identifier_to_map(const located_t &loc); - located_t map_to_identifier(const data::map_t &map); - - data::string_t loc_to_map(const location_t &loc); - location_t map_to_loc(const data::string_t &map); - - data::map_t nmsp_to_map(const loc_namespace_name_t &nmsp); - loc_namespace_name_t map_to_nmsp(const data::map_t &map); - } // namespace conv - - class construct_t { - public: - virtual const std::string &name() const = 0; - }; - - class parser_t { - public: - virtual bool parse(ast_ctx_t &ctx, size_t &res_i, construct_t *&out) const = 0; - virtual bool simplify(ast_ctx_t &ctx, size_t &res_i, const construct_t *global, const construct_t *container, const construct_t *current) const = 0; - }; - - namespace constr { - class glob_con_t: public construct_t { - const std::string &name() const { return "$_glob"s; } - bool parse(ast_ctx_t &ctx, size_t &res_i, construct_t *&out) const; - }; - } - - namespace parsers { - - } - - 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, 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; -} \ No newline at end of file diff --git a/include/lang/common.hh b/include/lang/common.hh index ef7178a..ba966b9 100644 --- a/include/lang/common.hh +++ b/include/lang/common.hh @@ -4,7 +4,7 @@ #include namespace ppc::lang { - struct namespace_name_t : public std::vector { + struct namespace_name_t: public std::vector { using base = std::vector; int compare(const namespace_name_t &other) const; @@ -42,7 +42,7 @@ struct std::hash { namespace ppc::lang { template - struct located_t : T { + struct located_t: T { location_t location; located_t(location_t loc, const T &val): T(val), location(loc) { } @@ -66,7 +66,7 @@ namespace ppc::lang { slocated_t() { } }; - struct loc_namespace_name_t : public std::vector> { + struct loc_namespace_name_t: public std::vector> { using base = std::vector>; int compare(const loc_namespace_name_t &other) const; diff --git a/include/treeifier/constr.hh b/include/treeifier/constr.hh new file mode 100644 index 0000000..cd8d39a --- /dev/null +++ b/include/treeifier/constr.hh @@ -0,0 +1,94 @@ +#pragma once + +#include "lang/common.hh" +#include "treeifier/tokenizer.hh" +#include "utils/data.hh" +#include +#include +#include +#include +#include +#include +#include + +using namespace std::string_literals; +using namespace ppc; +using namespace ppc::lang; +using namespace ppc::messages; + +namespace ppc::tree::constr { + struct ast_ctx_t; + + struct glob_t { + loc_namespace_name_t nmsp; + std::vector imports; + }; + + template + 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 + }; + + + struct ast_ctx_t { + public: + msg_stack_t &messages; + std::vector &tokens; + loc_namespace_name_t nmsp; + + ast_ctx_t &operator=(const ast_ctx_t &other) = delete; + + template + bool parse(const parser_t &parser, size_t &i, T &out) { + return parser(*this, i, out); + } + + template + static T parse(const parser_t &glob, msg_stack_t &messages, std::vector &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 &tokens); + }; + + template + class inspoint_t { + private: + std::map named_parsers; + std::set unnamed_parsers; + std::map parsers; + 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; + }; + + // 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, 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; +} \ No newline at end of file diff --git a/include/treeifier/constr/glob.hh b/include/treeifier/constr/glob.hh new file mode 100644 index 0000000..9303979 --- /dev/null +++ b/include/treeifier/constr/glob.hh @@ -0,0 +1,9 @@ +#include "treeifier/constr.hh" + +namespace ppc::tree::constr { + class glob_parser_t: public parser_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; } + }; +} \ No newline at end of file diff --git a/include/compiler/treeifier/ast/helper.hh b/include/treeifier/constr/helper.hh similarity index 73% rename from include/compiler/treeifier/ast/helper.hh rename to include/treeifier/constr/helper.hh index 971c562..c91f3a9 100644 --- a/include/compiler/treeifier/ast/helper.hh +++ b/include/treeifier/constr/helper.hh @@ -1,13 +1,13 @@ -#include "compiler/treeifier/ast.hh" +#include "treeifier/constr.hh" using namespace ppc; using namespace ppc::lang; using namespace ppc::data; -using namespace ppc::comp::tree; -using namespace ppc::comp::tree::ast; +using namespace ppc::tree; +using namespace ppc::tree::constr; -namespace ppc::comp::tree::ast { - struct tree_helper_t { +namespace ppc::tree::constr { + struct parse_helper_t { private: ast_ctx_t &ctx; size_t &res_i; @@ -105,37 +105,12 @@ namespace ppc::comp::tree::ast { } template - bool push_parse(const T &parser, data::array_t &out) { - data::map_t res; - if (parse(parser, res)) { - out.push_back(res); - return true; - } - else return false; - } - - template - bool parse(const T &parser, data::map_t &out) { + bool parse(const parser_t &parser, T &out) { return ctx.parse(parser, i, out); } template - void force_push_parse(const T &parser, std::string message, data::array_t &out) { - throw_ended(message); - bool success; - - try { - success = push_parse(parser, out); - } - catch (const message_t &msg) { - ctx.messages.push(msg); - success = false; - } - - if (!success) err(message); - } - template - void force_parse(const T &parser, std::string message, data::map_t &out) { + void force_parse(const parser_t &parser, std::string message, T &out) { throw_ended(message); bool success; @@ -150,7 +125,7 @@ namespace ppc::comp::tree::ast { if (!success) err(message); } - tree_helper_t(ast_ctx_t &ctx, size_t &i): ctx(ctx), res_i(i) { + parse_helper_t(ast_ctx_t &ctx, size_t &i): ctx(ctx), res_i(i) { this->i = i; } }; diff --git a/include/treeifier/constr/identifier.hh b/include/treeifier/constr/identifier.hh new file mode 100644 index 0000000..b16e615 --- /dev/null +++ b/include/treeifier/constr/identifier.hh @@ -0,0 +1,8 @@ +#include "treeifier/constr.hh" + +namespace ppc::tree::constr { + struct identifier_parser_t: public parser_t> { + bool operator()(ast_ctx_t &ctx, size_t &res_i, located_t &out) const override; + bool simplify(ast_ctx_t &ctx, glob_t &glob, located_t &val) const override { return false; } + }; +} \ No newline at end of file diff --git a/include/treeifier/constr/nmsp.hh b/include/treeifier/constr/nmsp.hh new file mode 100644 index 0000000..0c10a85 --- /dev/null +++ b/include/treeifier/constr/nmsp.hh @@ -0,0 +1,9 @@ +#include "treeifier/constr/identifier.hh" +#include "treeifier/constr.hh" + +namespace ppc::tree::constr { + struct nmsp_parser_t: public parser_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; } + }; +} \ No newline at end of file diff --git a/include/compiler/treeifier/lexer.hh b/include/treeifier/lexer.hh similarity index 95% rename from include/compiler/treeifier/lexer.hh rename to include/treeifier/lexer.hh index b36d9f8..c42090b 100644 --- a/include/compiler/treeifier/lexer.hh +++ b/include/treeifier/lexer.hh @@ -3,7 +3,7 @@ #include "utils/location.hh" #include "utils/message.hh" -namespace ppc::comp::tree::lex { +namespace ppc::tree::lex { struct token_t { enum kind_t { NONE, diff --git a/include/compiler/treeifier/tokenizer.hh b/include/treeifier/tokenizer.hh similarity index 95% rename from include/compiler/treeifier/tokenizer.hh rename to include/treeifier/tokenizer.hh index c8e2034..e60db90 100644 --- a/include/compiler/treeifier/tokenizer.hh +++ b/include/treeifier/tokenizer.hh @@ -2,9 +2,9 @@ #include "utils/location.hh" #include "utils/message.hh" -#include "compiler/treeifier/lexer.hh" +#include "treeifier/lexer.hh" -namespace ppc::comp::tree { +namespace ppc::tree { enum operator_t { NONE, diff --git a/include/utils/data.hh b/include/utils/data.hh index a4e8b4e..6353d80 100644 --- a/include/utils/data.hh +++ b/include/utils/data.hh @@ -116,5 +116,5 @@ namespace ppc::data { } }; - class array_t : public std::vector { }; + class array_t: public std::vector { }; } \ No newline at end of file diff --git a/src/compiler/treeifier/ast/ast.cc b/src/compiler/treeifier/ast/ast.cc deleted file mode 100644 index e875f59..0000000 --- a/src/compiler/treeifier/ast/ast.cc +++ /dev/null @@ -1,35 +0,0 @@ -#include "compiler/treeifier/ast.hh" - -using namespace ppc; -using namespace ppc::data; -using namespace ppc::lang; -using namespace ppc::comp::tree::ast; - -group_t &ast_ctx_t::group(const std::string &name) { - if (groups.find(name) == groups.end()) return groups[name] = {}; - else return groups[name]; -} - -ast_ctx_t::ast_ctx_t(msg_stack_t &messages, std::vector &tokens): - messages(messages), tokens(tokens) { - group("$_exp_val") - .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("$_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("$_func", parse_func) - .add("$_struct", { "struct" }, parse_struct) - .add("$_field", parse_field); - group("$_struct_def") - .add("$_func", parse_func) - .add("$_field", parse_field); -} diff --git a/src/compiler/treeifier/ast/conv.cc b/src/compiler/treeifier/ast/conv.cc deleted file mode 100644 index 41fd248..0000000 --- a/src/compiler/treeifier/ast/conv.cc +++ /dev/null @@ -1,70 +0,0 @@ -#include "compiler/treeifier/ast.hh" -#include - -namespace ppc::comp::tree::ast::conv { - data::map_t identifier_to_map(const located_t &loc) { - return { - { "location", conv::loc_to_map(loc.location) }, - { "content", loc }, - { "$_name", "$_identifier" }, - }; - } - located_t map_to_identifier(const data::map_t &map) { - return { conv::map_to_loc(map["location"].string()), map["content"].string() }; - } - - data::string_t loc_to_map(const location_t &loc) { - std::stringstream res; - res << loc.filename << ':' << loc.line + 1 << ':' << loc.start + 1 << ':' << loc.code_start + 1 << ':' << loc.length + 1; - return res.str(); - } - location_t map_to_loc(const data::string_t &map) { - std::stringstream res; - res.str(map); - - std::string filename; - std::string line; - std::string start; - std::string code_start; - std::string length; - - std::getline(res, filename, ':'); - std::getline(res, line, ':'); - std::getline(res, start, ':'); - std::getline(res, code_start, ':'); - std::getline(res, length, ':'); - - return { filename, std::stoull(line) - 1, std::stoull(start) - 1, std::stoull(code_start) - 1, std::stoull(length) - 1 }; - } - - data::map_t nmsp_to_map(const loc_namespace_name_t &nmsp) { - data::map_t res; - - auto arr = res["content"].array({}); - - for (const auto &segment : nmsp) { - arr.push_back({ - { "location", loc_to_map(segment.location) }, - { "content", segment }, - { "$_name", "$_nmsp" }, - }); - } - - return res; - } - loc_namespace_name_t map_to_nmsp(const data::map_t &map) { - loc_namespace_name_t res; - - for (const auto &segment : map["content"].array()) { - try { - auto val = map_to_identifier(segment.map()); - res.push_back(val); - } - catch (const message_t &) { - throw "'content' of a namespace map must contain only identifiers."; - } - } - - return res; - } -} diff --git a/src/compiler/treeifier/ast/parsers/exp.cc b/src/compiler/treeifier/ast/parsers/exp.cc deleted file mode 100644 index 929d85a..0000000 --- a/src/compiler/treeifier/ast/parsers/exp.cc +++ /dev/null @@ -1,364 +0,0 @@ -#include "compiler/treeifier/ast/helper.hh" -#include -#include - -enum precedence_t { - NONE, - POSTFIX, - PREFIX, - MULT, - ADD, - SHIFT, - COMP, - EQU, - BIN_AND, - BIN_XOR, - BIN_OR, - BOOL_AND, - BOOL_OR, - TERNARY, - ASSIGN, - PAREN, - CALL_START, -}; - -struct op_data_t { - precedence_t precedence; - size_t op_n; - std::string name; - bool assoc; -}; - -op_data_t sizeof_data { precedence_t::PREFIX, 1, "sizeof", true }; - -std::map pre_ops { - { operator_t::INCREASE, { precedence_t::PREFIX, 1, "inc_pre" } }, - { operator_t::DECREASE, { precedence_t::PREFIX, 1, "dec_pre" } }, - { operator_t::ADD, { precedence_t::PREFIX, 1, "positive" } }, - { operator_t::SUBTRACT, { precedence_t::PREFIX, 1, "negative" } }, - { operator_t::BITWISE_NEGATIVE, { precedence_t::PREFIX, 1, "flip" } }, - { operator_t::MULTIPLY, { precedence_t::PREFIX, 1, "dereference" } }, - { operator_t::AND, { precedence_t::PREFIX, 1, "reference" } }, -}; -std::map bin_ops { - { operator_t::INCREASE, { precedence_t::POSTFIX, 1, "inc_post" } }, - { operator_t::DECREASE, { precedence_t::POSTFIX, 1, "dec_post" } }, - { (operator_t)-1, sizeof_data }, - - { operator_t::ADD, { precedence_t::ADD, 2, "add" } }, - { operator_t::SUBTRACT, { precedence_t::ADD, 2, "subtract" } }, - - { operator_t::MULTIPLY, { precedence_t::MULT, 2, "multiply" } }, - { operator_t::DIVIDE, { precedence_t::MULT, 2, "divide" } }, - { operator_t::MODULO, { precedence_t::MULT, 2, "modulo" } }, - - { operator_t::SHIFT_LEFT, { precedence_t::SHIFT, 2, "shl" } }, - { operator_t::SHIFT_RIGHT, { precedence_t::SHIFT, 2, "shr" } }, - - { operator_t::LESS_THAN, { precedence_t::COMP, 2, "less" } }, - { operator_t::LESS_THAN_EQUALS, { precedence_t::COMP, 2, "less_eq" } }, - { operator_t::GREATER_THAN, { precedence_t::COMP, 2, "great" } }, - { operator_t::GREATER_THAN_EQUALS, { precedence_t::COMP, 2, "great_eq" } }, - - { operator_t::EQUALS, { precedence_t::EQU, 2, "eq" } }, - { operator_t::NOT_EQUALS, { precedence_t::EQU, 2, "neq" } }, - - { operator_t::AND, { precedence_t::BIN_AND, 2, "great_eq" } }, - { operator_t::OR, { precedence_t::BIN_OR, 2, "great_eq" } }, - { operator_t::XOR, { precedence_t::BIN_XOR, 2, "great_eq" } }, - - { operator_t::DOUBLE_AND, { precedence_t::BOOL_AND, 2, "great_eq" } }, - { operator_t::DOUBLE_OR, { precedence_t::BOOL_OR, 2, "great_eq" } }, - - { operator_t::ASSIGN, { precedence_t::ASSIGN, 2, "assign", true } }, - { operator_t::ASSIGN_ADD, { precedence_t::ASSIGN, 2, "assign_add", true } }, - { operator_t::ASSIGN_SUBTRACT, { precedence_t::ASSIGN, 2, "assign_subtract", true } }, - { operator_t::ASSIGN_MULTIPLY, { precedence_t::ASSIGN, 2, "assign_multiply", true } }, - { operator_t::ASSIGN_DIVIDE, { precedence_t::ASSIGN, 2, "assign_divide", true } }, - { operator_t::ASSIGN_MODULO, { precedence_t::ASSIGN, 2, "assign_modulo", true } }, - { operator_t::ASSIGN_SHIFT_LEFT, { precedence_t::ASSIGN, 2, "assign_shl", true } }, - { operator_t::ASSIGN_SHIFT_RIGHT, { precedence_t::ASSIGN, 2, "assign_shr", true } }, - { operator_t::ASSIGN_XOR, { precedence_t::ASSIGN, 2, "assign_xor", true } }, - { operator_t::ASSIGN_AND, { precedence_t::ASSIGN, 2, "assign_and", true } }, - { operator_t::ASSIGN_OR, { precedence_t::ASSIGN, 2, "assign_or", true } }, - { operator_t::ASSIGN_DOUBLE_AND, { precedence_t::ASSIGN, 2, "assign_dand", true } }, - { operator_t::ASSIGN_DOUBLE_OR, { precedence_t::ASSIGN, 2, "assign_dor", true } }, - { operator_t::ASSIGN_NULL_COALESCING, { precedence_t::ASSIGN, 2, "assign_null_coal", true } }, -}; - -map_t op_to_map(located_t op) { - return { - { "$_name", "$_operator" }, - { "ops", array_t() }, - { "location", conv::loc_to_map(op.location) }, - { "op", op.name }, - }; -} - -bool pop(std::vector> &op_stack, array_t &res) { - if (op_stack.empty()) return false; - - auto map = op_to_map(op_stack.back()); - auto op_n = op_stack.back().op_n; - auto loc = op_stack.back().location; - op_stack.pop_back(); - - if (res.size() < op_n) return false; - - auto &ops = map["ops"].array(); - - - for (size_t i = 0; i < op_n; i++) { - ops.push_back(res.back()); - loc = loc.intersect(conv::map_to_loc(res.back().map()["location"].string())); - res.pop_back(); - } - - map["location"] = conv::loc_to_map(loc); - - std::reverse(ops.begin(), ops.end()); - res.push_back(map); - - return true; -} -bool pop_paren(std::vector> &op_stack, array_t &res) { - bool has_paren = false; - for (const auto &op : op_stack) { - if (op.precedence == precedence_t::PAREN) { - has_paren = true; - break; - } - } - if (!has_paren) return false; - - while (true) { - if (op_stack.back().precedence == precedence_t::PAREN) break; - if (!pop(op_stack, res)) return false; - } - - op_stack.pop_back(); - return true; -} -bool pop_call(size_t n, location_t loc, std::vector> &op_stack, array_t &res) { - map_t call = { - { "$_name", "$_call" }, - }; - - array_t &args = call["args"].array({}); - - while (true) { - if (op_stack.back().precedence == precedence_t::CALL_START) break; - if (!pop(op_stack, res)) return false; - } - loc = loc.intersect(op_stack.back().location); - op_stack.pop_back(); - call["location"] = conv::loc_to_map(loc); - - for (size_t i = 0; i < n; i++) { - args.push_back(res.back()); - res.pop_back(); - } - - std::reverse(args.begin(), args.end()); - - call["func"] = res.back(); - res.pop_back(); - res.push_back(call); - - return true; -} -bool pop_until(const op_data_t &data, tree_helper_t &h, std::vector> &op_stack, array_t &res) { - while (!op_stack.empty()) { - auto &back_data = op_stack.back(); - if (data.assoc ? back_data.precedence >= data.precedence : back_data.precedence > data.precedence) break; - - if (!pop(op_stack, res)) return h.err("Expected an expression on the right side of this operator."); - } - return true; -} - -bool ast::parse_exp_var(ast_ctx_t &ctx, size_t &res_i, map_t &out) { - return ctx.parse(parse_nmsp, res_i, out); -} -bool ast::parse_exp_int_lit(ast_ctx_t &ctx, size_t &res_i, map_t &out) { - tree_helper_t h(ctx, res_i); - - if (h.curr().is_int_literal()) { - auto &arr = out["content"].array({}); - for (auto b : h.curr().literal()) { - arr.push_back((float)b); - } - out["location"] = conv::loc_to_map(h.loc()); - return h.submit(true); - } - - return false; -} -bool ast::parse_exp_str_lit(ast_ctx_t &ctx, size_t &res_i, map_t &out) { - tree_helper_t h(ctx, res_i); - - if (h.curr().is_str_literal()) { - auto &arr = out["content"].array({}); - for (auto b : h.curr().literal()) { - arr.push_back((float)b); - } - out["location"] = conv::loc_to_map(h.loc()); - return h.submit(true); - } - - return false; -} - -bool ast::parse_exp(ast_ctx_t &ctx, size_t &res_i, map_t &out) { - tree_helper_t h(ctx, res_i); - - bool last_val = false; - map_t val; - std::vector> op_stack; - std::vector call_args_n; - auto res = array_t(); - - - while (true) { - if (h.ended()) break; - - if (!last_val && h.curr().is_identifier("sizeof")) { - op_stack.push_back({ h.loc(), sizeof_data }); - h.advance("Expected a value on the right side of the operator."); - continue; - } - if (!last_val && h.push_parse(ctx.group("$_exp_val"), res)) { - last_val = true; - continue; - } - if (h.curr().is_operator()) { - auto op = h.curr()._operator(); - if (last_val) { - if (op == operator_t::PAREN_OPEN) { - h.advance("Expected an argument or closing parens."); - op_stack.push_back({ h.loc(), { precedence_t::CALL_START } }); - if (h.curr().is_operator(operator_t::PAREN_CLOSE)) { - pop_call(0, h.loc(), op_stack, res); - } - else { - call_args_n.push_back(1); - } - last_val = false; - } - else if (op == operator_t::PAREN_CLOSE) { - bool is_call = false, is_paren = false; - - for (auto i = op_stack.rbegin(); i != op_stack.rend(); i++) { - if (i->precedence == precedence_t::PAREN) { - is_paren = true; - break; - } - else if (i->precedence == precedence_t::CALL_START) { - is_call = true; - break; - } - } - - if (is_call) { - pop_call(call_args_n.back(), h.loc(), op_stack, res); - call_args_n.pop_back(); - } - else if (is_paren) pop_paren(op_stack, res); - else break; - - if (!h.try_advance()) break; - } - else if (op == operator_t::COMMA) { - if (call_args_n.size() == 0) break; - h.advance("Expected an argument."); - - pop_until({ .precedence = precedence_t::CALL_START, .assoc = true }, h, op_stack, res); - call_args_n.back()++; - last_val = false; - } - else if (op == operator_t::COLON) { - h.advance("Expected a type."); - pop_until({ .precedence = precedence_t::PREFIX, .assoc = true }, h, op_stack, res); - map_t cast = { - { "$_name", "$_cast" }, - { "exp", res.back() }, - }; - - res.pop_back(); - h.force_parse(parse_type, "Expected a type.", cast["type"].map({})); - cast["location"] = conv::loc_to_map(location_t::intersect( - conv::map_to_loc(cast["exp"].map()["location"].string()), - conv::map_to_loc(cast["type"].map()["location"].string()) - )); - res.push_back(cast); - } - else if (op == operator_t::DOT || op == operator_t::PTR_MEMBER) { - h.advance("Expected an identifier."); - pop_until({ .precedence = precedence_t::POSTFIX, .assoc = true }, h, op_stack, res); - - map_t member_access = { - { "exp", res.back() }, - { "is_ptr", op == operator_t::PTR_MEMBER }, - }; - h.force_parse(parse_identifier, "Expected an identifier.", member_access["name"].map({})); - member_access["location"] = conv::loc_to_map( - conv::map_to_loc(member_access["name"].map()["location"].string()) - .intersect(conv::map_to_loc(res.back().map()["location"].string())) - ); - res.pop_back(); - res.push_back(member_access); - } - else if (bin_ops.find(op) != bin_ops.end()) { - auto data = bin_ops[op]; - pop_until(data, h, op_stack, res); - op_stack.push_back({ h.loc(), data }); - - if (data.op_n == 1) { - last_val = true; - if (!pop(op_stack, res)) return h.err("Expected an expression on the right side of this operator."); - if (h.try_advance()) break; - } - else { - last_val = false; - h.advance("Expected a value on the right side of the operator."); - } - } - else break; - } - else { - if (op == operator_t::PAREN_OPEN) { - op_stack.push_back({ h.loc(), { precedence_t::PAREN } }); - h.advance("Expected a value."); - last_val = false; - } - else if (pre_ops.find(op) != pre_ops.end()) { - op_stack.push_back({ h.loc(), pre_ops[op] }); - h.advance("Expected a value on the right side of the operator."); - } - else break; - } - continue; - } - else break; - } - - if (res.size() == 0) return false; - - while (!op_stack.empty()) { - if (op_stack.back().precedence == precedence_t::PAREN) throw message_t::error("Unclosed paren.", op_stack.back().location); - if (op_stack.back().precedence == precedence_t::CALL_START) throw message_t::error("Unclosed call.", op_stack.back().location); - if (!pop(op_stack, res)) return h.err("Expected an expression on the right side of this operator."); - } - - out = res.front().map(); - - return h.submit(false); -} -bool ast::parse_stat_exp(ast_ctx_t &ctx, size_t &i, map_t &res) { - tree_helper_t h(ctx, i); - if (!h.parse(parse_exp, res)) return false; - if (!h.ended() && h.curr().is_operator(operator_t::SEMICOLON)) return h.submit(true); - - ctx.messages.push(message_t::error("Expected a semicolon.", h.loc(1))); - return h.submit(false); -} diff --git a/src/compiler/treeifier/ast/parsers/export.cc b/src/compiler/treeifier/ast/parsers/export.cc deleted file mode 100644 index 1076020..0000000 --- a/src/compiler/treeifier/ast/parsers/export.cc +++ /dev/null @@ -1,16 +0,0 @@ -#include "compiler/treeifier/ast/helper.hh" - -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 h.submit(false); -} diff --git a/src/compiler/treeifier/ast/parsers/field.cc b/src/compiler/treeifier/ast/parsers/field.cc deleted file mode 100644 index b2815a5..0000000 --- a/src/compiler/treeifier/ast/parsers/field.cc +++ /dev/null @@ -1,38 +0,0 @@ -#include "compiler/treeifier/ast/helper.hh" - -bool ast::parse_field(ast_ctx_t &ctx, size_t &res_i, map_t &out) { - tree_helper_t h(ctx, res_i); - - 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; - - h.throw_ended("Expected a colon or an equals sign."); - - if (h.curr().is_operator(operator_t::COLON)) { - h.advance(); - h.force_parse(parse_type, "Expected a type.", out["type"].map({})); - type = true; - } - if (h.curr().is_operator(operator_t::ASSIGN)) { - h.advance(); - h.force_parse(parse_exp, "Expected an expression.", out["value"].map({})); - type = true; - } - - if (!h.ended() && 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); -} diff --git a/src/compiler/treeifier/ast/parsers/func.cc b/src/compiler/treeifier/ast/parsers/func.cc deleted file mode 100644 index e280a36..0000000 --- a/src/compiler/treeifier/ast/parsers/func.cc +++ /dev/null @@ -1,92 +0,0 @@ -#include "compiler/treeifier/ast/helper.hh" - -static bool parse_arg(ast_ctx_t &ctx, size_t &res_i, map_t &out) { - tree_helper_t h(ctx, res_i); - - 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; - - h.throw_ended("Expected a colon or an equals sign."); - - if (h.curr().is_operator(operator_t::COLON)) { - h.advance(); - h.force_parse(parse_type, "Expected a type.", out["type"].map({})); - type = true; - } - if (h.curr().is_operator(operator_t::ASSIGN)) { - h.advance(); - h.force_parse(parse_exp, "Expected an expression.", out["value"].map({})); - type = true; - } - - if (!type && !defval) { - ctx.messages.push(message_t::error("Expected a type or a default value.", h.loc(1))); - } - - return h.submit(false); -} - -bool ast::parse_func(ast_ctx_t &ctx, size_t &res_i, map_t &out) { - tree_helper_t h(ctx, res_i); - - 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; - h.advance("Expected a closing paren or a parameter."); - - auto ¶ms = out["params"].array({}); - auto &content = out["content"].array({}); - - while (true) { - if (h.curr().is_operator(operator_t::PAREN_CLOSE)) { - h.advance("Expected a function body."); - break; - } - h.force_push_parse(parse_arg, "Expected a parameter.", params); - if (h.curr().is_operator(operator_t::COMMA)) { - h.advance("Expected a parameter."); - } - } - - if (h.curr().is_operator(operator_t::COLON)) { - h.advance("Expected a type."); - h.force_parse(parse_type, "Expected a type", out["type"].map({})); - } - - if (h.curr().is_operator(operator_t::SEMICOLON)) return h.submit(true); - else if (h.curr().is_operator(operator_t::LAMBDA)) { - h.advance("Expected an expression."); - map_t exp; - h.force_parse(parse_exp, "Expected an expression.", exp); - content.push_back({ - { "$_name", "$_return" }, - { "content", exp }, - }); - return h.submit(false); - } - else if (h.curr().is_operator(operator_t::BRACE_OPEN)) { - h.advance("Expected a statement."); - while (true) { - if (h.curr().is_operator(operator_t::BRACE_CLOSE)) { - return h.submit(true); - } - - h.force_push_parse(ctx.group("$_stat"), "Expected an expression.", content); - } - } - else { - ctx.messages.push(message_t::error("Expected a semicolon, brace open or a lambda operator.", h.loc(1))); - return h.submit(false); - } - - return h.submit(true); -} diff --git a/src/compiler/treeifier/ast/parsers/glob.cc b/src/compiler/treeifier/ast/parsers/glob.cc deleted file mode 100644 index a28053f..0000000 --- a/src/compiler/treeifier/ast/parsers/glob.cc +++ /dev/null @@ -1,68 +0,0 @@ -#include "compiler/treeifier/ast.hh" -#include "compiler/treeifier/ast/helper.hh" - -using namespace ppc::comp::tree::ast; - -static bool nmsp_def(ast_ctx_t &ctx, size_t &res_i, data::map_t &res) { - tree_helper_t h(ctx, res_i); - if (h.ended()) return false; - - if (!h.curr().is_identifier("namespace")) return false; - h.advance("Expected a namespace"); - h.force_parse(parse_nmsp, "Expected a namespace.", res); - if (!h.curr().is_operator(operator_t::SEMICOLON)) { - ctx.messages.push(message_t::error("Expected a semicolon.", h.loc(1))); - return h.submit(false); - } - return h.submit(true); -} -static bool import(ast_ctx_t &ctx, size_t &res_i, data::map_t &res) { - tree_helper_t h(ctx, res_i); - if (h.ended()) return false; - - if (!h.curr().is_identifier("import")) return false; - h.advance("Expected a namespace"); - h.force_parse(parse_nmsp, "Expected a namespace.", res); - if (!h.curr().is_operator(operator_t::SEMICOLON)) { - ctx.messages.push(message_t::error("Expected a semicolon.", h.loc(1))); - return h.submit(false); - } - - return h.submit(true); -} - -bool ast::parse_glob(ast_ctx_t &ctx, size_t &res_i, data::map_t &out) { - tree_helper_t h(ctx, res_i); - - if (h.ended()) return true; - if (h.parse(nmsp_def, out["namespace"].map({}))) { - ctx.nmsp = conv::map_to_nmsp(out["namespace"].map()); - } - else { - out["namespace"] = data::null; - } - - auto &imports = out["imports"].array({}); - auto &contents = out["content"].array({}); - - while (true) { - map_t map; - if (!h.parse(import, map)) break; - imports.push_back(map); - auto nmsp = conv::map_to_nmsp(map); - - 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(ctx.group("$_def"), contents)) { - ctx.messages.push(message_t::error("Invalid token.", h.loc())); - h.i++; - } - } - - if (!h.ended()) h.err("Invalid token."); - - return h.submit(); -} diff --git a/src/compiler/treeifier/ast/parsers/group.cc b/src/compiler/treeifier/ast/parsers/group.cc deleted file mode 100644 index 410e511..0000000 --- a/src/compiler/treeifier/ast/parsers/group.cc +++ /dev/null @@ -1,90 +0,0 @@ -#include "lang/module.hh" -#include "compiler/treeifier/ast.hh" -#include "compiler/treeifier/tokenizer.hh" -#include "compiler/treeifier/ast/helper.hh" -#include -#include -#include -#include - -using namespace ppc::comp::tree; -using namespace ppc::comp::tree::ast; -using namespace std::string_literals; -using namespace std; - -static bool read_nmsp(ast_ctx_t &ctx, size_t &i, lang::loc_namespace_name_t &name) { - tree_helper_t h(ctx, i); - map_t res; - if (!h.parse(parse_nmsp, res)) return false; - name = conv::map_to_nmsp(res); - return h.submit(false); -} - - -group_t &group_t::replace(const std::string &name, parser_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; -} -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."; - } - - parsers.emplace(name, parser); - unnamed_parsers.emplace(name); - - return *this; -} -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."; - } - - parsers.emplace(name, parser); - named_parsers.emplace(identifier, name); - - return *this; -} - -bool group_t::operator()(ast_ctx_t &ctx, size_t &i, data::map_t &out) const { - tree_helper_t h(ctx, i); - - if (h.ended()) return false; - - std::set names; - - for (auto &import : ctx.imports) names.insert(import.strip_location()); - - loc_namespace_name_t name; - if (read_nmsp(ctx, h.i, name)) { - namespace_name_t actual; - - if (resolve_name_map( - named_parsers, names, - 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()); - } - } - - for (auto name : unnamed_parsers) { - out["$_name"] = name; - out.clear(); - if (parsers.at(name)(ctx, i, out)) return true; - } - - stringstream m; - - return false; -} diff --git a/src/compiler/treeifier/ast/parsers/identifier.cc b/src/compiler/treeifier/ast/parsers/identifier.cc deleted file mode 100644 index a1119e0..0000000 --- a/src/compiler/treeifier/ast/parsers/identifier.cc +++ /dev/null @@ -1,15 +0,0 @@ -#include "compiler/treeifier/ast/helper.hh" - -bool ast::parse_identifier(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()) { - auto loc = h.loc(); - out["location"] = conv::loc_to_map(loc); - out["content"] = h.curr().identifier(); - return h.submit(); - } - else return false; -} diff --git a/src/compiler/treeifier/ast/parsers/nmsp.cc b/src/compiler/treeifier/ast/parsers/nmsp.cc deleted file mode 100644 index d2cabf5..0000000 --- a/src/compiler/treeifier/ast/parsers/nmsp.cc +++ /dev/null @@ -1,21 +0,0 @@ -#include "compiler/treeifier/ast/helper.hh" - -bool ast::parse_nmsp(ast_ctx_t &ctx, size_t &res_i, map_t &out) { - tree_helper_t h(ctx, res_i); - - if (h.ended()) return false; - - auto &arr = (out["content"] = array_t()).array(); - - if (!h.push_parse(parse_identifier, arr)) return false; - - while (true) { - if (h.ended()) break; - if (!h.curr().is_operator(operator_t::DOUBLE_COLON)) break; - h.advance("Expected an identifier."); - h.force_push_parse(parse_identifier, "Expected an identifier.", arr); - } - - out["location"] = conv::loc_to_map(h.res_loc()); - return h.submit(false); -} diff --git a/src/compiler/treeifier/ast/parsers/stat.cc b/src/compiler/treeifier/ast/parsers/stat.cc deleted file mode 100644 index ff31c03..0000000 --- a/src/compiler/treeifier/ast/parsers/stat.cc +++ /dev/null @@ -1,98 +0,0 @@ -#include "compiler/treeifier/ast/helper.hh" - -bool ast::parse_if(ast_ctx_t &ctx, size_t &res_i, map_t &out) { - tree_helper_t h(ctx, res_i); - - h.throw_ended("Expected open parens after if keyword."); - if (!h.curr("Expected open parens after if keyword.").is_operator(operator_t::PAREN_OPEN)) { - throw message_t::error("Expected open parens after if keyword.", h.loc(1)); - } - - h.advance("Expected an expression."); - h.force_parse(parse_exp, "Expected an expression.", out["condition"].map({})); - - if (!h.curr("Expected closed parens.").is_operator(operator_t::PAREN_CLOSE)) { - throw message_t::error("Expected closed parens.", h.loc(1)); - } - - h.advance("Expected a statement."); - h.force_parse(ctx.group("$_stat"), "Expected a statement.", out["if"].map({})); - - if (h.ended() || !h.curr().is_identifier("else")) return h.submit(false); - - h.advance("Expected a statement."); - h.force_parse(ctx.group("$_stat"), "Expected a statement.", out["else"].map({})); - - return h.submit(false); -} - -bool ast::parse_while(ast_ctx_t &ctx, size_t &res_i, map_t &out) { - tree_helper_t h(ctx, res_i); - - h.throw_ended("Expected open parens after while keyword."); - if (!h.curr("Expected open parens after while keyword.").is_operator(operator_t::PAREN_OPEN)) { - throw message_t::error("Expected open parens after while keyword.", h.loc(1)); - } - - h.advance("Expected an expression."); - h.force_parse(parse_exp, "Expected an expression.", out["condition"].map({})); - - if (!h.curr("Expected closed parens.").is_operator(operator_t::PAREN_CLOSE)) { - throw message_t::error("Expected closed parens.", h.loc(1)); - } - - h.advance("Expected a statement."); - h.force_parse(ctx.group("$_stat"), "Expected a statement.", out["while"].map({})); - - return h.submit(false); -} - -bool ast::parse_return(ast_ctx_t &ctx, size_t &res_i, map_t &out) { - tree_helper_t h(ctx, res_i); - - h.throw_ended("Expected an expression."); - h.force_parse(parse_exp, "Expected an expression.", out["condition"].map({})); - - if (!h.curr("Expected a semicolon.").is_operator(operator_t::SEMICOLON)) { - throw message_t::error("Expected a semicolon.", h.loc(1)); - } - - return h.submit(true); -} - -bool ast::parse_break(ast_ctx_t &ctx, size_t &res_i, map_t &out) { - tree_helper_t h(ctx, res_i); - - if (!h.curr("Expected a semicolon.").is_operator(operator_t::SEMICOLON)) { - throw message_t::error("Expected a semicolon.", h.loc(1)); - } - - return h.submit(true); -} - -bool ast::parse_continue(ast_ctx_t &ctx, size_t &res_i, map_t &out) { - tree_helper_t h(ctx, res_i); - - if (!h.curr("Expected a semicolon.").is_operator(operator_t::SEMICOLON)) { - throw message_t::error("Expected a semicolon.", h.loc(1)); - } - - return h.submit(true); -} - -bool ast::parse_stat_comp(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_operator(operator_t::BRACE_OPEN)) return false; - h.advance("Expected a statement or a closing brace."); - - auto &content = out["content"].array({}); - - while (!h.curr().is_operator(operator_t::BRACE_CLOSE)) { - h.throw_ended("Expected a statement or a closing brace."); - h.push_parse(ctx.group("$_stat"), content); - } - - return h.submit(true); -} \ No newline at end of file diff --git a/src/compiler/treeifier/ast/parsers/struct.cc b/src/compiler/treeifier/ast/parsers/struct.cc deleted file mode 100644 index 4ab0d94..0000000 --- a/src/compiler/treeifier/ast/parsers/struct.cc +++ /dev/null @@ -1,24 +0,0 @@ -#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); -} diff --git a/src/compiler/treeifier/ast/parsers/type.cc b/src/compiler/treeifier/ast/parsers/type.cc deleted file mode 100644 index eebcabf..0000000 --- a/src/compiler/treeifier/ast/parsers/type.cc +++ /dev/null @@ -1,35 +0,0 @@ -#include "compiler/treeifier/ast/helper.hh" - -bool ast::parse_type(ast_ctx_t &ctx, size_t &res_i, map_t &out) { - tree_helper_t h(ctx, res_i); - - if (h.ended()) return false; - - auto &nmsp = out["namespace"].map({}); - size_t ptr_n = 0; - - if (!h.parse(parse_nmsp, nmsp)) return false; - - while (!h.ended() && h.curr().is_operator(operator_t::MULTIPLY)) { - ptr_n++; - if (!h.try_advance()) break; - } - - auto &nmsp_arr = nmsp["content"].array(); - - h.i--; - out["location"] = conv::loc_to_map(h.res_loc()); - h.i++; - out["name"] = nmsp_arr.back(); - out["ptr_n"] = (float)ptr_n; - nmsp_arr.pop_back(); - if (nmsp_arr.empty()) out["namespace"] = null; - else { - auto loc_1 = conv::map_to_loc(nmsp_arr.front().map()["location"].string()); - auto loc_2 = conv::map_to_loc(nmsp_arr.back().map()["location"].string()); - auto loc = loc_1.intersect(loc_2); - nmsp["location"] = conv::loc_to_map(loc); - } - - return h.submit(false); -} diff --git a/src/main.proj b/src/main.proj index dd1bfcc..ba8a6bc 100644 --- a/src/main.proj +++ b/src/main.proj @@ -1,2 +1,2 @@ main -utils, compiler \ No newline at end of file +utils, treeifier \ No newline at end of file diff --git a/src/main/main.cc b/src/main/main.cc index 6e9a029..ce28519 100644 --- a/src/main/main.cc +++ b/src/main/main.cc @@ -17,9 +17,10 @@ #endif #include "./opions.hh" -#include "compiler/treeifier/ast.hh" -#include "compiler/treeifier/lexer.hh" -#include "compiler/treeifier/tokenizer.hh" +#include "treeifier/constr.hh" +#include "treeifier/constr/glob.hh" +#include "treeifier/lexer.hh" +#include "treeifier/tokenizer.hh" #include "utils/json.hh" #include "utils/strings.hh" #include "utils/threading.hh" @@ -31,83 +32,87 @@ using std::cout; using std::size_t; using namespace ppc; -using namespace ppc::comp::tree; -using namespace ppc::comp::tree::ast; +using namespace ppc::tree; +using namespace ppc::tree::constr; void add_flags(options::parser_t &parser) { - parser.add_flag({ .name = "version", - .shorthands = "v", - .description = "Displays version and license agreement of this binary", - .execute = [](options::parser_t &parser, const std::string &option, ppc::messages::msg_stack_t &global_stack) { - cout << "++C compiler\n" - << " Version: v" << PPC_VERSION_MAJOR << '.' << PPC_VERSION_MINOR << '.' << PPC_VERSION_BUILD + parser.add_flag({ + .name = "version", + .shorthands = "v", + .description = "Displays version and license agreement of this binary", + .execute = [](options::parser_t &parser, const std::string &option, ppc::messages::msg_stack_t &global_stack) { + cout << "++C compiler\n"; + cout << " Version: v" << PPC_VERSION_MAJOR << '.' << PPC_VERSION_MINOR << '.' << PPC_VERSION_BUILD; #if WINDOWS - << " (Windows)" + cout << " (Windows)"; #elif LINUX - << " (Linux)" + cout << " (Linux)"; #endif - << "\n" - << " License: MIT Copyright (C) TopchetoEU\n"; - exit(0); - } }); - parser.add_flag({ .name = "help", - .shorthands = "h", - .description = "Displays a list of all flags and their meaning", - .execute = [](options::parser_t &parser, const std::string &option, ppc::messages::msg_stack_t &global_stack) { - cout << "Usage: ...flags ...files\n\n" - << "Flags and file names can be interlaced\n" - << "Flags will execute in the order they're written, then compilation begins\n\n" - << "Flags:\n"; + cout << "\n"; + cout << " License: MIT Copyright (C) TopchetoEU\n"; + exit(0); + } + }); + parser.add_flag({ + .name = "help", + .shorthands = "h", + .description = "Displays a list of all flags and their meaning", + .execute = [](options::parser_t &parser, const std::string &option, ppc::messages::msg_stack_t &global_stack) { + cout << "Usage: ...flags ...files\n\n"; + cout << "Flags and file names can be interlaced\n"; + cout << "Flags will execute in the order they're written, then compilation begins\n\n"; + cout << "Flags:\n"; - for (const auto &flag : parser) { - std::stringstream buff; - buff << " --" << flag.name; + for (const auto &flag : parser) { + std::stringstream buff; + buff << " --" << flag.name; - if (flag.match_type) buff << "=..."; - if (flag.shorthands.size()) { - buff << " ("; - bool first = true; - for (char shorthand : flag.shorthands) { - if (!first) buff << ","; - else first = false; + if (flag.match_type) buff << "=..."; + if (flag.shorthands.size()) { + buff << " ("; + bool first = true; + for (char shorthand : flag.shorthands) { + if (!first) buff << ","; + else first = false; - buff << " -"; - buff << std::string { shorthand }; - } - buff << ")"; - } + buff << " -"; + buff << std::string { shorthand }; + } + buff << ")"; + } - buff << " "; + buff << " "; - cout << buff.str(); - size_t n = buff.str().length(); + cout << buff.str(); + size_t n = buff.str().length(); - if (flag.description.size()) { - const size_t padding = 24; - const size_t msg_width = 80 - padding; + if (flag.description.size()) { + const size_t padding = 24; + const size_t msg_width = 80 - padding; - for (size_t i = 0; i < padding - n; i++) - cout << ' '; + for (size_t i = 0; i < padding - n; i++) + cout << ' '; - int len = flag.description.length(); + int len = flag.description.length(); - for (size_t i = 0; i < len / msg_width; i++) { - for (size_t j = 0; j < msg_width; j++) - cout << flag.description[i * msg_width + j]; - cout << std::endl; - for (size_t j = 0; j < padding; j++) - cout << ' '; - } + for (size_t i = 0; i < len / msg_width; i++) { + for (size_t j = 0; j < msg_width; j++) + cout << flag.description[i * msg_width + j]; + cout << std::endl; + for (size_t j = 0; j < padding; j++) + cout << ' '; + } - int remainder = len % msg_width; + int remainder = len % msg_width; - for (int i = 0; i < remainder; i++) - cout << flag.description[len - remainder + i]; - } + for (int i = 0; i < remainder; i++) + cout << flag.description[len - remainder + i]; + } - printf("\n"); - } - } }); + printf("\n"); + } + } + }); parser.add_flag({ .name = "silent", .shorthands = "qs", @@ -118,12 +123,14 @@ void add_flags(options::parser_t &parser) { .description = "Sets a lower limit of messages that will print. Accepted values: 'all', 'debug', 'suggestion', 'info', 'warning', 'error', 'none'", .match_type = options::MATCH_PREFIX, }); - parser.add_flag({ .name = "print-what", - .description = "Prints a 'what?' type of message (you'll see)", - .match_type = options::MATCH_PREFIX, - .execute = [](options::parser_t &parser, const std::string &option, ppc::messages::msg_stack_t &global_stack) { - global_stack.push(messages::message_t((messages::message_t::level_t)69, "IDK LOL.")); - } }); + parser.add_flag({ + .name = "print-what", + .description = "Prints a 'what?' type of message (you'll see)", + .match_type = options::MATCH_PREFIX, + .execute = [](options::parser_t &parser, const std::string &option, ppc::messages::msg_stack_t &global_stack) { + global_stack.push(messages::message_t((messages::message_t::level_t)69, "IDK LOL.")); + } + }); } int main(int argc, const char *argv[]) { @@ -156,9 +163,8 @@ int main(int argc, const char *argv[]) { std::ifstream f { file, std::ios_base::in }; 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(ast::parse_glob, msg_stack, tokens); - - std::cout << data::json::stringify(ast) << std::endl; + auto ast = ast_ctx_t::parse(constr::glob_parser_t(), msg_stack, tokens); + // std::cout << data::json::stringify(ast) << std::endl; } catch (const messages::message_t &msg) { msg_stack.push(msg); diff --git a/src/compiler.proj b/src/treeifier.proj similarity index 52% rename from src/compiler.proj rename to src/treeifier.proj index 6fa4f42..d34bf8b 100644 --- a/src/compiler.proj +++ b/src/treeifier.proj @@ -1,2 +1,2 @@ -compiler +treeifier utils, lang \ No newline at end of file diff --git a/src/treeifier/ast.cc b/src/treeifier/ast.cc new file mode 100644 index 0000000..6063987 --- /dev/null +++ b/src/treeifier/ast.cc @@ -0,0 +1,36 @@ +#include "treeifier/constr.hh" +#include + +using namespace ppc; +using namespace ppc::data; +using namespace ppc::lang; +using namespace ppc::tree::constr; + +// ppc::tree::constr::inspoint_t &ast_ctx_t::group(const std::string &name) { +// if (groups.find(name) == groups.end()) return groups[name] = {}; +// else return groups[name]; +// } + +ast_ctx_t::ast_ctx_t(msg_stack_t &messages, std::vector &tokens): + messages(messages), tokens(tokens) { + // group("$_exp_val") + // .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("$_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("$_func", parse_func) + // .add("$_struct", { "struct" }, parse_struct) + // .add("$_field", parse_field); + // group("$_struct_def") + // .add("$_func", parse_func) + // .add("$_field", parse_field); +} diff --git a/src/treeifier/constr/glob.cc b/src/treeifier/constr/glob.cc new file mode 100644 index 0000000..cc23fa6 --- /dev/null +++ b/src/treeifier/constr/glob.cc @@ -0,0 +1,41 @@ +#include "treeifier/constr/glob.hh" +#include "treeifier/constr/helper.hh" +#include "treeifier/constr/nmsp.hh" + +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); + 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); + + if (!h.curr().is_operator(operator_t::SEMICOLON)) { + ctx.messages.push(message_t::error("Expected a semicolon.", h.loc(1))); + } + + if (!h.try_advance()) return h.submit(false); + } + + while (h.curr().is_identifier("import")) { + loc_namespace_name_t res; + + h.advance("Expected a namespace"); + h.force_parse(nmsp_parser_t(), "Expected a namespace.", res); + + if (!h.curr().is_operator(operator_t::SEMICOLON)) { + ctx.messages.push(message_t::error("Expected a semicolon.", h.loc(1))); + } + + out.imports.push_back(res); + if (!h.try_advance()) return h.submit(false); + } + + if (!h.ended()) h.err("Invalid token."); + + return h.submit(false); +} diff --git a/src/treeifier/constr/identifier.cc b/src/treeifier/constr/identifier.cc new file mode 100644 index 0000000..695ec42 --- /dev/null +++ b/src/treeifier/constr/identifier.cc @@ -0,0 +1,16 @@ +#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& out) const { + parse_helper_t h(ctx, res_i); + + if (h.ended()) return false; + + if (h.curr().is_identifier()) { + out = located_t(h.loc(), h.curr().identifier()); + return h.submit(); + } + else return false; +} diff --git a/src/treeifier/constr/nmsp.cc b/src/treeifier/constr/nmsp.cc new file mode 100644 index 0000000..942600a --- /dev/null +++ b/src/treeifier/constr/nmsp.cc @@ -0,0 +1,26 @@ +#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 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); +} diff --git a/src/compiler/treeifier/lexer.cc b/src/treeifier/lexer.cc similarity index 98% rename from src/compiler/treeifier/lexer.cc rename to src/treeifier/lexer.cc index b12b3b9..d17352f 100644 --- a/src/compiler/treeifier/lexer.cc +++ b/src/treeifier/lexer.cc @@ -1,10 +1,10 @@ -#include "compiler/treeifier/lexer.hh" +#include "treeifier/lexer.hh" #include "utils/message.hh" #include using namespace ppc; using namespace ppc::messages; -using namespace ppc::comp::tree::lex; +using namespace ppc::tree::lex; struct res_t; using lexlet_t = res_t (*)(char c, std::vector &tok); diff --git a/src/compiler/treeifier/operators.cc b/src/treeifier/operators.cc similarity index 89% rename from src/compiler/treeifier/operators.cc rename to src/treeifier/operators.cc index 584c264..d3fc66a 100644 --- a/src/compiler/treeifier/operators.cc +++ b/src/treeifier/operators.cc @@ -1,8 +1,8 @@ -#include "compiler/treeifier/tokenizer.hh" +#include "treeifier/tokenizer.hh" #include -using namespace ppc::comp::tree; -using namespace ppc::comp; +using namespace ppc; +using namespace ppc::tree; using namespace std::string_literals; diff --git a/src/compiler/treeifier/tokenizer.cc b/src/treeifier/tokenizer.cc similarity index 98% rename from src/compiler/treeifier/tokenizer.cc rename to src/treeifier/tokenizer.cc index 2da0e7d..b03b009 100644 --- a/src/compiler/treeifier/tokenizer.cc +++ b/src/treeifier/tokenizer.cc @@ -1,11 +1,11 @@ -#include "compiler/treeifier/lexer.hh" -#include "compiler/treeifier/tokenizer.hh" +#include "treeifier/lexer.hh" +#include "treeifier/tokenizer.hh" #include #include using namespace ppc; using namespace messages; -using namespace comp::tree; +using namespace ppc::tree; using namespace std::string_literals; static std::vector parse_string(msg_stack_t &msg_stack, bool is_char, const lex::token_t &token) {