diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-02-12 14:50:09 +0100 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-02-12 14:50:09 +0100 |
| commit | b37eb0690c9905b84c224cc693bbf1cab84f55fd (patch) | |
| tree | 60e4c9533f338f9acdfc42a39c868edbd2e86cde /include | |
| parent | 2061fece3dc46f745cc983935ae930ce84092dfa (diff) | |
| download | elna-b37eb0690c9905b84c224cc693bbf1cab84f55fd.tar.gz | |
Remove the old, not self-hosted frontend
Diffstat (limited to 'include')
| -rw-r--r-- | include/elna/frontend/ast.h | 815 | ||||
| -rw-r--r-- | include/elna/frontend/driver.h | 51 | ||||
| -rw-r--r-- | include/elna/frontend/result.h | 124 | ||||
| -rw-r--r-- | include/elna/frontend/symbol.h | 457 |
4 files changed, 0 insertions, 1447 deletions
diff --git a/include/elna/frontend/ast.h b/include/elna/frontend/ast.h deleted file mode 100644 index bbb8a36..0000000 --- a/include/elna/frontend/ast.h +++ /dev/null @@ -1,815 +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 -<http://www.gnu.org/licenses/>. */ - -#pragma once - -#include <cstdint> -#include <memory> -#include <string> -#include <vector> -#include <optional> -#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 named_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 variable_expression; - class array_access_expression; - class field_access_expression; - class dereference_expression; - class designator_expression; - class literal_expression; - template<typename T> - 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(named_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(variable_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<std::int32_t> *) = 0; - virtual void visit(literal<std::uint32_t> *) = 0; - virtual void visit(literal<double> *) = 0; - virtual void visit(literal<bool> *) = 0; - virtual void visit(literal<unsigned char> *) = 0; - virtual void visit(literal<std::nullptr_t> *) = 0; - virtual void visit(literal<std::string> *) = 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(named_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(variable_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<std::int32_t> *) override; - [[noreturn]] virtual void visit(literal<std::uint32_t> *) override; - [[noreturn]] virtual void visit(literal<double> *) override; - [[noreturn]] virtual void visit(literal<bool> *) override; - [[noreturn]] virtual void visit(literal<unsigned char> *) override; - [[noreturn]] virtual void visit(literal<std::nullptr_t> *) override; - [[noreturn]] virtual void visit(literal<std::string> *) 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 node - { - public: - virtual named_type_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(); - - protected: - type_expression(const struct position position); - }; - - /** - * Expression refering to a type by its name. - */ - class named_type_expression : public type_expression - { - public: - const std::string name; - - named_type_expression(const struct position position, const std::string& name); - void accept(parser_visitor *visitor) override; - named_type_expression *is_named() override; - }; - - 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<std::string, type_expression *>; - - class record_type_expression : public type_expression - { - public: - const std::vector<field_declaration> fields; - - record_type_expression(const struct position position, std::vector<field_declaration>&& 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<field_declaration> fields; - - union_type_expression(const struct position position, std::vector<field_declaration>&& 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<std::string> members; - - enumeration_type_expression(const struct position, std::vector<std::string>&& members); - - void accept(parser_visitor *visitor) override; - enumeration_type_expression *is_enumeration() override; - }; - - /** - * Variable declaration. - */ - class variable_declaration : public node - { - std::shared_ptr<type_expression> m_variable_type; - - public: - variable_declaration(const struct position position, - std::vector<identifier_definition>&& identifier, std::shared_ptr<type_expression> variable_type, - expression *body = nullptr); - variable_declaration(const struct position position, - std::vector<identifier_definition>&& identifier, std::shared_ptr<type_expression> variable_type, - std::monostate); - - void accept(parser_visitor *visitor) override; - - bool has_initializer() const; - - const std::vector<identifier_definition> 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; - - protected: - literal_expression(); - }; - - /** - * 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<type_expression *>; - - const return_t return_type; - std::vector<type_expression *> 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<constant_declaration*>&& constants, std::vector<variable_declaration *>&& variables, - std::vector<statement *>&& body); - block(const block&) = delete; - block(block&& that); - - block& operator=(const block&) = delete; - block& operator=(block&& that); - - const std::vector<variable_declaration *>& variables(); - const std::vector<constant_declaration *>& constants(); - const std::vector<statement *>& body(); - - virtual ~block(); - - private: - std::vector<variable_declaration *> m_variables; - std::vector<constant_declaration *> m_constants; - std::vector<statement *> m_body; - - }; - - /** - * Procedure definition. - */ - class procedure_declaration : public declaration - { - procedure_type_expression *m_heading; - - public: - std::optional<block> body; - std::vector<std::string> 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<type_expression *> parameters; - const std::string name; - std::vector<type> 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<statement *> statements; - - conditional_statements(expression *prerequisite, std::vector<statement *>&& 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<expression *> labels; - std::vector<statement *> statements; - }; - - class case_statement : public statement - { - expression *m_condition; - - public: - const std::vector<switch_case> cases; - const std::vector<statement *> *alternative; - - case_statement(const struct position position, expression *condition, - std::vector<switch_case>&& cases, std::vector<statement *> *alternative = nullptr); - void accept(parser_visitor *visitor) override; - expression& condition(); - }; - - class designator_expression : public expression - { - public: - virtual variable_expression *is_variable(); - 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; - - protected: - designator_expression(); - }; - - class variable_expression : public designator_expression, public literal_expression - { - public: - const std::string name; - - variable_expression(const struct position position, const std::string& name); - void accept(parser_visitor *visitor) override; - - variable_expression *is_variable() 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<expression *> 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<conditional_statements *> branches; - const std::vector<statement *> *alternative; - - if_statement(const struct position position, conditional_statements *body, - std::vector<conditional_statements *>&& branches, - std::vector<statement *> *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<std::string> segments; - - import_declaration(const struct position position, std::vector<std::string>&& segments); - void accept(parser_visitor *visitor) override; - }; - - /** - * While-statement. - */ - class while_statement : public statement - { - conditional_statements *m_body; - - public: - const std::vector<conditional_statements *> branches; - - while_statement(const struct position position, conditional_statements *body, - std::vector<conditional_statements *>&& branches); - void accept(parser_visitor *visitor) override; - - conditional_statements& body(); - - virtual ~while_statement() override; - }; - - class unit : public node - { - public: - std::vector<import_declaration *> imports; - std::vector<constant_declaration *> constants; - std::vector<type_declaration *> types; - std::vector<variable_declaration *> variables; - std::vector<procedure_declaration *> procedures; - - unit(const struct position position); - virtual void accept(parser_visitor *visitor) override; - - virtual ~unit() override; - }; - - class program : public unit - { - public: - std::vector<statement *> body; - - program(const struct position position); - void accept(parser_visitor *visitor) override; - - virtual ~program() override; - }; - - template<typename T> - 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<statement *> statements; - - defer_statement(const struct position position, std::vector<statement *>&& 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/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 -<http://www.gnu.org/licenses/>. */ - -#pragma once - -#include <optional> -#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<unit> tree; - - driver(const char *input_file); - }; - - constexpr char escape_invalid_char = '\xff'; - - char escape_char(char escape); - std::optional<std::string> 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 -<http://www.gnu.org/licenses/>. */ - -#pragma once - -#include <cstddef> -#include <string> -#include <deque> -#include <memory> -#include <variant> - -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<std::unique_ptr<error>>; - - class error_container - { - protected: - error_list m_errors; - - error_container(const char *input_file); - - public: - const char *input_file; - - error_list& errors(); - - template<typename T, typename... Args> - void add_error(Args... arguments) - { - auto new_error = std::make_unique<T>(arguments...); - m_errors.emplace_back(std::move(new_error)); - } - - bool has_errors() const; - }; - - /** - * Tags a procedure type as never returning. - */ - template<typename T> - 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<elna::frontend::identifier_definition> -{ - std::size_t operator()(const elna::frontend::identifier_definition& key) const noexcept; -}; 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 -<http://www.gnu.org/licenses/>. */ - -#pragma once - -#include <cstdint> -#include <unordered_map> -#include <string> -#include <memory> -#include <vector> -#include <forward_list> - -#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_type> alias; - std::shared_ptr<primitive_type> primitive; - std::shared_ptr<record_type> record; - std::shared_ptr<union_type> _union; - std::shared_ptr<pointer_type> pointer; - std::shared_ptr<array_type> array; - std::shared_ptr<procedure_type> procedure; - std::shared_ptr<enumeration_type> enumeration; - }; - - void copy(const type& other); - void move(type&& other); - - public: - type(); - explicit type(std::shared_ptr<alias_type> alias); - explicit type(std::shared_ptr<primitive_type> primitive); - explicit type(std::shared_ptr<record_type> record); - explicit type(std::shared_ptr<union_type> _union); - explicit type(std::shared_ptr<pointer_type> pointer); - explicit type(std::shared_ptr<array_type> array); - explicit type(std::shared_ptr<procedure_type> procedure); - explicit type(std::shared_ptr<enumeration_type> 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<typename T> - std::shared_ptr<T> 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<std::string, type>; - - struct record_type - { - std::vector<type_field> fields; - }; - - struct union_type - { - std::vector<type_field> fields; - }; - - struct procedure_type - { - using return_t = return_declaration<type>; - - std::vector<type> parameters; - const return_t return_type; - - procedure_type(return_t return_type = return_t()); - }; - - struct enumeration_type - { - std::vector<std::string> members; - - explicit enumeration_type(const std::vector<std::string>& members); - }; - - class type_info; - class procedure_info; - class constant_info; - class variable_info; - - class info : public std::enable_shared_from_this<info> - { - public: - bool exported{ false }; - - virtual ~info() = 0; - - virtual std::shared_ptr<type_info> is_type(); - virtual std::shared_ptr<procedure_info> is_procedure(); - virtual std::shared_ptr<constant_info> is_constant(); - virtual std::shared_ptr<variable_info> is_variable(); - }; - - /** - * Symbol table. - */ - template<typename T, typename U, U nothing> - class symbol_map - { - public: - using symbol_ptr = typename std::enable_if< - std::is_convertible<U, T>::value || std::is_assignable<T, U>::value, - T - >::type; - using iterator = typename std::unordered_map<std::string, symbol_ptr>::iterator; - using const_iterator = typename std::unordered_map<std::string, symbol_ptr>::const_iterator; - - private: - std::unordered_map<std::string, symbol_ptr> entries; - std::shared_ptr<symbol_map> outer_scope; - - public: - /** - * Constructs a new symbol with an optional outer scope. - * - * \param scope Outer scope. - */ - explicit symbol_map(std::shared_ptr<symbol_map> 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<symbol_map> scope() - { - return this->outer_scope; - } - }; - - using symbol_table = symbol_map<std::shared_ptr<info>, std::nullptr_t, nullptr>; - using forward_table = std::unordered_map<std::string, std::shared_ptr<alias_type>>; - - class type_info : public info - { - public: - const type symbol; - - explicit type_info(const type symbol); - std::shared_ptr<type_info> is_type() override; - }; - - /** - * Procedure symbol information. - */ - class procedure_info : public info - { - public: - /// Procedure type. - const procedure_type symbol; - - /// Parameter names. - const std::vector<std::string> names; - - /// Local definitions. - std::shared_ptr<symbol_table> 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<std::string> names, - std::shared_ptr<symbol_table> scope = nullptr); - - std::shared_ptr<procedure_info> 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<std::int32_t, std::uint32_t, double, bool, unsigned char, std::nullptr_t, std::string>; - - const variant symbol; - - explicit constant_info(const variant& symbol); - std::shared_ptr<constant_info> 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<variable_info> is_variable() override; - }; - - std::shared_ptr<symbol_table> 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<symbol_table> symbols; - std::forward_list<std::shared_ptr<symbol_table>> 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<symbol_table> 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<info> 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<info> entry); - - /** - * Enters a new scope. - * - * \return Reference to the allocated scope. - */ - std::shared_ptr<symbol_table> enter(); - - /** - * Sets the current scope to \a child. - * - * \param child New scope. - */ - void enter(std::shared_ptr<symbol_table> child); - - /** - * Leave the current scope. - * - * \return Left scope. - */ - std::shared_ptr<symbol_table> 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<alias_type> 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<alias_type> 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); - }; -} |
