diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-07-10 17:06:21 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-07-10 17:06:21 +0200 |
| commit | b7dd49c1d5832ac7d82edba27316884ab53e614c (patch) | |
| tree | 24afc27b83974c9322088e5469d2d1894c0eb314 /include | |
| parent | 36440faa345bf842c348711325312c2b02e4cc23 (diff) | |
| download | elna-b7dd49c1d5832ac7d82edba27316884ab53e614c.tar.gz | |
Report if the base type of a record is not a record
Diffstat (limited to 'include')
| -rw-r--r-- | include/elna/boot/ast.h | 107 | ||||
| -rw-r--r-- | include/elna/boot/semantic.h | 62 | ||||
| -rw-r--r-- | include/elna/boot/symbol.h | 11 | ||||
| -rw-r--r-- | include/elna/gcc/elna-generic.h | 4 |
4 files changed, 115 insertions, 69 deletions
diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h index fe502a4..1c27166 100644 --- a/include/elna/boot/ast.h +++ b/include/elna/boot/ast.h @@ -111,7 +111,6 @@ namespace elna::boot virtual void visit(unit *) = 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; @@ -139,7 +138,6 @@ namespace elna::boot [[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(type_declaration *) override; @@ -179,6 +177,50 @@ namespace elna::boot }; /** + * Abstract visitor that visits all nodes recursively. + */ + class walking_visitor : public parser_visitor + { + public: + virtual void visit(array_type_expression *) override; + virtual void visit(pointer_type_expression *) override; + virtual void visit(type_declaration *) override; + virtual void visit(record_type_expression *) override; + virtual void visit(union_type_expression *) override; + virtual void visit(procedure_type_expression *) override; + virtual void visit(enumeration_type_expression *) override; + + virtual void visit(variable_declaration *) override; + virtual void visit(constant_declaration *) override; + virtual void visit(procedure_declaration *) override; + virtual void visit(assign_statement *) override; + virtual void visit(if_statement *) override; + virtual void visit(import_declaration *) override; + virtual void visit(while_statement *statement) override; + virtual void visit(return_statement *statement) override; + virtual void visit(defer_statement *statement) override; + virtual void visit(empty_statement *) override; + virtual void visit(case_statement *statement) override; + virtual void visit(procedure_call *call) override; + virtual void visit(unit *unit) override; + virtual void visit(cast_expression *expression) override; + virtual void visit(traits_expression *trait) override; + virtual void visit(binary_expression *expression) override; + virtual void visit(unary_expression *expression) override; + virtual void visit(named_expression *) override; + virtual void visit(array_access_expression *expression) override; + virtual void visit(field_access_expression *expression) override; + virtual void visit(dereference_expression *expression) override; + virtual void visit(literal<std::int32_t> *) override; + virtual void visit(literal<std::uint32_t> *) override; + virtual void visit(literal<double> *) override; + virtual void visit(literal<bool> *) override; + virtual void visit(literal<unsigned char> *) override; + virtual void visit(literal<std::nullptr_t> *) override; + virtual void visit(literal<std::string> *) override; + }; + + /** * AST node. */ class node @@ -242,9 +284,6 @@ namespace elna::boot 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 @@ -331,7 +370,7 @@ namespace elna::boot public: variable_declaration(const struct position position, std::vector<identifier_definition>&& identifier, std::shared_ptr<type_expression> variable_type, - expression *body = nullptr); + expression *initializer = nullptr); variable_declaration(const struct position position, std::vector<identifier_definition>&& identifier, std::shared_ptr<type_expression> variable_type, std::monostate); @@ -342,7 +381,7 @@ namespace elna::boot const std::vector<identifier_definition> identifiers; type_expression& variable_type(); - expression *const body{ nullptr }; + expression *const initializer{ nullptr }; const bool is_extern{ false }; }; @@ -360,14 +399,14 @@ namespace elna::boot */ class constant_declaration : public declaration { - expression *m_body; + expression *m_initializer; public: constant_declaration(const struct position position, identifier_definition identifier, - expression *body); + expression *initializer); void accept(parser_visitor *visitor) override; - expression& body(); + expression& initializer(); virtual ~constant_declaration() override; }; @@ -391,27 +430,27 @@ namespace elna::boot procedure_type_expression *is_procedure() override; }; - struct block + struct procedure_body { - block(std::vector<constant_declaration*>&& constants, std::vector<variable_declaration *>&& variables, - std::vector<statement *>&& body); - block(std::vector<constant_declaration*>&& constants, std::vector<variable_declaration *>&& variables); - block(const block&) = delete; - block(block&& that); + procedure_body(std::vector<constant_declaration*>&& constants, + std::vector<variable_declaration *>&& variables, std::vector<statement *>&& statements); + procedure_body(std::vector<constant_declaration*>&& constants, std::vector<variable_declaration *>&& variables); + procedure_body(const procedure_body&) = delete; + procedure_body(procedure_body&& that); - block& operator=(const block&) = delete; - block& operator=(block&& that); + procedure_body& operator=(const procedure_body&) = delete; + procedure_body& operator=(procedure_body&& that); const std::vector<variable_declaration *>& variables(); const std::vector<constant_declaration *>& constants(); - const std::vector<statement *>& body(); + const std::vector<statement *>& statements(); - virtual ~block(); + virtual ~procedure_body(); private: std::vector<variable_declaration *> m_variables; std::vector<constant_declaration *> m_constants; - std::vector<statement *> m_body; + std::vector<statement *> m_statements; }; @@ -423,10 +462,10 @@ namespace elna::boot procedure_type_expression *m_heading; public: - std::optional<block> body; + std::optional<procedure_body> body; procedure_declaration(const struct position position, identifier_definition identifier, - procedure_type_expression *heading, block&& body); + procedure_type_expression *heading, procedure_body&& body); procedure_declaration(const struct position position, identifier_definition identifier, procedure_type_expression *heading); void accept(parser_visitor *visitor) override; @@ -441,16 +480,16 @@ namespace elna::boot */ class type_declaration : public declaration { - type_expression *m_body; + type_expression *m_underlying_type; public: type_declaration(const struct position position, identifier_definition identifier, type_expression *expression); - ~type_declaration(); + ~type_declaration() override; void accept(parser_visitor *visitor) override; - type_expression& body(); + type_expression& underlying_type(); }; /** @@ -660,18 +699,18 @@ namespace elna::boot */ class if_statement : public statement { - conditional_statements *m_body; + conditional_statements *m_branch; public: const std::vector<conditional_statements *> branches; const std::vector<statement *> *alternative; - if_statement(const struct position position, conditional_statements *body, + if_statement(const struct position position, conditional_statements *branch, std::vector<conditional_statements *>&& branches, std::vector<statement *> *alternative = nullptr); void accept(parser_visitor *visitor) override; - conditional_statements& body(); + conditional_statements& branch(); virtual ~if_statement() override; }; @@ -693,16 +732,16 @@ namespace elna::boot */ class while_statement : public statement { - conditional_statements *m_body; + conditional_statements *m_branch; public: const std::vector<conditional_statements *> branches; - while_statement(const struct position position, conditional_statements *body, + while_statement(const struct position position, conditional_statements *branch, std::vector<conditional_statements *>&& branches); void accept(parser_visitor *visitor) override; - conditional_statements& body(); + conditional_statements& branch(); virtual ~while_statement() override; }; @@ -710,7 +749,7 @@ namespace elna::boot class unit : public node { public: - std::optional<std::vector<statement *>> body; + const std::optional<std::vector<statement *>> entry_point; std::vector<import_declaration *> imports; std::vector<constant_declaration *> constants; @@ -719,7 +758,7 @@ namespace elna::boot std::vector<procedure_declaration *> procedures; unit(const struct position position); - unit(const struct position position, std::vector<statement *>&& body); + unit(const struct position position, std::vector<statement *>&& entry_point); virtual void accept(parser_visitor *visitor) override; virtual ~unit() override; diff --git a/include/elna/boot/semantic.h b/include/elna/boot/semantic.h index c6ad19d..9d79b14 100644 --- a/include/elna/boot/semantic.h +++ b/include/elna/boot/semantic.h @@ -28,6 +28,9 @@ along with GCC; see the file COPYING3. If not see namespace elna::boot { + /** + * Undeclared identifier. + */ class undeclared_error : public error { const std::string identifier; @@ -38,6 +41,9 @@ namespace elna::boot std::string what() const override; }; + /** + * A symbol was already declared in this scope. + */ class already_declared_error : public error { const std::string identifier; @@ -48,6 +54,9 @@ namespace elna::boot std::string what() const override; }; + /** + * Field with the same name is already declared in this type. + */ class field_duplication_error : public error { const std::string field_name; @@ -58,6 +67,9 @@ namespace elna::boot std::string what() const override; }; + /** + * Cyclic type declaration. + */ class cyclic_declaration_error : public error { const std::vector<std::string> cycle; @@ -68,6 +80,9 @@ namespace elna::boot std::string what() const override; }; + /** + * Procedure with a return type does not return. + */ class return_error : public error { const std::string identifier; @@ -78,6 +93,9 @@ namespace elna::boot std::string what() const override; }; + /** + * Base type of a record is not a record. + */ class base_type_error : public error { const std::string base; @@ -91,7 +109,7 @@ namespace elna::boot /** * Checks types. */ - class type_analysis_visitor final : public empty_visitor, public error_container + class type_analysis_visitor final : public walking_visitor, public error_container { bool returns; symbol_bag bag; @@ -102,23 +120,16 @@ namespace elna::boot public: explicit type_analysis_visitor(symbol_bag bag); - 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(empty_statement *) override; - void visit(case_statement *) override; - void visit(procedure_call *) override; - void visit(unit *unit) override; - void visit(type_declaration *definition) override; + void visit(procedure_declaration *declaration) override; + void visit(return_statement *statement) override; + void visit(type_declaration *declaration) override; + void visit(record_type_expression *expression) override; }; /** * Performs name analysis. */ - class name_analysis_visitor final : public parser_visitor, public error_container + class name_analysis_visitor final : public walking_visitor, public error_container { type current_type; constant_info::variant current_literal; @@ -134,36 +145,23 @@ namespace elna::boot public: name_analysis_visitor(symbol_bag bag); - void visit(type_expression *) override; void visit(array_type_expression *expression) override; void visit(pointer_type_expression *expression) override; - void visit(type_declaration *definition) override; + void visit(type_declaration *declaration) override; void visit(record_type_expression *expression) override; void visit(union_type_expression *expression) override; void visit(procedure_type_expression *expression) override; void visit(enumeration_type_expression *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 *) override; - void visit(empty_statement *statement) override; - void visit(case_statement *statement) override; + void visit(constant_declaration *declaration) override; + void visit(procedure_declaration *declaration) 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 *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<std::int32_t> *literal) override; void visit(literal<std::uint32_t> *literal) override; void visit(literal<double> *literal) override; @@ -185,8 +183,6 @@ namespace elna::boot void visit(import_declaration *) override; void visit(unit *unit) override; - void visit(type_declaration *definition) override; - void visit(variable_declaration *) override; - void visit(procedure_declaration *definition) override; + void visit(type_declaration *declaration) override; }; } diff --git a/include/elna/boot/symbol.h b/include/elna/boot/symbol.h index beb44e2..6258760 100644 --- a/include/elna/boot/symbol.h +++ b/include/elna/boot/symbol.h @@ -457,4 +457,15 @@ namespace elna::boot */ void add_import(const symbol_bag& bag); }; + + /** + * If a type is a declared name for another type, look up recursively + * the declared type. If the given type is not an alias, then this function + * returns its argument. + * + * \param alias The type to lookup the innermost declaration for. + * \return Innermost type declaration. + */ + type inner_aliased_type(type alias); + type inner_aliased_type(std::shared_ptr<alias_type> alias); } diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h index 7ee251b..28bfe2d 100644 --- a/include/elna/gcc/elna-generic.h +++ b/include/elna/gcc/elna-generic.h @@ -65,7 +65,7 @@ namespace elna::gcc public: generic_visitor(std::shared_ptr<symbol_table> symbol_table, elna::boot::symbol_bag bag); - void visit(boot::procedure_declaration *definition) override; + void visit(boot::procedure_declaration *declaration) override; void visit(boot::procedure_call *call) override; void visit(boot::cast_expression *expression) override; void visit(boot::traits_expression *trait) override; @@ -78,7 +78,7 @@ namespace elna::gcc void visit(boot::literal<std::string> *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::constant_declaration *declaration) override; void visit(boot::variable_declaration *declaration) override; void visit(boot::named_expression *expression) override; void visit(boot::array_access_expression *expression) override; |
