From b6b68b25043fc4008af6c7bfb4573593a858a9de Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Fri, 3 Jul 2026 11:09:44 +0200 Subject: Rename frontend to boot(strap) --- include/elna/boot/ast.h | 800 +++++++++++++++++++++++++++++++++++++ include/elna/boot/dependency.h | 55 +++ include/elna/boot/driver.h | 51 +++ include/elna/boot/result.h | 124 ++++++ include/elna/boot/semantic.h | 192 +++++++++ include/elna/boot/symbol.h | 457 +++++++++++++++++++++ include/elna/frontend/ast.h | 800 ------------------------------------- include/elna/frontend/dependency.h | 55 --- include/elna/frontend/driver.h | 51 --- include/elna/frontend/result.h | 124 ------ include/elna/frontend/semantic.h | 192 --------- include/elna/frontend/symbol.h | 457 --------------------- include/elna/gcc/elna-builtins.h | 10 +- include/elna/gcc/elna-diagnostic.h | 6 +- include/elna/gcc/elna-generic.h | 92 ++--- include/elna/gcc/elna-tree.h | 12 +- 16 files changed, 1739 insertions(+), 1739 deletions(-) create mode 100644 include/elna/boot/ast.h create mode 100644 include/elna/boot/dependency.h create mode 100644 include/elna/boot/driver.h create mode 100644 include/elna/boot/result.h create mode 100644 include/elna/boot/semantic.h create mode 100644 include/elna/boot/symbol.h delete mode 100644 include/elna/frontend/ast.h delete mode 100644 include/elna/frontend/dependency.h delete mode 100644 include/elna/frontend/driver.h delete mode 100644 include/elna/frontend/result.h delete mode 100644 include/elna/frontend/semantic.h delete mode 100644 include/elna/frontend/symbol.h (limited to 'include') diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h new file mode 100644 index 0000000..7d94e84 --- /dev/null +++ b/include/elna/boot/ast.h @@ -0,0 +1,800 @@ +/* Abstract syntax tree representation. + Copyright (C) 2025 Free Software Foundation, Inc. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#pragma once + +#include +#include +#include +#include +#include +#include "elna/boot/symbol.h" +#include "elna/boot/result.h" + +namespace elna::boot +{ + enum class binary_operator + { + sum, + subtraction, + multiplication, + division, + remainder, + equals, + not_equals, + less, + greater, + less_equal, + greater_equal, + disjunction, + conjunction, + exclusive_disjunction, + shift_left, + shift_right + }; + + enum class unary_operator + { + reference, + negation, + minus + }; + + class variable_declaration; + class constant_declaration; + class procedure_declaration; + class type_declaration; + class procedure_call; + class cast_expression; + class assign_statement; + class if_statement; + class import_declaration; + class while_statement; + class return_statement; + class case_statement; + class traits_expression; + class unit; + class program; + class binary_expression; + class unary_expression; + class type_expression; + class array_type_expression; + class pointer_type_expression; + class record_type_expression; + class union_type_expression; + class procedure_type_expression; + class enumeration_type_expression; + class named_expression; + class array_access_expression; + class field_access_expression; + class dereference_expression; + class designator_expression; + class literal_expression; + template + class literal; + class defer_statement; + + /** + * Interface for AST visitors. + */ + struct parser_visitor + { + virtual void visit(variable_declaration *) = 0; + virtual void visit(constant_declaration *) = 0; + virtual void visit(procedure_declaration *) = 0; + virtual void visit(type_declaration *) = 0; + virtual void visit(procedure_call *) = 0; + virtual void visit(cast_expression *) = 0; + virtual void visit(traits_expression *) = 0; + virtual void visit(assign_statement *) = 0; + virtual void visit(if_statement *) = 0; + virtual void visit(import_declaration *) = 0; + virtual void visit(while_statement *) = 0; + virtual void visit(return_statement *) = 0; + virtual void visit(defer_statement *) = 0; + virtual void visit(case_statement *) = 0; + virtual void visit(unit *) = 0; + virtual void visit(program *) = 0; + virtual void visit(binary_expression *) = 0; + virtual void visit(unary_expression *) = 0; + virtual void visit(type_expression *) = 0; + virtual void visit(array_type_expression *) = 0; + virtual void visit(pointer_type_expression *) = 0; + virtual void visit(record_type_expression *) = 0; + virtual void visit(union_type_expression *) = 0; + virtual void visit(procedure_type_expression *) = 0; + virtual void visit(enumeration_type_expression *) = 0; + virtual void visit(named_expression *) = 0; + virtual void visit(array_access_expression *) = 0; + virtual void visit(field_access_expression *) = 0; + virtual void visit(dereference_expression *) = 0; + virtual void visit(literal *) = 0; + virtual void visit(literal *) = 0; + virtual void visit(literal *) = 0; + virtual void visit(literal *) = 0; + virtual void visit(literal *) = 0; + virtual void visit(literal *) = 0; + virtual void visit(literal *) = 0; + }; + + /** + * Abstract visitor that doesn't visit any nodes by default. + */ + class empty_visitor : public parser_visitor + { + [[noreturn]] void not_implemented(); + + public: + [[noreturn]] virtual void visit(type_expression *) override; + [[noreturn]] virtual void visit(array_type_expression *) override; + [[noreturn]] virtual void visit(pointer_type_expression *) override; + [[noreturn]] virtual void visit(program *) override; + [[noreturn]] virtual void visit(type_declaration *) override; + [[noreturn]] virtual void visit(record_type_expression *) override; + [[noreturn]] virtual void visit(union_type_expression *) override; + [[noreturn]] virtual void visit(procedure_type_expression *) override; + [[noreturn]] virtual void visit(enumeration_type_expression *) override; + + [[noreturn]] virtual void visit(variable_declaration *) override; + [[noreturn]] virtual void visit(constant_declaration *) override; + [[noreturn]] virtual void visit(procedure_declaration *) override; + [[noreturn]] virtual void visit(assign_statement *) override; + [[noreturn]] virtual void visit(if_statement *) override; + [[noreturn]] virtual void visit(import_declaration *) override; + [[noreturn]] virtual void visit(while_statement *) override; + [[noreturn]] virtual void visit(return_statement *) override; + [[noreturn]] virtual void visit(defer_statement *) override; + [[noreturn]] virtual void visit(case_statement *) override; + [[noreturn]] virtual void visit(procedure_call *) override; + [[noreturn]] virtual void visit(unit *) override; + [[noreturn]] virtual void visit(cast_expression *) override; + [[noreturn]] virtual void visit(traits_expression *) override; + [[noreturn]] virtual void visit(binary_expression *) override; + [[noreturn]] virtual void visit(unary_expression *) override; + [[noreturn]] virtual void visit(named_expression *) override; + [[noreturn]] virtual void visit(array_access_expression *) override; + [[noreturn]] virtual void visit(field_access_expression *) override; + [[noreturn]] virtual void visit(dereference_expression *) override; + [[noreturn]] virtual void visit(literal *) override; + [[noreturn]] virtual void visit(literal *) override; + [[noreturn]] virtual void visit(literal *) override; + [[noreturn]] virtual void visit(literal *) override; + [[noreturn]] virtual void visit(literal *) override; + [[noreturn]] virtual void visit(literal *) override; + [[noreturn]] virtual void visit(literal *) override; + }; + + /** + * AST node. + */ + class node + { + const struct position source_position; + + protected: + /** + * \param position Source code position. + */ + explicit node(const position position); + + public: + virtual void accept(parser_visitor *visitor) = 0; + virtual ~node() = 0; + + /** + * \return Node position in the source code. + */ + const struct position& position() const; + }; + + class statement : public virtual node + { + }; + + class expression : public virtual node + { + public: + virtual cast_expression *is_cast(); + virtual traits_expression *is_traits(); + virtual binary_expression *is_binary(); + virtual unary_expression *is_unary(); + virtual designator_expression *is_designator(); + virtual procedure_call *is_call_expression(); + virtual literal_expression *is_literal(); + }; + + /** + * Symbol definition. + */ + class declaration : public node + { + protected: + declaration(const struct position position, identifier_definition identifier); + + public: + const identifier_definition identifier; + }; + + /** + * Some type expression. + */ + class type_expression : public virtual node + { + public: + virtual named_expression *is_named(); + virtual array_type_expression *is_array(); + virtual pointer_type_expression *is_pointer(); + virtual record_type_expression *is_record(); + virtual union_type_expression *is_union(); + virtual procedure_type_expression *is_procedure(); + virtual enumeration_type_expression *is_enumeration(); + + void accept(parser_visitor *visitor) override; + ~type_expression() = 0; + }; + + class array_type_expression : public type_expression + { + type_expression *m_base; + + public: + const std::uint32_t size; + + array_type_expression(const struct position position, + type_expression *base, const std::uint32_t size); + ~array_type_expression(); + + void accept(parser_visitor *visitor) override; + array_type_expression *is_array() override; + + type_expression& base(); + }; + + class pointer_type_expression : public type_expression + { + type_expression *m_base; + + public: + pointer_type_expression(const struct position position, type_expression *base); + ~pointer_type_expression(); + + void accept(parser_visitor *visitor) override; + pointer_type_expression *is_pointer() override; + + type_expression& base(); + }; + + using field_declaration = std::pair; + + class record_type_expression : public type_expression + { + public: + const std::vector fields; + + record_type_expression(const struct position position, std::vector&& fields); + ~record_type_expression(); + + void accept(parser_visitor *visitor) override; + record_type_expression *is_record() override; + }; + + class union_type_expression : public type_expression + { + public: + std::vector fields; + + union_type_expression(const struct position position, std::vector&& fields); + ~union_type_expression(); + + void accept(parser_visitor *visitor) override; + union_type_expression *is_union() override; + }; + + /** + * Enumeration type. + */ + class enumeration_type_expression : public type_expression + { + public: + const std::vector members; + + enumeration_type_expression(const struct position, std::vector&& members); + + void accept(parser_visitor *visitor) override; + enumeration_type_expression *is_enumeration() override; + }; + + /** + * Variable declaration. + */ + class variable_declaration : public node + { + std::shared_ptr m_variable_type; + + public: + variable_declaration(const struct position position, + std::vector&& identifier, std::shared_ptr variable_type, + expression *body = nullptr); + variable_declaration(const struct position position, + std::vector&& identifier, std::shared_ptr variable_type, + std::monostate); + + void accept(parser_visitor *visitor) override; + + bool has_initializer() const; + + const std::vector identifiers; + type_expression& variable_type(); + expression *const body{ nullptr }; + const bool is_extern{ false }; + }; + + /** + * Literal expression. + */ + class literal_expression : public expression + { + public: + literal_expression *is_literal() override; + }; + + /** + * Constant definition. + */ + class constant_declaration : public declaration + { + expression *m_body; + + public: + constant_declaration(const struct position position, identifier_definition identifier, + expression *body); + void accept(parser_visitor *visitor) override; + + expression& body(); + + virtual ~constant_declaration() override; + }; + + /** + * Procedure type. + */ + class procedure_type_expression : public type_expression + { + public: + using return_t = return_declaration; + + const return_t return_type; + std::vector parameters; + + procedure_type_expression(const struct position position, return_t return_type = return_t()); + ~procedure_type_expression(); + + void accept(parser_visitor *visitor) override; + procedure_type_expression *is_procedure() override; + }; + + struct block + { + block(std::vector&& constants, std::vector&& variables, + std::vector&& body); + block(std::vector&& constants, std::vector&& variables); + block(const block&) = delete; + block(block&& that); + + block& operator=(const block&) = delete; + block& operator=(block&& that); + + const std::vector& variables(); + const std::vector& constants(); + const std::vector& body(); + + virtual ~block(); + + private: + std::vector m_variables; + std::vector m_constants; + std::vector m_body; + + }; + + /** + * Procedure definition. + */ + class procedure_declaration : public declaration + { + procedure_type_expression *m_heading; + + public: + std::optional body; + std::vector parameter_names; + + procedure_declaration(const struct position position, identifier_definition identifier, + procedure_type_expression *heading, block&& body); + procedure_declaration(const struct position position, identifier_definition identifier, + procedure_type_expression *heading); + void accept(parser_visitor *visitor) override; + + procedure_type_expression& heading(); + + virtual ~procedure_declaration() override; + }; + + /** + * Type definition. + */ + class type_declaration : public declaration + { + type_expression *m_body; + + public: + type_declaration(const struct position position, identifier_definition identifier, + type_expression *expression); + ~type_declaration(); + + void accept(parser_visitor *visitor) override; + + type_expression& body(); + }; + + /** + * Cast expression. + */ + class cast_expression : public expression + { + type_expression *m_target; + expression *m_value; + + public: + type expression_type; + + cast_expression(const struct position position, type_expression *target, expression *value); + void accept(parser_visitor *visitor) override; + cast_expression *is_cast() override; + + type_expression& target(); + expression& value(); + + virtual ~cast_expression() override; + }; + + class traits_expression : public expression + { + public: + std::vector parameters; + const std::string name; + std::vector types; + + traits_expression(const struct position position, const std::string& name); + ~traits_expression(); + + void accept(parser_visitor *visitor) override; + traits_expression *is_traits() override; + }; + + /** + * List of statements paired with a condition. + */ + class conditional_statements + { + expression *m_prerequisite; + + public: + const std::vector statements; + + conditional_statements(expression *prerequisite, std::vector&& statements); + + expression& prerequisite(); + + virtual ~conditional_statements(); + }; + + class return_statement : public statement + { + public: + expression *m_return_expression; + + return_statement(const struct position position, expression *return_expression); + void accept(parser_visitor *visitor) override; + + expression& return_expression(); + + virtual ~return_statement() override; + }; + + struct switch_case + { + std::vector labels; + std::vector statements; + }; + + class case_statement : public statement + { + expression *m_condition; + + public: + const std::vector cases; + const std::vector *alternative; + + case_statement(const struct position position, expression *condition, + std::vector&& cases, std::vector *alternative = nullptr); + void accept(parser_visitor *visitor) override; + expression& condition(); + }; + + class designator_expression : public expression + { + public: + virtual named_expression *is_named(); + virtual array_access_expression *is_array_access(); + virtual field_access_expression *is_field_access(); + virtual dereference_expression *is_dereference(); + + designator_expression *is_designator() override; + void accept(parser_visitor *visitor); + ~designator_expression() = 0; + }; + + /** + * Expression refering to an entity by its name. + */ + class named_expression : public designator_expression, public type_expression + { + public: + const std::string name; + + named_expression(const struct position position, const std::string& name); + void accept(parser_visitor *visitor) override; + + named_expression *is_named() override; + }; + + class array_access_expression : public designator_expression + { + expression *m_base; + expression *m_index; + + public: + array_access_expression(const struct position position, expression *base, expression *index); + void accept(parser_visitor *visitor) override; + + expression& base(); + expression& index(); + + array_access_expression *is_array_access() override; + + ~array_access_expression() override; + }; + + class field_access_expression : public designator_expression + { + expression *m_base; + std::string m_field; + + public: + field_access_expression(const struct position position, expression *base, + const std::string& field); + void accept(parser_visitor *visitor) override; + + expression& base(); + std::string& field(); + + field_access_expression *is_field_access() override; + + ~field_access_expression() override; + }; + + class dereference_expression : public designator_expression + { + expression *m_base; + + public: + dereference_expression(const struct position position, expression *base); + void accept(parser_visitor *visitor) override; + + expression& base(); + + dereference_expression *is_dereference() override; + + ~dereference_expression() override; + }; + + /** + * Procedure call expression. + */ + class procedure_call : public expression, public statement + { + designator_expression *m_callable; + + public: + std::vector arguments; + + procedure_call(const struct position position, designator_expression *callable); + void accept(parser_visitor *visitor) override; + virtual procedure_call *is_call_expression() override; + + designator_expression& callable(); + + virtual ~procedure_call() override; + }; + + class assign_statement : public statement + { + designator_expression *m_lvalue; + expression *m_rvalue; + + public: + /** + * \param position Source code position. + * \param lvalue Left-hand side. + * \param rvalue Assigned expression. + */ + assign_statement(const struct position position, designator_expression *lvalue, + expression *rvalue); + void accept(parser_visitor *visitor) override; + + designator_expression& lvalue(); + expression& rvalue(); + + virtual ~assign_statement() override; + }; + + /** + * If-statement. + */ + class if_statement : public statement + { + conditional_statements *m_body; + + public: + const std::vector branches; + const std::vector *alternative; + + if_statement(const struct position position, conditional_statements *body, + std::vector&& branches, + std::vector *alternative = nullptr); + void accept(parser_visitor *visitor) override; + + conditional_statements& body(); + + virtual ~if_statement() override; + }; + + /** + * Import statement. + */ + class import_declaration : public node + { + public: + const std::vector segments; + + import_declaration(const struct position position, std::vector&& segments); + void accept(parser_visitor *visitor) override; + }; + + /** + * While-statement. + */ + class while_statement : public statement + { + conditional_statements *m_body; + + public: + const std::vector branches; + + while_statement(const struct position position, conditional_statements *body, + std::vector&& branches); + void accept(parser_visitor *visitor) override; + + conditional_statements& body(); + + virtual ~while_statement() override; + }; + + class unit : public node + { + public: + std::vector imports; + std::vector constants; + std::vector types; + std::vector variables; + std::vector procedures; + + unit(const struct position position); + virtual void accept(parser_visitor *visitor) override; + + virtual ~unit() override; + }; + + class program : public unit + { + public: + std::vector body; + + program(const struct position position); + void accept(parser_visitor *visitor) override; + + virtual ~program() override; + }; + + template + class literal : public literal_expression + { + public: + T value; + + literal(const struct position position, const T& value) + : node(position), value(value) + { + } + + void accept(parser_visitor *visitor) override + { + visitor->visit(this); + } + }; + + class defer_statement : public statement + { + public: + const std::vector statements; + + defer_statement(const struct position position, std::vector&& statements); + void accept(parser_visitor *visitor) override; + + virtual ~defer_statement() override; + }; + + class binary_expression : public expression + { + expression *m_lhs; + expression *m_rhs; + binary_operator m_operator; + + public: + binary_expression(const struct position position, expression *lhs, + expression *rhs, const binary_operator operation); + + void accept(parser_visitor *visitor) override; + binary_expression *is_binary() override; + + expression& lhs(); + expression& rhs(); + binary_operator operation() const; + + virtual ~binary_expression() override; + }; + + class unary_expression : public expression + { + expression *m_operand; + unary_operator m_operator; + + public: + unary_expression(const struct position position, expression *operand, + const unary_operator operation); + + void accept(parser_visitor *visitor) override; + unary_expression *is_unary() override; + + expression& operand(); + unary_operator operation() const; + + virtual ~unary_expression() override; + }; + + const char *print_binary_operator(const binary_operator operation); +} diff --git a/include/elna/boot/dependency.h b/include/elna/boot/dependency.h new file mode 100644 index 0000000..4ec4d44 --- /dev/null +++ b/include/elna/boot/dependency.h @@ -0,0 +1,55 @@ +/* Dependency graph analysis. + Copyright (C) 2025 Free Software Foundation, Inc. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#pragma once + +#include +#include +#include "elna/boot/result.h" +#include "elna/boot/ast.h" +#include "elna/boot/symbol.h" + +namespace elna::boot +{ + class dependency : public error_container + { + error_list m_errors; + + public: + std::unique_ptr tree; + forward_table unresolved; + + explicit dependency(const char *path); + }; + + dependency read_source(std::istream& entry_point, const char *entry_path); + std::filesystem::path build_path(const std::vector& segments); + error_list analyze_semantics(const char *path, std::unique_ptr& tree, symbol_bag bag); + + template + struct dependency_state + { + const std::shared_ptr globals; + T custom; + std::unordered_map cache; + + explicit dependency_state(T custom) + : globals(builtin_symbol_table()), custom(custom) + { + } + }; +} diff --git a/include/elna/boot/driver.h b/include/elna/boot/driver.h new file mode 100644 index 0000000..288aa0c --- /dev/null +++ b/include/elna/boot/driver.h @@ -0,0 +1,51 @@ +/* Parsing driver. + Copyright (C) 2025 Free Software Foundation, Inc. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#pragma once + +#include +#include "elna/boot/ast.h" +#include "location.hh" + +namespace elna::boot +{ + position make_position(const yy::location& location); + + class syntax_error final : public error + { + std::string message; + + public: + syntax_error(const std::string& message, + const char *input_file, const yy::location& location); + + virtual std::string what() const override; + }; + + class driver : public error_container + { + public: + std::unique_ptr tree; + + driver(const char *input_file); + }; + + constexpr char escape_invalid_char = '\xff'; + + char escape_char(char escape); + std::optional escape_string(const char *escape); +} diff --git a/include/elna/boot/result.h b/include/elna/boot/result.h new file mode 100644 index 0000000..9fc1849 --- /dev/null +++ b/include/elna/boot/result.h @@ -0,0 +1,124 @@ +/* Miscellaneous types used across stage boundaries. + Copyright (C) 2025 Free Software Foundation, Inc. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace elna::boot +{ + /** + * Position in the source text. + */ + struct position + { + /// Line. + std::size_t line = 1; + + /// Column. + std::size_t column = 1; + }; + + /** + * A compilation error consists of an error message and position. + */ + class error + { + protected: + error(const char *path, const struct position position); + + public: + const struct position position; + const char *path; + + virtual ~error() = default; + + /// Error text. + virtual std::string what() const = 0; + + /// Error line in the source text. + std::size_t line() const; + + /// Error column in the source text. + std::size_t column() const; + }; + + using error_list = typename std::deque>; + + class error_container + { + protected: + error_list m_errors; + + error_container(const char *input_file); + + public: + const char *input_file; + + error_list& errors(); + + template + void add_error(Args... arguments) + { + auto new_error = std::make_unique(arguments...); + m_errors.emplace_back(std::move(new_error)); + } + + bool has_errors() const; + }; + + /** + * Tags a procedure type as never returning. + */ + template + struct return_declaration + { + return_declaration() = default; + + explicit return_declaration(T type) + : proper_type(type) + { + } + + explicit return_declaration(std::monostate) + : no_return(true) + { + } + + T proper_type{}; + bool no_return{ false }; + }; + + struct identifier_definition + { + std::string name; + bool exported; + + bool operator==(const identifier_definition& that) const; + bool operator==(const std::string& that) const; + }; +} + +template<> +struct std::hash +{ + std::size_t operator()(const elna::boot::identifier_definition& key) const noexcept; +}; diff --git a/include/elna/boot/semantic.h b/include/elna/boot/semantic.h new file mode 100644 index 0000000..66eb0a7 --- /dev/null +++ b/include/elna/boot/semantic.h @@ -0,0 +1,192 @@ +/* Name analysis. + Copyright (C) 2025 Free Software Foundation, Inc. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#pragma once + +#include +#include +#include +#include + +#include "elna/boot/ast.h" +#include "elna/boot/result.h" +#include "elna/boot/symbol.h" + +namespace elna::boot +{ + class undeclared_error : public error + { + const std::string identifier; + + public: + undeclared_error(const std::string& identifier, const char *path, const struct position position); + + std::string what() const override; + }; + + class already_declared_error : public error + { + const std::string identifier; + + public: + already_declared_error(const std::string& identifier, const char *path, const struct position position); + + std::string what() const override; + }; + + class field_duplication_error : public error + { + const std::string field_name; + + public: + field_duplication_error(const std::string& field_name, const char *path, const struct position position); + + std::string what() const override; + }; + + class cyclic_declaration_error : public error + { + const std::vector cycle; + + public: + cyclic_declaration_error(const std::vector& cycle, + const char *path, const struct position position); + + std::string what() const override; + }; + + class return_error : public error + { + const std::string identifier; + + public: + return_error(const std::string& identifier, const char *path, const struct position position); + + std::string what() const override; + }; + + class variable_initializer_error : public error + { + public: + variable_initializer_error(const char *path, const struct position position); + + std::string what() const override; + }; + + /** + * Checks types. + */ + class type_analysis_visitor final : public empty_visitor, public error_container + { + bool returns; + symbol_bag bag; + + bool check_unresolved_symbol(std::shared_ptr alias, + std::vector& path); + + public: + explicit type_analysis_visitor(const char *path, symbol_bag bag); + + void visit(program *program) override; + + void visit(procedure_declaration *definition) override; + void visit(assign_statement *) override; + void visit(if_statement *) override; + void visit(while_statement *) override; + void visit(return_statement *) override; + void visit(defer_statement *) override; + void visit(case_statement *) override; + void visit(procedure_call *) override; + void visit(unit *unit) override; + void visit(type_declaration *definition) override; + }; + + /** + * Performs name analysis. + */ + class name_analysis_visitor final : public parser_visitor, public error_container + { + type current_type; + constant_info::variant current_literal; + + symbol_bag bag; + + procedure_type build_procedure(procedure_type_expression& type_expression); + std::vector build_composite_type(const std::vector& fields); + std::shared_ptr register_variable(const std::string& name, + const bool is_extern, const struct position position); + + public: + name_analysis_visitor(const char *path, symbol_bag bag); + + void visit(type_expression *) override; + void visit(array_type_expression *type_expression) override; + void visit(pointer_type_expression *type_expression) override; + void visit(program *program) override; + void visit(type_declaration *definition) override; + void visit(record_type_expression *type_expression) override; + void visit(union_type_expression *type_expression) override; + void visit(procedure_type_expression *type_expression) override; + void visit(enumeration_type_expression *type_expression) override; + + void visit(variable_declaration *declaration) override; + void visit(constant_declaration *definition) override; + void visit(procedure_declaration *definition) override; + void visit(assign_statement *statement) override; + void visit(if_statement *statement) override; + void visit(import_declaration *) override; + void visit(while_statement *statement) override; + void visit(return_statement *statement) override; + void visit(defer_statement *statement) override; + void visit(case_statement *statement) override; + void visit(procedure_call *call) override; + void visit(unit *unit) override; + void visit(cast_expression *expression) override; + void visit(traits_expression *trait) override; + void visit(binary_expression *expression) override; + void visit(unary_expression *expression) override; + void visit(named_expression *type_expression) override; + void visit(array_access_expression *expression) override; + void visit(field_access_expression *expression) override; + void visit(dereference_expression *expression) override; + void visit(literal *literal) override; + void visit(literal *literal) override; + void visit(literal *literal) override; + void visit(literal *literal) override; + void visit(literal *literal) override; + void visit(literal *literal) override; + void visit(literal *literal) override; + }; + + /** + * Collects global declarations without resolving any symbols. + */ + class declaration_visitor final : public empty_visitor, public error_container + { + public: + forward_table unresolved; + + explicit declaration_visitor(const char *path); + + void visit(program *program) override; + void visit(import_declaration *) override; + void visit(unit *unit) override; + void visit(type_declaration *definition) override; + void visit(variable_declaration *declaration) override; + void visit(procedure_declaration *definition) override; + }; +} diff --git a/include/elna/boot/symbol.h b/include/elna/boot/symbol.h new file mode 100644 index 0000000..5ef917e --- /dev/null +++ b/include/elna/boot/symbol.h @@ -0,0 +1,457 @@ +/* Symbol definitions. + Copyright (C) 2025 Free Software Foundation, Inc. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "elna/boot/result.h" + +namespace elna::boot +{ + class alias_type; + class primitive_type; + class record_type; + class union_type; + class pointer_type; + class array_type; + class procedure_type; + class enumeration_type; + + class type + { + enum class type_tag + { + empty, + alias, + primitive, + record, + _union, + pointer, + array, + procedure, + enumeration + }; + type_tag tag{ type_tag::empty }; + union + { + std::weak_ptr alias; + std::shared_ptr primitive; + std::shared_ptr record; + std::shared_ptr _union; + std::shared_ptr pointer; + std::shared_ptr array; + std::shared_ptr procedure; + std::shared_ptr enumeration; + }; + + void copy(const type& other); + void move(type&& other); + + public: + type(); + explicit type(std::shared_ptr alias); + explicit type(std::shared_ptr primitive); + explicit type(std::shared_ptr record); + explicit type(std::shared_ptr _union); + explicit type(std::shared_ptr pointer); + explicit type(std::shared_ptr array); + explicit type(std::shared_ptr procedure); + explicit type(std::shared_ptr enumeration); + + type(const type& other); + type& operator=(const type& other); + + type(type&& other); + type& operator=(type&& other); + + bool operator==(const std::nullptr_t&); + + ~type(); + + template + std::shared_ptr get() const; + + bool empty() const; + }; + + struct alias_type + { + const std::string name; + type reference; + + explicit alias_type(const std::string& name); + }; + + struct pointer_type + { + const type base; + + explicit pointer_type(type base); + }; + + struct array_type + { + const type base; + const std::uint64_t size; + + array_type(type base, std::uint64_t size); + }; + + struct primitive_type + { + const std::string identifier; + + explicit primitive_type(const std::string& identifier); + }; + + using type_field = std::pair; + + struct record_type + { + std::vector fields; + }; + + struct union_type + { + std::vector fields; + }; + + struct procedure_type + { + using return_t = return_declaration; + + std::vector parameters; + const return_t return_type; + + procedure_type(return_t return_type = return_t()); + }; + + struct enumeration_type + { + std::vector members; + + explicit enumeration_type(const std::vector& members); + }; + + class type_info; + class procedure_info; + class constant_info; + class variable_info; + + class info : public std::enable_shared_from_this + { + public: + bool exported{ false }; + + virtual ~info() = 0; + + virtual std::shared_ptr is_type(); + virtual std::shared_ptr is_procedure(); + virtual std::shared_ptr is_constant(); + virtual std::shared_ptr is_variable(); + }; + + /** + * Symbol table. + */ + template + class symbol_map + { + public: + using symbol_ptr = typename std::enable_if< + std::is_convertible::value || std::is_assignable::value, + T + >::type; + using iterator = typename std::unordered_map::iterator; + using const_iterator = typename std::unordered_map::const_iterator; + + private: + std::unordered_map entries; + std::shared_ptr outer_scope; + + public: + /** + * Constructs a new symbol with an optional outer scope. + * + * \param scope Outer scope. + */ + explicit symbol_map(std::shared_ptr scope = nullptr) + : outer_scope(scope) + { + } + + iterator begin() + { + return this->entries.begin(); + } + + iterator end() + { + return this->entries.end(); + } + + const_iterator cbegin() const + { + return this->entries.cbegin(); + } + + const_iterator cend() const + { + return this->entries.cend(); + } + + /** + * \return Symbol count in the current scope. + */ + std::size_t size() const + { + return this->entries.size(); + } + + /** + * Looks for symbol in the table by name. Returns nothing if the symbol + * can not be found. + * + * \param name Symbol name. + * + * \return Symbol from the table if found. + */ + symbol_ptr lookup(const std::string& name) + { + auto entry = entries.find(name); + + if (entry != entries.cend()) + { + return entry->second; + } + if (this->outer_scope != nullptr) + { + return this->outer_scope->lookup(name); + } + return nothing; + } + + /** + * \param name Symbol name. + * + * \return Whether the table contains a symbol with the given name. + */ + bool contains(const std::string& name) + { + return lookup(name) != nothing; + } + + /** + * Registers new symbol. + * + * \param name Symbol name. + * \param entry Symbol information. + * + * \return Whether the insertion took place. + */ + bool enter(const std::string& name, symbol_ptr entry) + { + return lookup(name) == nothing && entries.insert({ name, entry }).second; + } + + /** + * Returns the outer scope or nullptr if the this is the global scope. + * + * \return Outer scope. + */ + std::shared_ptr scope() + { + return this->outer_scope; + } + }; + + using symbol_table = symbol_map, std::nullptr_t, nullptr>; + using forward_table = std::unordered_map>; + + class type_info : public info + { + public: + const type symbol; + + explicit type_info(const type symbol); + std::shared_ptr is_type() override; + }; + + /** + * Procedure symbol information. + */ + class procedure_info : public info + { + public: + /// Procedure type. + const procedure_type symbol; + + /// Parameter names. + const std::vector names; + + /// Local definitions. + std::shared_ptr scope; + + /** + * Constructs procedure symbol information. + * + * \param symbol Procedure type. + * \param names Parameter names. + * \param scope Local definition (is `nullptr` for extern symbols). + */ + procedure_info(const procedure_type symbol, const std::vector names, + std::shared_ptr scope = nullptr); + + std::shared_ptr is_procedure() override; + + /** + * \return Whether this is an extern symbol. + */ + bool is_extern() const; + }; + + class constant_info : public info + { + public: + using variant = typename + std::variant; + + const variant symbol; + + explicit constant_info(const variant& symbol); + std::shared_ptr is_constant() override; + }; + + /** + * Variable symbol information. + */ + class variable_info : public info + { + public: + /// Variable type. + const type symbol; + + /// Whether this is an extern symbol. + const bool is_extern; + + /** + * Constructs a variable symbol information. + * + * \param symbol Variable type. + * \param is_extern Whether this is an extern symbol. + */ + variable_info(const type symbol, bool is_extern); + + std::shared_ptr is_variable() override; + }; + + std::shared_ptr builtin_symbol_table(); + + /** + * Symbol bag contains: + * + * - the symbol table of a module itself + * - symbol tables of imported modules + * - forward declarations + */ + class symbol_bag + { + std::shared_ptr symbols; + std::forward_list> imports; + forward_table unresolved; + + public: + + /** + * \param unresolved Forward declarations collected in the previous step. + * \param global_table Global symbols. + */ + symbol_bag(forward_table&& unresolved, std::shared_ptr global_table); + + /** + * Looks up a symbol in the current and imported modules. + * + * \param name Symbol name to look up. + * + * \return Symbol from one of the symbol tables if found. + */ + std::shared_ptr lookup(const std::string& name); + + /** + * Inserts a symbol into the current scope. + * + * \param name Symbol name. + * \param entry Symbol info. + * + * \return Whether the insertion took place. + */ + bool enter(const std::string& name, std::shared_ptr entry); + + /** + * Enters a new scope. + * + * \return Reference to the allocated scope. + */ + std::shared_ptr enter(); + + /** + * Sets the current scope to \a child. + * + * \param child New scope. + */ + void enter(std::shared_ptr child); + + /** + * Leave the current scope. + * + * \return Left scope. + */ + std::shared_ptr leave(); + + /** + * Checks whether there is a forward declaration \a symbol_name and + * returns it if so. + * + * \param symbol_name Type name to look up. + * \return Forward declaration or `nullptr` if the symbol is not declared. + */ + std::shared_ptr declared(const std::string& symbol_name); + + /** + * Completes the forward-declared type \a symbol_name and defines it to + * be \a resolution. + * + * \param symbol_name Type name. + * \param resolution Type definition. + * \return Alias to the defined type. + */ + std::shared_ptr resolve(const std::string& symbol_name, type& resolution); + + /** + * Add imported symbols to the scope. + * + * \param bag Symbol bag of another module. + */ + void add_import(const symbol_bag& bag); + }; +} diff --git a/include/elna/frontend/ast.h b/include/elna/frontend/ast.h deleted file mode 100644 index 0b5f3d7..0000000 --- a/include/elna/frontend/ast.h +++ /dev/null @@ -1,800 +0,0 @@ -/* Abstract syntax tree representation. - Copyright (C) 2025 Free Software Foundation, Inc. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#pragma once - -#include -#include -#include -#include -#include -#include "elna/frontend/symbol.h" -#include "elna/frontend/result.h" - -namespace elna::frontend -{ - enum class binary_operator - { - sum, - subtraction, - multiplication, - division, - remainder, - equals, - not_equals, - less, - greater, - less_equal, - greater_equal, - disjunction, - conjunction, - exclusive_disjunction, - shift_left, - shift_right - }; - - enum class unary_operator - { - reference, - negation, - minus - }; - - class variable_declaration; - class constant_declaration; - class procedure_declaration; - class type_declaration; - class procedure_call; - class cast_expression; - class assign_statement; - class if_statement; - class import_declaration; - class while_statement; - class return_statement; - class case_statement; - class traits_expression; - class unit; - class program; - class binary_expression; - class unary_expression; - class type_expression; - class array_type_expression; - class pointer_type_expression; - class record_type_expression; - class union_type_expression; - class procedure_type_expression; - class enumeration_type_expression; - class named_expression; - class array_access_expression; - class field_access_expression; - class dereference_expression; - class designator_expression; - class literal_expression; - template - class literal; - class defer_statement; - - /** - * Interface for AST visitors. - */ - struct parser_visitor - { - virtual void visit(variable_declaration *) = 0; - virtual void visit(constant_declaration *) = 0; - virtual void visit(procedure_declaration *) = 0; - virtual void visit(type_declaration *) = 0; - virtual void visit(procedure_call *) = 0; - virtual void visit(cast_expression *) = 0; - virtual void visit(traits_expression *) = 0; - virtual void visit(assign_statement *) = 0; - virtual void visit(if_statement *) = 0; - virtual void visit(import_declaration *) = 0; - virtual void visit(while_statement *) = 0; - virtual void visit(return_statement *) = 0; - virtual void visit(defer_statement *) = 0; - virtual void visit(case_statement *) = 0; - virtual void visit(unit *) = 0; - virtual void visit(program *) = 0; - virtual void visit(binary_expression *) = 0; - virtual void visit(unary_expression *) = 0; - virtual void visit(type_expression *) = 0; - virtual void visit(array_type_expression *) = 0; - virtual void visit(pointer_type_expression *) = 0; - virtual void visit(record_type_expression *) = 0; - virtual void visit(union_type_expression *) = 0; - virtual void visit(procedure_type_expression *) = 0; - virtual void visit(enumeration_type_expression *) = 0; - virtual void visit(named_expression *) = 0; - virtual void visit(array_access_expression *) = 0; - virtual void visit(field_access_expression *) = 0; - virtual void visit(dereference_expression *) = 0; - virtual void visit(literal *) = 0; - virtual void visit(literal *) = 0; - virtual void visit(literal *) = 0; - virtual void visit(literal *) = 0; - virtual void visit(literal *) = 0; - virtual void visit(literal *) = 0; - virtual void visit(literal *) = 0; - }; - - /** - * Abstract visitor that doesn't visit any nodes by default. - */ - class empty_visitor : public parser_visitor - { - [[noreturn]] void not_implemented(); - - public: - [[noreturn]] virtual void visit(type_expression *) override; - [[noreturn]] virtual void visit(array_type_expression *) override; - [[noreturn]] virtual void visit(pointer_type_expression *) override; - [[noreturn]] virtual void visit(program *) override; - [[noreturn]] virtual void visit(type_declaration *) override; - [[noreturn]] virtual void visit(record_type_expression *) override; - [[noreturn]] virtual void visit(union_type_expression *) override; - [[noreturn]] virtual void visit(procedure_type_expression *) override; - [[noreturn]] virtual void visit(enumeration_type_expression *) override; - - [[noreturn]] virtual void visit(variable_declaration *) override; - [[noreturn]] virtual void visit(constant_declaration *) override; - [[noreturn]] virtual void visit(procedure_declaration *) override; - [[noreturn]] virtual void visit(assign_statement *) override; - [[noreturn]] virtual void visit(if_statement *) override; - [[noreturn]] virtual void visit(import_declaration *) override; - [[noreturn]] virtual void visit(while_statement *) override; - [[noreturn]] virtual void visit(return_statement *) override; - [[noreturn]] virtual void visit(defer_statement *) override; - [[noreturn]] virtual void visit(case_statement *) override; - [[noreturn]] virtual void visit(procedure_call *) override; - [[noreturn]] virtual void visit(unit *) override; - [[noreturn]] virtual void visit(cast_expression *) override; - [[noreturn]] virtual void visit(traits_expression *) override; - [[noreturn]] virtual void visit(binary_expression *) override; - [[noreturn]] virtual void visit(unary_expression *) override; - [[noreturn]] virtual void visit(named_expression *) override; - [[noreturn]] virtual void visit(array_access_expression *) override; - [[noreturn]] virtual void visit(field_access_expression *) override; - [[noreturn]] virtual void visit(dereference_expression *) override; - [[noreturn]] virtual void visit(literal *) override; - [[noreturn]] virtual void visit(literal *) override; - [[noreturn]] virtual void visit(literal *) override; - [[noreturn]] virtual void visit(literal *) override; - [[noreturn]] virtual void visit(literal *) override; - [[noreturn]] virtual void visit(literal *) override; - [[noreturn]] virtual void visit(literal *) override; - }; - - /** - * AST node. - */ - class node - { - const struct position source_position; - - protected: - /** - * \param position Source code position. - */ - explicit node(const position position); - - public: - virtual void accept(parser_visitor *visitor) = 0; - virtual ~node() = 0; - - /** - * \return Node position in the source code. - */ - const struct position& position() const; - }; - - class statement : public virtual node - { - }; - - class expression : public virtual node - { - public: - virtual cast_expression *is_cast(); - virtual traits_expression *is_traits(); - virtual binary_expression *is_binary(); - virtual unary_expression *is_unary(); - virtual designator_expression *is_designator(); - virtual procedure_call *is_call_expression(); - virtual literal_expression *is_literal(); - }; - - /** - * Symbol definition. - */ - class declaration : public node - { - protected: - declaration(const struct position position, identifier_definition identifier); - - public: - const identifier_definition identifier; - }; - - /** - * Some type expression. - */ - class type_expression : public virtual node - { - public: - virtual named_expression *is_named(); - virtual array_type_expression *is_array(); - virtual pointer_type_expression *is_pointer(); - virtual record_type_expression *is_record(); - virtual union_type_expression *is_union(); - virtual procedure_type_expression *is_procedure(); - virtual enumeration_type_expression *is_enumeration(); - - void accept(parser_visitor *visitor) override; - ~type_expression() = 0; - }; - - class array_type_expression : public type_expression - { - type_expression *m_base; - - public: - const std::uint32_t size; - - array_type_expression(const struct position position, - type_expression *base, const std::uint32_t size); - ~array_type_expression(); - - void accept(parser_visitor *visitor) override; - array_type_expression *is_array() override; - - type_expression& base(); - }; - - class pointer_type_expression : public type_expression - { - type_expression *m_base; - - public: - pointer_type_expression(const struct position position, type_expression *base); - ~pointer_type_expression(); - - void accept(parser_visitor *visitor) override; - pointer_type_expression *is_pointer() override; - - type_expression& base(); - }; - - using field_declaration = std::pair; - - class record_type_expression : public type_expression - { - public: - const std::vector fields; - - record_type_expression(const struct position position, std::vector&& fields); - ~record_type_expression(); - - void accept(parser_visitor *visitor) override; - record_type_expression *is_record() override; - }; - - class union_type_expression : public type_expression - { - public: - std::vector fields; - - union_type_expression(const struct position position, std::vector&& fields); - ~union_type_expression(); - - void accept(parser_visitor *visitor) override; - union_type_expression *is_union() override; - }; - - /** - * Enumeration type. - */ - class enumeration_type_expression : public type_expression - { - public: - const std::vector members; - - enumeration_type_expression(const struct position, std::vector&& members); - - void accept(parser_visitor *visitor) override; - enumeration_type_expression *is_enumeration() override; - }; - - /** - * Variable declaration. - */ - class variable_declaration : public node - { - std::shared_ptr m_variable_type; - - public: - variable_declaration(const struct position position, - std::vector&& identifier, std::shared_ptr variable_type, - expression *body = nullptr); - variable_declaration(const struct position position, - std::vector&& identifier, std::shared_ptr variable_type, - std::monostate); - - void accept(parser_visitor *visitor) override; - - bool has_initializer() const; - - const std::vector identifiers; - type_expression& variable_type(); - expression *const body{ nullptr }; - const bool is_extern{ false }; - }; - - /** - * Literal expression. - */ - class literal_expression : public expression - { - public: - literal_expression *is_literal() override; - }; - - /** - * Constant definition. - */ - class constant_declaration : public declaration - { - expression *m_body; - - public: - constant_declaration(const struct position position, identifier_definition identifier, - expression *body); - void accept(parser_visitor *visitor) override; - - expression& body(); - - virtual ~constant_declaration() override; - }; - - /** - * Procedure type. - */ - class procedure_type_expression : public type_expression - { - public: - using return_t = return_declaration; - - const return_t return_type; - std::vector parameters; - - procedure_type_expression(const struct position position, return_t return_type = return_t()); - ~procedure_type_expression(); - - void accept(parser_visitor *visitor) override; - procedure_type_expression *is_procedure() override; - }; - - struct block - { - block(std::vector&& constants, std::vector&& variables, - std::vector&& body); - block(std::vector&& constants, std::vector&& variables); - block(const block&) = delete; - block(block&& that); - - block& operator=(const block&) = delete; - block& operator=(block&& that); - - const std::vector& variables(); - const std::vector& constants(); - const std::vector& body(); - - virtual ~block(); - - private: - std::vector m_variables; - std::vector m_constants; - std::vector m_body; - - }; - - /** - * Procedure definition. - */ - class procedure_declaration : public declaration - { - procedure_type_expression *m_heading; - - public: - std::optional body; - std::vector parameter_names; - - procedure_declaration(const struct position position, identifier_definition identifier, - procedure_type_expression *heading, block&& body); - procedure_declaration(const struct position position, identifier_definition identifier, - procedure_type_expression *heading); - void accept(parser_visitor *visitor) override; - - procedure_type_expression& heading(); - - virtual ~procedure_declaration() override; - }; - - /** - * Type definition. - */ - class type_declaration : public declaration - { - type_expression *m_body; - - public: - type_declaration(const struct position position, identifier_definition identifier, - type_expression *expression); - ~type_declaration(); - - void accept(parser_visitor *visitor) override; - - type_expression& body(); - }; - - /** - * Cast expression. - */ - class cast_expression : public expression - { - type_expression *m_target; - expression *m_value; - - public: - type expression_type; - - cast_expression(const struct position position, type_expression *target, expression *value); - void accept(parser_visitor *visitor) override; - cast_expression *is_cast() override; - - type_expression& target(); - expression& value(); - - virtual ~cast_expression() override; - }; - - class traits_expression : public expression - { - public: - std::vector parameters; - const std::string name; - std::vector types; - - traits_expression(const struct position position, const std::string& name); - ~traits_expression(); - - void accept(parser_visitor *visitor) override; - traits_expression *is_traits() override; - }; - - /** - * List of statements paired with a condition. - */ - class conditional_statements - { - expression *m_prerequisite; - - public: - const std::vector statements; - - conditional_statements(expression *prerequisite, std::vector&& statements); - - expression& prerequisite(); - - virtual ~conditional_statements(); - }; - - class return_statement : public statement - { - public: - expression *m_return_expression; - - return_statement(const struct position position, expression *return_expression); - void accept(parser_visitor *visitor) override; - - expression& return_expression(); - - virtual ~return_statement() override; - }; - - struct switch_case - { - std::vector labels; - std::vector statements; - }; - - class case_statement : public statement - { - expression *m_condition; - - public: - const std::vector cases; - const std::vector *alternative; - - case_statement(const struct position position, expression *condition, - std::vector&& cases, std::vector *alternative = nullptr); - void accept(parser_visitor *visitor) override; - expression& condition(); - }; - - class designator_expression : public expression - { - public: - virtual named_expression *is_named(); - virtual array_access_expression *is_array_access(); - virtual field_access_expression *is_field_access(); - virtual dereference_expression *is_dereference(); - - designator_expression *is_designator() override; - void accept(parser_visitor *visitor); - ~designator_expression() = 0; - }; - - /** - * Expression refering to an entity by its name. - */ - class named_expression : public designator_expression, public type_expression - { - public: - const std::string name; - - named_expression(const struct position position, const std::string& name); - void accept(parser_visitor *visitor) override; - - named_expression *is_named() override; - }; - - class array_access_expression : public designator_expression - { - expression *m_base; - expression *m_index; - - public: - array_access_expression(const struct position position, expression *base, expression *index); - void accept(parser_visitor *visitor) override; - - expression& base(); - expression& index(); - - array_access_expression *is_array_access() override; - - ~array_access_expression() override; - }; - - class field_access_expression : public designator_expression - { - expression *m_base; - std::string m_field; - - public: - field_access_expression(const struct position position, expression *base, - const std::string& field); - void accept(parser_visitor *visitor) override; - - expression& base(); - std::string& field(); - - field_access_expression *is_field_access() override; - - ~field_access_expression() override; - }; - - class dereference_expression : public designator_expression - { - expression *m_base; - - public: - dereference_expression(const struct position position, expression *base); - void accept(parser_visitor *visitor) override; - - expression& base(); - - dereference_expression *is_dereference() override; - - ~dereference_expression() override; - }; - - /** - * Procedure call expression. - */ - class procedure_call : public expression, public statement - { - designator_expression *m_callable; - - public: - std::vector arguments; - - procedure_call(const struct position position, designator_expression *callable); - void accept(parser_visitor *visitor) override; - virtual procedure_call *is_call_expression() override; - - designator_expression& callable(); - - virtual ~procedure_call() override; - }; - - class assign_statement : public statement - { - designator_expression *m_lvalue; - expression *m_rvalue; - - public: - /** - * \param position Source code position. - * \param lvalue Left-hand side. - * \param rvalue Assigned expression. - */ - assign_statement(const struct position position, designator_expression *lvalue, - expression *rvalue); - void accept(parser_visitor *visitor) override; - - designator_expression& lvalue(); - expression& rvalue(); - - virtual ~assign_statement() override; - }; - - /** - * If-statement. - */ - class if_statement : public statement - { - conditional_statements *m_body; - - public: - const std::vector branches; - const std::vector *alternative; - - if_statement(const struct position position, conditional_statements *body, - std::vector&& branches, - std::vector *alternative = nullptr); - void accept(parser_visitor *visitor) override; - - conditional_statements& body(); - - virtual ~if_statement() override; - }; - - /** - * Import statement. - */ - class import_declaration : public node - { - public: - const std::vector segments; - - import_declaration(const struct position position, std::vector&& segments); - void accept(parser_visitor *visitor) override; - }; - - /** - * While-statement. - */ - class while_statement : public statement - { - conditional_statements *m_body; - - public: - const std::vector branches; - - while_statement(const struct position position, conditional_statements *body, - std::vector&& branches); - void accept(parser_visitor *visitor) override; - - conditional_statements& body(); - - virtual ~while_statement() override; - }; - - class unit : public node - { - public: - std::vector imports; - std::vector constants; - std::vector types; - std::vector variables; - std::vector procedures; - - unit(const struct position position); - virtual void accept(parser_visitor *visitor) override; - - virtual ~unit() override; - }; - - class program : public unit - { - public: - std::vector body; - - program(const struct position position); - void accept(parser_visitor *visitor) override; - - virtual ~program() override; - }; - - template - class literal : public literal_expression - { - public: - T value; - - literal(const struct position position, const T& value) - : node(position), value(value) - { - } - - void accept(parser_visitor *visitor) override - { - visitor->visit(this); - } - }; - - class defer_statement : public statement - { - public: - const std::vector statements; - - defer_statement(const struct position position, std::vector&& statements); - void accept(parser_visitor *visitor) override; - - virtual ~defer_statement() override; - }; - - class binary_expression : public expression - { - expression *m_lhs; - expression *m_rhs; - binary_operator m_operator; - - public: - binary_expression(const struct position position, expression *lhs, - expression *rhs, const binary_operator operation); - - void accept(parser_visitor *visitor) override; - binary_expression *is_binary() override; - - expression& lhs(); - expression& rhs(); - binary_operator operation() const; - - virtual ~binary_expression() override; - }; - - class unary_expression : public expression - { - expression *m_operand; - unary_operator m_operator; - - public: - unary_expression(const struct position position, expression *operand, - const unary_operator operation); - - void accept(parser_visitor *visitor) override; - unary_expression *is_unary() override; - - expression& operand(); - unary_operator operation() const; - - virtual ~unary_expression() override; - }; - - const char *print_binary_operator(const binary_operator operation); -} diff --git a/include/elna/frontend/dependency.h b/include/elna/frontend/dependency.h deleted file mode 100644 index f1502d1..0000000 --- a/include/elna/frontend/dependency.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Dependency graph analysis. - Copyright (C) 2025 Free Software Foundation, Inc. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#pragma once - -#include -#include -#include "elna/frontend/result.h" -#include "elna/frontend/ast.h" -#include "elna/frontend/symbol.h" - -namespace elna::frontend -{ - class dependency : public error_container - { - error_list m_errors; - - public: - std::unique_ptr tree; - forward_table unresolved; - - explicit dependency(const char *path); - }; - - dependency read_source(std::istream& entry_point, const char *entry_path); - std::filesystem::path build_path(const std::vector& segments); - error_list analyze_semantics(const char *path, std::unique_ptr& tree, symbol_bag bag); - - template - struct dependency_state - { - const std::shared_ptr globals; - T custom; - std::unordered_map cache; - - explicit dependency_state(T custom) - : globals(builtin_symbol_table()), custom(custom) - { - } - }; -} diff --git a/include/elna/frontend/driver.h b/include/elna/frontend/driver.h deleted file mode 100644 index 66ef579..0000000 --- a/include/elna/frontend/driver.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Parsing driver. - Copyright (C) 2025 Free Software Foundation, Inc. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#pragma once - -#include -#include "elna/frontend/ast.h" -#include "location.hh" - -namespace elna::frontend -{ - position make_position(const yy::location& location); - - class syntax_error final : public error - { - std::string message; - - public: - syntax_error(const std::string& message, - const char *input_file, const yy::location& location); - - virtual std::string what() const override; - }; - - class driver : public error_container - { - public: - std::unique_ptr tree; - - driver(const char *input_file); - }; - - constexpr char escape_invalid_char = '\xff'; - - char escape_char(char escape); - std::optional escape_string(const char *escape); -} diff --git a/include/elna/frontend/result.h b/include/elna/frontend/result.h deleted file mode 100644 index 7e5ed77..0000000 --- a/include/elna/frontend/result.h +++ /dev/null @@ -1,124 +0,0 @@ -/* Miscellaneous types used across stage boundaries. - Copyright (C) 2025 Free Software Foundation, Inc. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#pragma once - -#include -#include -#include -#include -#include - -namespace elna::frontend -{ - /** - * Position in the source text. - */ - struct position - { - /// Line. - std::size_t line = 1; - - /// Column. - std::size_t column = 1; - }; - - /** - * A compilation error consists of an error message and position. - */ - class error - { - protected: - error(const char *path, const struct position position); - - public: - const struct position position; - const char *path; - - virtual ~error() = default; - - /// Error text. - virtual std::string what() const = 0; - - /// Error line in the source text. - std::size_t line() const; - - /// Error column in the source text. - std::size_t column() const; - }; - - using error_list = typename std::deque>; - - class error_container - { - protected: - error_list m_errors; - - error_container(const char *input_file); - - public: - const char *input_file; - - error_list& errors(); - - template - void add_error(Args... arguments) - { - auto new_error = std::make_unique(arguments...); - m_errors.emplace_back(std::move(new_error)); - } - - bool has_errors() const; - }; - - /** - * Tags a procedure type as never returning. - */ - template - struct return_declaration - { - return_declaration() = default; - - explicit return_declaration(T type) - : proper_type(type) - { - } - - explicit return_declaration(std::monostate) - : no_return(true) - { - } - - T proper_type{}; - bool no_return{ false }; - }; - - struct identifier_definition - { - std::string name; - bool exported; - - bool operator==(const identifier_definition& that) const; - bool operator==(const std::string& that) const; - }; -} - -template<> -struct std::hash -{ - std::size_t operator()(const elna::frontend::identifier_definition& key) const noexcept; -}; diff --git a/include/elna/frontend/semantic.h b/include/elna/frontend/semantic.h deleted file mode 100644 index 887b660..0000000 --- a/include/elna/frontend/semantic.h +++ /dev/null @@ -1,192 +0,0 @@ -/* Name analysis. - Copyright (C) 2025 Free Software Foundation, Inc. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#pragma once - -#include -#include -#include -#include - -#include "elna/frontend/ast.h" -#include "elna/frontend/result.h" -#include "elna/frontend/symbol.h" - -namespace elna::frontend -{ - class undeclared_error : public error - { - const std::string identifier; - - public: - undeclared_error(const std::string& identifier, const char *path, const struct position position); - - std::string what() const override; - }; - - class already_declared_error : public error - { - const std::string identifier; - - public: - already_declared_error(const std::string& identifier, const char *path, const struct position position); - - std::string what() const override; - }; - - class field_duplication_error : public error - { - const std::string field_name; - - public: - field_duplication_error(const std::string& field_name, const char *path, const struct position position); - - std::string what() const override; - }; - - class cyclic_declaration_error : public error - { - const std::vector cycle; - - public: - cyclic_declaration_error(const std::vector& cycle, - const char *path, const struct position position); - - std::string what() const override; - }; - - class return_error : public error - { - const std::string identifier; - - public: - return_error(const std::string& identifier, const char *path, const struct position position); - - std::string what() const override; - }; - - class variable_initializer_error : public error - { - public: - variable_initializer_error(const char *path, const struct position position); - - std::string what() const override; - }; - - /** - * Checks types. - */ - class type_analysis_visitor final : public empty_visitor, public error_container - { - bool returns; - symbol_bag bag; - - bool check_unresolved_symbol(std::shared_ptr alias, - std::vector& path); - - public: - explicit type_analysis_visitor(const char *path, symbol_bag bag); - - void visit(program *program) override; - - void visit(procedure_declaration *definition) override; - void visit(assign_statement *) override; - void visit(if_statement *) override; - void visit(while_statement *) override; - void visit(return_statement *) override; - void visit(defer_statement *) override; - void visit(case_statement *) override; - void visit(procedure_call *) override; - void visit(unit *unit) override; - void visit(type_declaration *definition) override; - }; - - /** - * Performs name analysis. - */ - class name_analysis_visitor final : public parser_visitor, public error_container - { - type current_type; - constant_info::variant current_literal; - - symbol_bag bag; - - procedure_type build_procedure(procedure_type_expression& type_expression); - std::vector build_composite_type(const std::vector& fields); - std::shared_ptr register_variable(const std::string& name, - const bool is_extern, const struct position position); - - public: - name_analysis_visitor(const char *path, symbol_bag bag); - - void visit(type_expression *) override; - void visit(array_type_expression *type_expression) override; - void visit(pointer_type_expression *type_expression) override; - void visit(program *program) override; - void visit(type_declaration *definition) override; - void visit(record_type_expression *type_expression) override; - void visit(union_type_expression *type_expression) override; - void visit(procedure_type_expression *type_expression) override; - void visit(enumeration_type_expression *type_expression) override; - - void visit(variable_declaration *declaration) override; - void visit(constant_declaration *definition) override; - void visit(procedure_declaration *definition) override; - void visit(assign_statement *statement) override; - void visit(if_statement *statement) override; - void visit(import_declaration *) override; - void visit(while_statement *statement) override; - void visit(return_statement *statement) override; - void visit(defer_statement *statement) override; - void visit(case_statement *statement) override; - void visit(procedure_call *call) override; - void visit(unit *unit) override; - void visit(cast_expression *expression) override; - void visit(traits_expression *trait) override; - void visit(binary_expression *expression) override; - void visit(unary_expression *expression) override; - void visit(named_expression *type_expression) override; - void visit(array_access_expression *expression) override; - void visit(field_access_expression *expression) override; - void visit(dereference_expression *expression) override; - void visit(literal *literal) override; - void visit(literal *literal) override; - void visit(literal *literal) override; - void visit(literal *literal) override; - void visit(literal *literal) override; - void visit(literal *literal) override; - void visit(literal *literal) override; - }; - - /** - * Collects global declarations without resolving any symbols. - */ - class declaration_visitor final : public empty_visitor, public error_container - { - public: - forward_table unresolved; - - explicit declaration_visitor(const char *path); - - void visit(program *program) override; - void visit(import_declaration *) override; - void visit(unit *unit) override; - void visit(type_declaration *definition) override; - void visit(variable_declaration *declaration) override; - void visit(procedure_declaration *definition) override; - }; -} diff --git a/include/elna/frontend/symbol.h b/include/elna/frontend/symbol.h deleted file mode 100644 index ec912ef..0000000 --- a/include/elna/frontend/symbol.h +++ /dev/null @@ -1,457 +0,0 @@ -/* Symbol definitions. - Copyright (C) 2025 Free Software Foundation, Inc. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "elna/frontend/result.h" - -namespace elna::frontend -{ - class alias_type; - class primitive_type; - class record_type; - class union_type; - class pointer_type; - class array_type; - class procedure_type; - class enumeration_type; - - class type - { - enum class type_tag - { - empty, - alias, - primitive, - record, - _union, - pointer, - array, - procedure, - enumeration - }; - type_tag tag{ type_tag::empty }; - union - { - std::weak_ptr alias; - std::shared_ptr primitive; - std::shared_ptr record; - std::shared_ptr _union; - std::shared_ptr pointer; - std::shared_ptr array; - std::shared_ptr procedure; - std::shared_ptr enumeration; - }; - - void copy(const type& other); - void move(type&& other); - - public: - type(); - explicit type(std::shared_ptr alias); - explicit type(std::shared_ptr primitive); - explicit type(std::shared_ptr record); - explicit type(std::shared_ptr _union); - explicit type(std::shared_ptr pointer); - explicit type(std::shared_ptr array); - explicit type(std::shared_ptr procedure); - explicit type(std::shared_ptr enumeration); - - type(const type& other); - type& operator=(const type& other); - - type(type&& other); - type& operator=(type&& other); - - bool operator==(const std::nullptr_t&); - - ~type(); - - template - std::shared_ptr get() const; - - bool empty() const; - }; - - struct alias_type - { - const std::string name; - type reference; - - explicit alias_type(const std::string& name); - }; - - struct pointer_type - { - const type base; - - explicit pointer_type(type base); - }; - - struct array_type - { - const type base; - const std::uint64_t size; - - array_type(type base, std::uint64_t size); - }; - - struct primitive_type - { - const std::string identifier; - - explicit primitive_type(const std::string& identifier); - }; - - using type_field = std::pair; - - struct record_type - { - std::vector fields; - }; - - struct union_type - { - std::vector fields; - }; - - struct procedure_type - { - using return_t = return_declaration; - - std::vector parameters; - const return_t return_type; - - procedure_type(return_t return_type = return_t()); - }; - - struct enumeration_type - { - std::vector members; - - explicit enumeration_type(const std::vector& members); - }; - - class type_info; - class procedure_info; - class constant_info; - class variable_info; - - class info : public std::enable_shared_from_this - { - public: - bool exported{ false }; - - virtual ~info() = 0; - - virtual std::shared_ptr is_type(); - virtual std::shared_ptr is_procedure(); - virtual std::shared_ptr is_constant(); - virtual std::shared_ptr is_variable(); - }; - - /** - * Symbol table. - */ - template - class symbol_map - { - public: - using symbol_ptr = typename std::enable_if< - std::is_convertible::value || std::is_assignable::value, - T - >::type; - using iterator = typename std::unordered_map::iterator; - using const_iterator = typename std::unordered_map::const_iterator; - - private: - std::unordered_map entries; - std::shared_ptr outer_scope; - - public: - /** - * Constructs a new symbol with an optional outer scope. - * - * \param scope Outer scope. - */ - explicit symbol_map(std::shared_ptr scope = nullptr) - : outer_scope(scope) - { - } - - iterator begin() - { - return this->entries.begin(); - } - - iterator end() - { - return this->entries.end(); - } - - const_iterator cbegin() const - { - return this->entries.cbegin(); - } - - const_iterator cend() const - { - return this->entries.cend(); - } - - /** - * \return Symbol count in the current scope. - */ - std::size_t size() const - { - return this->entries.size(); - } - - /** - * Looks for symbol in the table by name. Returns nothing if the symbol - * can not be found. - * - * \param name Symbol name. - * - * \return Symbol from the table if found. - */ - symbol_ptr lookup(const std::string& name) - { - auto entry = entries.find(name); - - if (entry != entries.cend()) - { - return entry->second; - } - if (this->outer_scope != nullptr) - { - return this->outer_scope->lookup(name); - } - return nothing; - } - - /** - * \param name Symbol name. - * - * \return Whether the table contains a symbol with the given name. - */ - bool contains(const std::string& name) - { - return lookup(name) != nothing; - } - - /** - * Registers new symbol. - * - * \param name Symbol name. - * \param entry Symbol information. - * - * \return Whether the insertion took place. - */ - bool enter(const std::string& name, symbol_ptr entry) - { - return lookup(name) == nothing && entries.insert({ name, entry }).second; - } - - /** - * Returns the outer scope or nullptr if the this is the global scope. - * - * \return Outer scope. - */ - std::shared_ptr scope() - { - return this->outer_scope; - } - }; - - using symbol_table = symbol_map, std::nullptr_t, nullptr>; - using forward_table = std::unordered_map>; - - class type_info : public info - { - public: - const type symbol; - - explicit type_info(const type symbol); - std::shared_ptr is_type() override; - }; - - /** - * Procedure symbol information. - */ - class procedure_info : public info - { - public: - /// Procedure type. - const procedure_type symbol; - - /// Parameter names. - const std::vector names; - - /// Local definitions. - std::shared_ptr scope; - - /** - * Constructs procedure symbol information. - * - * \param symbol Procedure type. - * \param names Parameter names. - * \param scope Local definition (is `nullptr` for extern symbols). - */ - procedure_info(const procedure_type symbol, const std::vector names, - std::shared_ptr scope = nullptr); - - std::shared_ptr is_procedure() override; - - /** - * \return Whether this is an extern symbol. - */ - bool is_extern() const; - }; - - class constant_info : public info - { - public: - using variant = typename - std::variant; - - const variant symbol; - - explicit constant_info(const variant& symbol); - std::shared_ptr is_constant() override; - }; - - /** - * Variable symbol information. - */ - class variable_info : public info - { - public: - /// Variable type. - const type symbol; - - /// Whether this is an extern symbol. - const bool is_extern; - - /** - * Constructs a variable symbol information. - * - * \param symbol Variable type. - * \param is_extern Whether this is an extern symbol. - */ - variable_info(const type symbol, bool is_extern); - - std::shared_ptr is_variable() override; - }; - - std::shared_ptr builtin_symbol_table(); - - /** - * Symbol bag contains: - * - * - the symbol table of a module itself - * - symbol tables of imported modules - * - forward declarations - */ - class symbol_bag - { - std::shared_ptr symbols; - std::forward_list> imports; - forward_table unresolved; - - public: - - /** - * \param unresolved Forward declarations collected in the previous step. - * \param global_table Global symbols. - */ - symbol_bag(forward_table&& unresolved, std::shared_ptr global_table); - - /** - * Looks up a symbol in the current and imported modules. - * - * \param name Symbol name to look up. - * - * \return Symbol from one of the symbol tables if found. - */ - std::shared_ptr lookup(const std::string& name); - - /** - * Inserts a symbol into the current scope. - * - * \param name Symbol name. - * \param entry Symbol info. - * - * \return Whether the insertion took place. - */ - bool enter(const std::string& name, std::shared_ptr entry); - - /** - * Enters a new scope. - * - * \return Reference to the allocated scope. - */ - std::shared_ptr enter(); - - /** - * Sets the current scope to \a child. - * - * \param child New scope. - */ - void enter(std::shared_ptr child); - - /** - * Leave the current scope. - * - * \return Left scope. - */ - std::shared_ptr leave(); - - /** - * Checks whether there is a forward declaration \a symbol_name and - * returns it if so. - * - * \param symbol_name Type name to look up. - * \return Forward declaration or `nullptr` if the symbol is not declared. - */ - std::shared_ptr declared(const std::string& symbol_name); - - /** - * Completes the forward-declared type \a symbol_name and defines it to - * be \a resolution. - * - * \param symbol_name Type name. - * \param resolution Type definition. - * \return Alias to the defined type. - */ - std::shared_ptr resolve(const std::string& symbol_name, type& resolution); - - /** - * Add imported symbols to the scope. - * - * \param bag Symbol bag of another module. - */ - void add_import(const symbol_bag& bag); - }; -} diff --git a/include/elna/gcc/elna-builtins.h b/include/elna/gcc/elna-builtins.h index 60baab7..0cdf519 100644 --- a/include/elna/gcc/elna-builtins.h +++ b/include/elna/gcc/elna-builtins.h @@ -30,12 +30,12 @@ namespace elna::gcc void init_ttree(); std::shared_ptr builtin_symbol_table(); - void rewrite_symbol_table(std::shared_ptr info_table, std::shared_ptr symbols); - tree handle_symbol(const std::string& symbol_name, std::shared_ptr reference, + void rewrite_symbol_table(std::shared_ptr info_table, std::shared_ptr symbols); + tree handle_symbol(const std::string& symbol_name, std::shared_ptr reference, std::shared_ptr symbols); - tree get_inner_alias(const frontend::type& type, std::shared_ptr symbols); - void declare_procedure(const std::string& name, const frontend::procedure_info& info, + tree get_inner_alias(const boot::type& type, std::shared_ptr symbols); + void declare_procedure(const std::string& name, const boot::procedure_info& info, std::shared_ptr symbols); - tree declare_variable(const std::string& name, const frontend::variable_info& info, + tree declare_variable(const std::string& name, const boot::variable_info& info, std::shared_ptr symbols); } diff --git a/include/elna/gcc/elna-diagnostic.h b/include/elna/gcc/elna-diagnostic.h index 83f768e..1eef65d 100644 --- a/include/elna/gcc/elna-diagnostic.h +++ b/include/elna/gcc/elna-diagnostic.h @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see #include #include -#include "elna/frontend/result.h" +#include "elna/boot/result.h" namespace elna::gcc { @@ -40,7 +40,7 @@ namespace elna::gcc ~linemap_guard(); }; - location_t get_location(const frontend::position *position); + location_t get_location(const boot::position *position); std::string print_type(tree type); - void report_errors(const std::deque>& errors); + void report_errors(const std::deque>& errors); } diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h index ec6f32f..7490e92 100644 --- a/include/elna/gcc/elna-generic.h +++ b/include/elna/gcc/elna-generic.h @@ -17,9 +17,9 @@ along with GCC; see the file COPYING3. If not see #pragma once -#include "elna/frontend/ast.h" -#include "elna/frontend/symbol.h" -#include "elna/frontend/semantic.h" +#include "elna/boot/ast.h" +#include "elna/boot/symbol.h" +#include "elna/boot/semantic.h" #include "elna/gcc/elna-tree.h" #include "config.h" @@ -33,65 +33,65 @@ along with GCC; see the file COPYING3. If not see namespace elna::gcc { - class generic_visitor final : public frontend::empty_visitor + class generic_visitor final : public boot::empty_visitor { tree current_expression{ NULL_TREE }; - elna::frontend::symbol_bag bag; + elna::boot::symbol_bag bag; std::shared_ptr symbols; void enter_scope(); tree leave_scope(); - void make_if_branch(frontend::conditional_statements& branch, tree goto_endif); + void make_if_branch(boot::conditional_statements& branch, tree goto_endif); - tree build_arithmetic_operation(frontend::binary_expression *expression, + tree build_arithmetic_operation(boot::binary_expression *expression, tree_code operator_code, tree left, tree right); - tree build_comparison_operation(frontend::binary_expression *expression, + tree build_comparison_operation(boot::binary_expression *expression, tree_code operator_code, tree left, tree right); - tree build_bit_logic_operation(frontend::binary_expression *expression, tree left, tree right); - tree build_equality_operation(frontend::binary_expression *expression, tree left, tree right); + tree build_bit_logic_operation(boot::binary_expression *expression, tree left, tree right); + tree build_equality_operation(boot::binary_expression *expression, tree left, tree right); void build_procedure_call(location_t call_location, - tree procedure_address, const std::vector& arguments); + tree procedure_address, const std::vector& arguments); void build_record_call(location_t call_location, - tree symbol, const std::vector& arguments); - bool build_builtin_procedures(frontend::procedure_call *call); - void build_assert_builtin(location_t call_location, const std::vector& arguments); + tree symbol, const std::vector& arguments); + bool build_builtin_procedures(boot::procedure_call *call); + void build_assert_builtin(location_t call_location, const std::vector& arguments); - bool expect_trait_type_only(frontend::traits_expression *trait); - bool expect_trait_for_integral_type(frontend::traits_expression *trait); - void visit_statements(const std::vector& statements); + bool expect_trait_type_only(boot::traits_expression *trait); + bool expect_trait_for_integral_type(boot::traits_expression *trait); + void visit_statements(const std::vector& statements); bool assert_constant(location_t expression_location); public: - generic_visitor(std::shared_ptr symbol_table, elna::frontend::symbol_bag bag); + generic_visitor(std::shared_ptr symbol_table, elna::boot::symbol_bag bag); - void visit(frontend::program *program) override; - void visit(frontend::procedure_declaration *definition) override; - void visit(frontend::procedure_call *call) override; - void visit(frontend::cast_expression *expression) override; - void visit(frontend::traits_expression *trait) override; - void visit(frontend::literal *literal) override; - void visit(frontend::literal *literal) override; - void visit(frontend::literal *literal) override; - void visit(frontend::literal *boolean) override; - void visit(frontend::literal *character) override; - void visit(frontend::literal *) override; - void visit(frontend::literal *string) override; - void visit(frontend::binary_expression *expression) override; - void visit(frontend::unary_expression *expression) override; - void visit(frontend::constant_declaration *definition) override; - void visit(frontend::variable_declaration *declaration) override; - void visit(frontend::named_expression *expression) override; - void visit(frontend::array_access_expression *expression) override; - void visit(frontend::field_access_expression *expression) override; - void visit(frontend::dereference_expression *expression) override; - void visit(frontend::unit *unit) override; - void visit(frontend::assign_statement *statement) override; - void visit(frontend::if_statement *statement) override; - void visit(frontend::import_declaration *) override; - void visit(frontend::while_statement *statement) override; - void visit(frontend::return_statement *statement) override; - void visit(frontend::defer_statement *statement) override; - void visit(frontend::case_statement *statement) override; + void visit(boot::program *program) override; + void visit(boot::procedure_declaration *definition) override; + void visit(boot::procedure_call *call) override; + void visit(boot::cast_expression *expression) override; + void visit(boot::traits_expression *trait) override; + void visit(boot::literal *literal) override; + void visit(boot::literal *literal) override; + void visit(boot::literal *literal) override; + void visit(boot::literal *boolean) override; + void visit(boot::literal *character) override; + void visit(boot::literal *) override; + void visit(boot::literal *string) override; + void visit(boot::binary_expression *expression) override; + void visit(boot::unary_expression *expression) override; + void visit(boot::constant_declaration *definition) override; + void visit(boot::variable_declaration *declaration) override; + void visit(boot::named_expression *expression) override; + void visit(boot::array_access_expression *expression) override; + void visit(boot::field_access_expression *expression) override; + void visit(boot::dereference_expression *expression) override; + void visit(boot::unit *unit) override; + void visit(boot::assign_statement *statement) override; + void visit(boot::if_statement *statement) override; + void visit(boot::import_declaration *) override; + void visit(boot::while_statement *statement) override; + void visit(boot::return_statement *statement) override; + void visit(boot::defer_statement *statement) override; + void visit(boot::case_statement *statement) override; }; } diff --git a/include/elna/gcc/elna-tree.h b/include/elna/gcc/elna-tree.h index 48dfeb5..f1402a7 100644 --- a/include/elna/gcc/elna-tree.h +++ b/include/elna/gcc/elna-tree.h @@ -27,13 +27,13 @@ along with GCC; see the file COPYING3. If not see #include "stringpool.h" #include "fold-const.h" -#include "elna/frontend/ast.h" -#include "elna/frontend/symbol.h" +#include "elna/boot/ast.h" +#include "elna/boot/symbol.h" #include "elna/gcc/elna1.h" namespace elna::gcc { - using symbol_table = frontend::symbol_map; + using symbol_table = boot::symbol_map; bool is_integral_type(tree type); bool is_numeric_type(tree type); @@ -74,11 +74,11 @@ namespace elna::gcc void defer(tree statement_tree); tree chain_defer(); - tree do_pointer_arithmetic(frontend::binary_operator binary_operator, + tree do_pointer_arithmetic(boot::binary_operator binary_operator, tree left, tree right, location_t expression_location); - tree build_binary_operation(bool condition, frontend::binary_expression *expression, + tree build_binary_operation(bool condition, boot::binary_expression *expression, tree_code operator_code, tree left, tree right, tree target_type); - tree build_arithmetic_operation(frontend::binary_expression *expression, + tree build_arithmetic_operation(boot::binary_expression *expression, tree_code operator_code, tree left, tree right); tree build_field(location_t location, tree record_type, const std::string name, tree type); tree find_field_by_name(location_t expression_location, tree type, const std::string& field_name); -- cgit v1.2.3