From 50970f3289b5f0175b61964adb3a85e877805cea Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Wed, 2 Apr 2025 21:08:15 +0200 Subject: [PATCH] Add the unreachable builtin function --- boot/ast.cc | 103 ++++++++++++++++++++++++++++++---------- boot/parser.yy | 31 ++++++------ boot/semantic.cc | 2 +- gcc/elna-builtins.cc | 2 + gcc/elna-generic.cc | 2 +- include/elna/boot/ast.h | 69 ++++++++++++++++----------- 6 files changed, 136 insertions(+), 73 deletions(-) diff --git a/boot/ast.cc b/boot/ast.cc index 588830c..0ac0b81 100644 --- a/boot/ast.cc +++ b/boot/ast.cc @@ -103,32 +103,32 @@ namespace elna::boot { } - std::shared_ptr type_expression::is_primitive() + primitive_type_expression *type_expression::is_primitive() { return nullptr; } - std::shared_ptr type_expression::is_array() + array_type_expression *type_expression::is_array() { return nullptr; } - std::shared_ptr type_expression::is_pointer() + pointer_type_expression *type_expression::is_pointer() { return nullptr; } - std::shared_ptr type_expression::is_record() + record_type_expression *type_expression::is_record() { return nullptr; } - std::shared_ptr type_expression::is_union() + union_type_expression *type_expression::is_union() { return nullptr; } - std::shared_ptr type_expression::is_procedure() + procedure_type_expression *type_expression::is_procedure() { return nullptr; } @@ -143,25 +143,30 @@ namespace elna::boot visitor->visit(this); } - std::shared_ptr primitive_type_expression::is_primitive() + primitive_type_expression *primitive_type_expression::is_primitive() { - return std::static_pointer_cast(shared_from_this()); + return this; } array_type_expression::array_type_expression(const struct position position, - std::shared_ptr base, const std::uint32_t size) + type_expression *base, const std::uint32_t size) : type_expression(position), m_base(base), size(size) { } + array_type_expression::~array_type_expression() + { + delete m_base; + } + void array_type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } - std::shared_ptr array_type_expression::is_array() + array_type_expression *array_type_expression::is_array() { - return std::static_pointer_cast(shared_from_this()); + return this; } type_expression& array_type_expression::base() @@ -170,19 +175,24 @@ namespace elna::boot } pointer_type_expression::pointer_type_expression(const struct position position, - std::shared_ptr base) + type_expression *base) : type_expression(position), m_base(base) { } + pointer_type_expression::~pointer_type_expression() + { + delete m_base; + } + void pointer_type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } - std::shared_ptr pointer_type_expression::is_pointer() + pointer_type_expression *pointer_type_expression::is_pointer() { - return std::static_pointer_cast(shared_from_this()); + return this; } type_expression& pointer_type_expression::base() @@ -196,14 +206,22 @@ namespace elna::boot { } + record_type_expression::~record_type_expression() + { + for (const field_declaration& field : this->fields) + { + delete field.second; + } + } + void record_type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } - std::shared_ptr record_type_expression::is_record() + record_type_expression *record_type_expression::is_record() { - return std::static_pointer_cast(shared_from_this()); + return this; } union_type_expression::union_type_expression(const struct position position, @@ -212,14 +230,22 @@ namespace elna::boot { } + union_type_expression::~union_type_expression() + { + for (const field_declaration& field : this->fields) + { + delete field.second; + } + } + void union_type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } - std::shared_ptr union_type_expression::is_union() + union_type_expression *union_type_expression::is_union() { - return std::static_pointer_cast(shared_from_this()); + return this; } variable_declaration::variable_declaration(const struct position position, const std::string& identifier, @@ -264,19 +290,30 @@ namespace elna::boot delete m_body; } - procedure_type_expression::procedure_type_expression(const struct position position, - return_declaration> return_type) + procedure_type_expression::procedure_type_expression(const struct position position, return_t return_type) : type_expression(position), return_type(return_type) { } + procedure_type_expression::~procedure_type_expression() + { + if (return_type.proper_type != nullptr) + { + delete return_type.proper_type; + } + for (const type_expression *parameter : this->parameters) + { + delete parameter; + } + } + void procedure_type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } procedure_definition::procedure_definition(const struct position position, const std::string& identifier, - const bool exported, std::shared_ptr heading, block *body) + const bool exported, procedure_type_expression *heading, block *body) : definition(position, identifier, exported), m_heading(heading), body(body) { } @@ -286,9 +323,9 @@ namespace elna::boot visitor->visit(this); } - std::shared_ptr procedure_type_expression::is_procedure() + procedure_type_expression *procedure_type_expression::is_procedure() { - return std::static_pointer_cast(shared_from_this()); + return this; } procedure_type_expression& procedure_definition::heading() @@ -298,15 +335,21 @@ namespace elna::boot procedure_definition::~procedure_definition() { + delete m_heading; delete body; } type_definition::type_definition(const struct position position, const std::string& identifier, - const bool exported, std::shared_ptr body) + const bool exported, type_expression *body) : definition(position, identifier, exported), m_body(body) { } + type_definition::~type_definition() + { + delete m_body; + } + void type_definition::accept(parser_visitor *visitor) { visitor->visit(this); @@ -637,8 +680,7 @@ namespace elna::boot delete m_callable; } - cast_expression::cast_expression(const struct position position, - std::shared_ptr target, expression *value) + cast_expression::cast_expression(const struct position position, type_expression *target, expression *value) : node(position), m_target(target), m_value(value) { } @@ -665,6 +707,7 @@ namespace elna::boot cast_expression::~cast_expression() { + delete m_target; delete m_value; } @@ -673,6 +716,14 @@ namespace elna::boot { } + traits_expression::~traits_expression() + { + for (const type_expression *parameter : this->parameters) + { + delete parameter; + } + } + void traits_expression::accept(parser_visitor *visitor) { visitor->visit(this); diff --git a/boot/parser.yy b/boot/parser.yy index 19cb999..ea6df6f 100644 --- a/boot/parser.yy +++ b/boot/parser.yy @@ -127,8 +127,8 @@ along with GCC; see the file COPYING3. If not see %type constant_definition; %type > constant_part constant_definitions; %type > variable_declarations variable_part variable_declaration; -%type > type_expression; -%type >> type_expressions; +%type type_expression; +%type > type_expressions; %type traits_expression; %type expression operand qualident; %type unary_expression; @@ -143,14 +143,14 @@ along with GCC; see the file COPYING3. If not see %type statement; %type > statements; %type procedure_definition; -%type , std::shared_ptr>> procedure_heading; +%type , elna::boot::procedure_type_expression *>> procedure_heading; %type return_declaration; %type > procedure_definitions procedure_part; %type type_definition; %type > type_definitions type_part; %type block; %type field_declaration formal_parameter; -%type >>> +%type >> optional_fields required_fields formal_parameters; %type > elsif_then_statements elsif_do_statements; %type cast_expression; @@ -202,8 +202,7 @@ return_declaration: procedure_heading: "(" formal_parameters ")" return_declaration { - $$.second = std::make_shared(boot::make_position(@1), - std::move($4)); + $$.second = new boot::procedure_type_expression(boot::make_position(@1), std::move($4)); for (auto& [name, type] : $2) { $$.first.emplace_back(std::move(name)); @@ -213,8 +212,7 @@ procedure_heading: procedure_definition: "proc" identifier_definition procedure_heading ";" block { - $$ = new boot::procedure_definition(boot::make_position(@1), - $2.first, $2.second, $3.second, $5); + $$ = new boot::procedure_definition(boot::make_position(@1), $2.first, $2.second, $3.second, $5); std::swap($3.first, $$->parameter_names); } | "proc" identifier_definition procedure_heading ";" "extern" @@ -489,37 +487,38 @@ optional_fields: type_expression: "[" INTEGER "]" type_expression { - $$ = std::make_shared(boot::make_position(@1), $4, $2); + $$ = new boot::array_type_expression(boot::make_position(@1), $4, $2); } | "^" type_expression { - $$ = std::make_shared(boot::make_position(@1), $2); + $$ = new boot::pointer_type_expression(boot::make_position(@1), $2); } | "record" optional_fields "end" { - $$ = std::make_shared(boot::make_position(@1), std::move($2)); + $$ = new boot::record_type_expression(boot::make_position(@1), std::move($2)); } | "union" required_fields "end" { - $$ = std::make_shared(boot::make_position(@1), std::move($2)); + $$ = new boot::union_type_expression(boot::make_position(@1), std::move($2)); } | "proc" "(" type_expressions ")" return_declaration { - auto result = std::make_shared(boot::make_position(@1), - std::move($5)); + auto result = new boot::procedure_type_expression(boot::make_position(@1), std::move($5)); std::swap(result->parameters, $3); $$ = result; } | IDENTIFIER { - $$ = std::make_shared(boot::make_position(@1), $1); + $$ = new boot::primitive_type_expression(boot::make_position(@1), $1); } variable_declaration: identifier_definitions ":" type_expression { + std::shared_ptr shared_type{ $3 }; + for (const std::pair& identifier : $1) { boot::variable_declaration *declaration = new boot::variable_declaration( - boot::make_position(@2), identifier.first, $3, identifier.second); + boot::make_position(@2), identifier.first, shared_type, identifier.second); $$.push_back(declaration); } } diff --git a/boot/semantic.cc b/boot/semantic.cc index 72fea6b..6c9f456 100644 --- a/boot/semantic.cc +++ b/boot/semantic.cc @@ -65,7 +65,7 @@ namespace elna::boot } procedure_type result_type = procedure_type(result_return); - for (std::shared_ptr parameter : type_expression.parameters) + for (struct type_expression *parameter : type_expression.parameters) { parameter->accept(this); result_type.parameters.push_back(this->current_type); diff --git a/gcc/elna-builtins.cc b/gcc/elna-builtins.cc index 60b929c..e3cda7c 100644 --- a/gcc/elna-builtins.cc +++ b/gcc/elna-builtins.cc @@ -73,6 +73,8 @@ namespace elna::gcc declare_builtin_type(symbol_table, "Float", elna_float_type_node); declare_builtin_type(symbol_table, "String", elna_string_type_node); + symbol_table->enter("unreachable", *elna_global_decls->get("__builtin_unreachable")); + return symbol_table; } } diff --git a/gcc/elna-generic.cc b/gcc/elna-generic.cc index 4796d32..ff13659 100644 --- a/gcc/elna-generic.cc +++ b/gcc/elna-generic.cc @@ -281,7 +281,7 @@ namespace elna::gcc std::vector::const_iterator parameter_name = definition->parameter_names.cbegin(); - for (std::shared_ptr parameter : definition->heading().parameters) + for (boot::type_expression *parameter : definition->heading().parameters) { tree declaration_tree = build_decl(get_location(¶meter->position()), PARM_DECL, get_identifier(parameter_name->c_str()), function_args_iter_cond(¶meter_type)); diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h index b06f863..65a3f5b 100644 --- a/include/elna/boot/ast.h +++ b/include/elna/boot/ast.h @@ -185,15 +185,15 @@ namespace elna::boot /** * Some type expression. */ - class type_expression : public node, public std::enable_shared_from_this + class type_expression : public node { public: - virtual std::shared_ptr is_primitive(); - virtual std::shared_ptr is_array(); - virtual std::shared_ptr is_pointer(); - virtual std::shared_ptr is_record(); - virtual std::shared_ptr is_union(); - virtual std::shared_ptr is_procedure(); + virtual primitive_type_expression *is_primitive(); + 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(); protected: type_expression(const struct position position); @@ -209,37 +209,41 @@ namespace elna::boot primitive_type_expression(const struct position position, const std::string& name); void accept(parser_visitor *visitor) override; - std::shared_ptr is_primitive() override; + primitive_type_expression *is_primitive() override; }; class array_type_expression : public type_expression { - std::shared_ptr m_base; + type_expression *m_base; public: const std::uint32_t size; array_type_expression(const struct position position, - std::shared_ptr base, const std::uint32_t size); + type_expression *base, const std::uint32_t size); + ~array_type_expression(); + void accept(parser_visitor *visitor) override; - std::shared_ptr is_array() override; + array_type_expression *is_array() override; type_expression& base(); }; class pointer_type_expression : public type_expression { - std::shared_ptr m_base; + type_expression *m_base; public: - pointer_type_expression(const struct position position, std::shared_ptr base); + pointer_type_expression(const struct position position, type_expression *base); + ~pointer_type_expression(); + void accept(parser_visitor *visitor) override; - std::shared_ptr is_pointer() override; + pointer_type_expression *is_pointer() override; type_expression& base(); }; - using field_declaration = std::pair>; + using field_declaration = std::pair; class record_type_expression : public type_expression { @@ -247,9 +251,10 @@ namespace elna::boot const std::vector fields; record_type_expression(const struct position position, std::vector&& fields); + ~record_type_expression(); void accept(parser_visitor *visitor) override; - std::shared_ptr is_record() override; + record_type_expression *is_record() override; }; class union_type_expression : public type_expression @@ -258,9 +263,10 @@ namespace elna::boot std::vector fields; union_type_expression(const struct position position, std::vector&& fields); + ~union_type_expression(); void accept(parser_visitor *visitor) override; - std::shared_ptr is_union() override; + union_type_expression *is_union() override; }; /** @@ -273,6 +279,7 @@ namespace elna::boot public: variable_declaration(const struct position position, const std::string& identifier, std::shared_ptr variable_type, const bool exported = false); + void accept(parser_visitor *visitor) override; type_expression& variable_type(); @@ -321,16 +328,16 @@ namespace elna::boot class procedure_type_expression : public type_expression { public: - using return_t = return_declaration>; + using return_t = return_declaration; const return_t return_type; - std::vector> parameters; + std::vector parameters; - procedure_type_expression(const struct position position, - return_t return_type = return_t()); + procedure_type_expression(const struct position position, return_t return_type = return_t()); + ~procedure_type_expression(); void accept(parser_visitor *visitor) override; - std::shared_ptr is_procedure() override; + procedure_type_expression *is_procedure() override; }; /** @@ -338,14 +345,14 @@ namespace elna::boot */ class procedure_definition : public definition { - std::shared_ptr m_heading; + procedure_type_expression *m_heading; public: block *const body; std::vector parameter_names; procedure_definition(const struct position position, const std::string& identifier, - const bool exported, std::shared_ptr heading, block *body = nullptr); + const bool exported, procedure_type_expression *heading, block *body = nullptr); void accept(parser_visitor *visitor) override; procedure_type_expression& heading(); @@ -358,11 +365,13 @@ namespace elna::boot */ class type_definition : public definition { - std::shared_ptr m_body; + type_expression *m_body; public: type_definition(const struct position position, const std::string& identifier, - const bool exported, std::shared_ptr expression); + const bool exported, type_expression *expression); + ~type_definition(); + void accept(parser_visitor *visitor) override; type_expression& body(); @@ -373,11 +382,11 @@ namespace elna::boot */ class cast_expression : public expression { - std::shared_ptr m_target; + type_expression *m_target; expression *m_value; public: - cast_expression(const struct position position, std::shared_ptr target, expression *value); + cast_expression(const struct position position, type_expression *target, expression *value); void accept(parser_visitor *visitor) override; cast_expression *is_cast() override; @@ -390,10 +399,12 @@ namespace elna::boot class traits_expression : public expression { public: - std::vector> parameters; + std::vector parameters; const std::string name; traits_expression(const struct position position, const std::string& name); + ~traits_expression(); + void accept(parser_visitor *visitor) override; traits_expression *is_traits() override; };