Add the unreachable builtin function

This commit is contained in:
Eugen Wissner 2025-04-02 21:08:15 +02:00
parent a7b5e32d09
commit 50970f3289
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
6 changed files with 136 additions and 73 deletions

View File

@ -103,32 +103,32 @@ namespace elna::boot
{ {
} }
std::shared_ptr<primitive_type_expression> type_expression::is_primitive() primitive_type_expression *type_expression::is_primitive()
{ {
return nullptr; return nullptr;
} }
std::shared_ptr<array_type_expression> type_expression::is_array() array_type_expression *type_expression::is_array()
{ {
return nullptr; return nullptr;
} }
std::shared_ptr<pointer_type_expression> type_expression::is_pointer() pointer_type_expression *type_expression::is_pointer()
{ {
return nullptr; return nullptr;
} }
std::shared_ptr<record_type_expression> type_expression::is_record() record_type_expression *type_expression::is_record()
{ {
return nullptr; return nullptr;
} }
std::shared_ptr<union_type_expression> type_expression::is_union() union_type_expression *type_expression::is_union()
{ {
return nullptr; return nullptr;
} }
std::shared_ptr<procedure_type_expression> type_expression::is_procedure() procedure_type_expression *type_expression::is_procedure()
{ {
return nullptr; return nullptr;
} }
@ -143,25 +143,30 @@ namespace elna::boot
visitor->visit(this); visitor->visit(this);
} }
std::shared_ptr<primitive_type_expression> primitive_type_expression::is_primitive() primitive_type_expression *primitive_type_expression::is_primitive()
{ {
return std::static_pointer_cast<primitive_type_expression>(shared_from_this()); return this;
} }
array_type_expression::array_type_expression(const struct position position, array_type_expression::array_type_expression(const struct position position,
std::shared_ptr<type_expression> base, const std::uint32_t size) type_expression *base, const std::uint32_t size)
: type_expression(position), m_base(base), size(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) void array_type_expression::accept(parser_visitor *visitor)
{ {
visitor->visit(this); visitor->visit(this);
} }
std::shared_ptr<array_type_expression> array_type_expression::is_array() array_type_expression *array_type_expression::is_array()
{ {
return std::static_pointer_cast<array_type_expression>(shared_from_this()); return this;
} }
type_expression& array_type_expression::base() type_expression& array_type_expression::base()
@ -170,19 +175,24 @@ namespace elna::boot
} }
pointer_type_expression::pointer_type_expression(const struct position position, pointer_type_expression::pointer_type_expression(const struct position position,
std::shared_ptr<type_expression> base) type_expression *base)
: type_expression(position), m_base(base) : type_expression(position), m_base(base)
{ {
} }
pointer_type_expression::~pointer_type_expression()
{
delete m_base;
}
void pointer_type_expression::accept(parser_visitor *visitor) void pointer_type_expression::accept(parser_visitor *visitor)
{ {
visitor->visit(this); visitor->visit(this);
} }
std::shared_ptr<pointer_type_expression> pointer_type_expression::is_pointer() pointer_type_expression *pointer_type_expression::is_pointer()
{ {
return std::static_pointer_cast<pointer_type_expression>(shared_from_this()); return this;
} }
type_expression& pointer_type_expression::base() 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) void record_type_expression::accept(parser_visitor *visitor)
{ {
visitor->visit(this); visitor->visit(this);
} }
std::shared_ptr<record_type_expression> record_type_expression::is_record() record_type_expression *record_type_expression::is_record()
{ {
return std::static_pointer_cast<record_type_expression>(shared_from_this()); return this;
} }
union_type_expression::union_type_expression(const struct position position, 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) void union_type_expression::accept(parser_visitor *visitor)
{ {
visitor->visit(this); visitor->visit(this);
} }
std::shared_ptr<union_type_expression> union_type_expression::is_union() union_type_expression *union_type_expression::is_union()
{ {
return std::static_pointer_cast<union_type_expression>(shared_from_this()); return this;
} }
variable_declaration::variable_declaration(const struct position position, const std::string& identifier, variable_declaration::variable_declaration(const struct position position, const std::string& identifier,
@ -264,19 +290,30 @@ namespace elna::boot
delete m_body; delete m_body;
} }
procedure_type_expression::procedure_type_expression(const struct position position, procedure_type_expression::procedure_type_expression(const struct position position, return_t return_type)
return_declaration<std::shared_ptr<type_expression>> return_type)
: type_expression(position), return_type(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) void procedure_type_expression::accept(parser_visitor *visitor)
{ {
visitor->visit(this); visitor->visit(this);
} }
procedure_definition::procedure_definition(const struct position position, const std::string& identifier, procedure_definition::procedure_definition(const struct position position, const std::string& identifier,
const bool exported, std::shared_ptr<procedure_type_expression> heading, block *body) const bool exported, procedure_type_expression *heading, block *body)
: definition(position, identifier, exported), m_heading(heading), body(body) : definition(position, identifier, exported), m_heading(heading), body(body)
{ {
} }
@ -286,9 +323,9 @@ namespace elna::boot
visitor->visit(this); visitor->visit(this);
} }
std::shared_ptr<procedure_type_expression> procedure_type_expression::is_procedure() procedure_type_expression *procedure_type_expression::is_procedure()
{ {
return std::static_pointer_cast<procedure_type_expression>(shared_from_this()); return this;
} }
procedure_type_expression& procedure_definition::heading() procedure_type_expression& procedure_definition::heading()
@ -298,15 +335,21 @@ namespace elna::boot
procedure_definition::~procedure_definition() procedure_definition::~procedure_definition()
{ {
delete m_heading;
delete body; delete body;
} }
type_definition::type_definition(const struct position position, const std::string& identifier, type_definition::type_definition(const struct position position, const std::string& identifier,
const bool exported, std::shared_ptr<type_expression> body) const bool exported, type_expression *body)
: definition(position, identifier, exported), m_body(body) : definition(position, identifier, exported), m_body(body)
{ {
} }
type_definition::~type_definition()
{
delete m_body;
}
void type_definition::accept(parser_visitor *visitor) void type_definition::accept(parser_visitor *visitor)
{ {
visitor->visit(this); visitor->visit(this);
@ -637,8 +680,7 @@ namespace elna::boot
delete m_callable; delete m_callable;
} }
cast_expression::cast_expression(const struct position position, cast_expression::cast_expression(const struct position position, type_expression *target, expression *value)
std::shared_ptr<type_expression> target, expression *value)
: node(position), m_target(target), m_value(value) : node(position), m_target(target), m_value(value)
{ {
} }
@ -665,6 +707,7 @@ namespace elna::boot
cast_expression::~cast_expression() cast_expression::~cast_expression()
{ {
delete m_target;
delete m_value; 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) void traits_expression::accept(parser_visitor *visitor)
{ {
visitor->visit(this); visitor->visit(this);

View File

@ -127,8 +127,8 @@ along with GCC; see the file COPYING3. If not see
%type <elna::boot::constant_definition *> constant_definition; %type <elna::boot::constant_definition *> constant_definition;
%type <std::vector<elna::boot::constant_definition *>> constant_part constant_definitions; %type <std::vector<elna::boot::constant_definition *>> constant_part constant_definitions;
%type <std::vector<elna::boot::variable_declaration *>> variable_declarations variable_part variable_declaration; %type <std::vector<elna::boot::variable_declaration *>> variable_declarations variable_part variable_declaration;
%type <std::shared_ptr<elna::boot::type_expression>> type_expression; %type <elna::boot::type_expression *> type_expression;
%type <std::vector<std::shared_ptr<elna::boot::type_expression>>> type_expressions; %type <std::vector<elna::boot::type_expression *>> type_expressions;
%type <elna::boot::traits_expression *> traits_expression; %type <elna::boot::traits_expression *> traits_expression;
%type <elna::boot::expression *> expression operand qualident; %type <elna::boot::expression *> expression operand qualident;
%type <elna::boot::unary_expression *> unary_expression; %type <elna::boot::unary_expression *> unary_expression;
@ -143,14 +143,14 @@ along with GCC; see the file COPYING3. If not see
%type <elna::boot::statement *> statement; %type <elna::boot::statement *> statement;
%type <std::vector<elna::boot::statement *>> statements; %type <std::vector<elna::boot::statement *>> statements;
%type <elna::boot::procedure_definition *> procedure_definition; %type <elna::boot::procedure_definition *> procedure_definition;
%type <std::pair<std::vector<std::string>, std::shared_ptr<elna::boot::procedure_type_expression>>> procedure_heading; %type <std::pair<std::vector<std::string>, elna::boot::procedure_type_expression *>> procedure_heading;
%type <elna::boot::procedure_type_expression::return_t> return_declaration; %type <elna::boot::procedure_type_expression::return_t> return_declaration;
%type <std::vector<elna::boot::procedure_definition *>> procedure_definitions procedure_part; %type <std::vector<elna::boot::procedure_definition *>> procedure_definitions procedure_part;
%type <elna::boot::type_definition *> type_definition; %type <elna::boot::type_definition *> type_definition;
%type <std::vector<elna::boot::type_definition *>> type_definitions type_part; %type <std::vector<elna::boot::type_definition *>> type_definitions type_part;
%type <elna::boot::block *> block; %type <elna::boot::block *> block;
%type <elna::boot::field_declaration> field_declaration formal_parameter; %type <elna::boot::field_declaration> field_declaration formal_parameter;
%type <std::vector<std::pair<std::string, std::shared_ptr<elna::boot::type_expression>>>> %type <std::vector<std::pair<std::string, elna::boot::type_expression *>>>
optional_fields required_fields formal_parameters; optional_fields required_fields formal_parameters;
%type <std::vector<elna::boot::conditional_statements *>> elsif_then_statements elsif_do_statements; %type <std::vector<elna::boot::conditional_statements *>> elsif_then_statements elsif_do_statements;
%type <elna::boot::cast_expression *> cast_expression; %type <elna::boot::cast_expression *> cast_expression;
@ -202,8 +202,7 @@ return_declaration:
procedure_heading: procedure_heading:
"(" formal_parameters ")" return_declaration "(" formal_parameters ")" return_declaration
{ {
$$.second = std::make_shared<boot::procedure_type_expression>(boot::make_position(@1), $$.second = new boot::procedure_type_expression(boot::make_position(@1), std::move($4));
std::move($4));
for (auto& [name, type] : $2) for (auto& [name, type] : $2)
{ {
$$.first.emplace_back(std::move(name)); $$.first.emplace_back(std::move(name));
@ -213,8 +212,7 @@ procedure_heading:
procedure_definition: procedure_definition:
"proc" identifier_definition procedure_heading ";" block "proc" identifier_definition procedure_heading ";" block
{ {
$$ = new boot::procedure_definition(boot::make_position(@1), $$ = new boot::procedure_definition(boot::make_position(@1), $2.first, $2.second, $3.second, $5);
$2.first, $2.second, $3.second, $5);
std::swap($3.first, $$->parameter_names); std::swap($3.first, $$->parameter_names);
} }
| "proc" identifier_definition procedure_heading ";" "extern" | "proc" identifier_definition procedure_heading ";" "extern"
@ -489,37 +487,38 @@ optional_fields:
type_expression: type_expression:
"[" INTEGER "]" type_expression "[" INTEGER "]" type_expression
{ {
$$ = std::make_shared<boot::array_type_expression>(boot::make_position(@1), $4, $2); $$ = new boot::array_type_expression(boot::make_position(@1), $4, $2);
} }
| "^" type_expression | "^" type_expression
{ {
$$ = std::make_shared<boot::pointer_type_expression>(boot::make_position(@1), $2); $$ = new boot::pointer_type_expression(boot::make_position(@1), $2);
} }
| "record" optional_fields "end" | "record" optional_fields "end"
{ {
$$ = std::make_shared<boot::record_type_expression>(boot::make_position(@1), std::move($2)); $$ = new boot::record_type_expression(boot::make_position(@1), std::move($2));
} }
| "union" required_fields "end" | "union" required_fields "end"
{ {
$$ = std::make_shared<boot::union_type_expression>(boot::make_position(@1), std::move($2)); $$ = new boot::union_type_expression(boot::make_position(@1), std::move($2));
} }
| "proc" "(" type_expressions ")" return_declaration | "proc" "(" type_expressions ")" return_declaration
{ {
auto result = std::make_shared<boot::procedure_type_expression>(boot::make_position(@1), auto result = new boot::procedure_type_expression(boot::make_position(@1), std::move($5));
std::move($5));
std::swap(result->parameters, $3); std::swap(result->parameters, $3);
$$ = result; $$ = result;
} }
| IDENTIFIER | IDENTIFIER
{ {
$$ = std::make_shared<boot::primitive_type_expression>(boot::make_position(@1), $1); $$ = new boot::primitive_type_expression(boot::make_position(@1), $1);
} }
variable_declaration: identifier_definitions ":" type_expression variable_declaration: identifier_definitions ":" type_expression
{ {
std::shared_ptr<boot::type_expression> shared_type{ $3 };
for (const std::pair<std::string, bool>& identifier : $1) for (const std::pair<std::string, bool>& identifier : $1)
{ {
boot::variable_declaration *declaration = new boot::variable_declaration( 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); $$.push_back(declaration);
} }
} }

View File

@ -65,7 +65,7 @@ namespace elna::boot
} }
procedure_type result_type = procedure_type(result_return); procedure_type result_type = procedure_type(result_return);
for (std::shared_ptr<struct type_expression> parameter : type_expression.parameters) for (struct type_expression *parameter : type_expression.parameters)
{ {
parameter->accept(this); parameter->accept(this);
result_type.parameters.push_back(this->current_type); result_type.parameters.push_back(this->current_type);

View File

@ -73,6 +73,8 @@ namespace elna::gcc
declare_builtin_type(symbol_table, "Float", elna_float_type_node); declare_builtin_type(symbol_table, "Float", elna_float_type_node);
declare_builtin_type(symbol_table, "String", elna_string_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; return symbol_table;
} }
} }

View File

@ -281,7 +281,7 @@ namespace elna::gcc
std::vector<std::string>::const_iterator parameter_name = definition->parameter_names.cbegin(); std::vector<std::string>::const_iterator parameter_name = definition->parameter_names.cbegin();
for (std::shared_ptr<boot::type_expression> parameter : definition->heading().parameters) for (boot::type_expression *parameter : definition->heading().parameters)
{ {
tree declaration_tree = build_decl(get_location(&parameter->position()), PARM_DECL, tree declaration_tree = build_decl(get_location(&parameter->position()), PARM_DECL,
get_identifier(parameter_name->c_str()), function_args_iter_cond(&parameter_type)); get_identifier(parameter_name->c_str()), function_args_iter_cond(&parameter_type));

View File

@ -185,15 +185,15 @@ namespace elna::boot
/** /**
* Some type expression. * Some type expression.
*/ */
class type_expression : public node, public std::enable_shared_from_this<type_expression> class type_expression : public node
{ {
public: public:
virtual std::shared_ptr<primitive_type_expression> is_primitive(); virtual primitive_type_expression *is_primitive();
virtual std::shared_ptr<array_type_expression> is_array(); virtual array_type_expression *is_array();
virtual std::shared_ptr<pointer_type_expression> is_pointer(); virtual pointer_type_expression *is_pointer();
virtual std::shared_ptr<record_type_expression> is_record(); virtual record_type_expression *is_record();
virtual std::shared_ptr<union_type_expression> is_union(); virtual union_type_expression *is_union();
virtual std::shared_ptr<procedure_type_expression> is_procedure(); virtual procedure_type_expression *is_procedure();
protected: protected:
type_expression(const struct position position); type_expression(const struct position position);
@ -209,37 +209,41 @@ namespace elna::boot
primitive_type_expression(const struct position position, const std::string& name); primitive_type_expression(const struct position position, const std::string& name);
void accept(parser_visitor *visitor) override; void accept(parser_visitor *visitor) override;
std::shared_ptr<primitive_type_expression> is_primitive() override; primitive_type_expression *is_primitive() override;
}; };
class array_type_expression : public type_expression class array_type_expression : public type_expression
{ {
std::shared_ptr<type_expression> m_base; type_expression *m_base;
public: public:
const std::uint32_t size; const std::uint32_t size;
array_type_expression(const struct position position, array_type_expression(const struct position position,
std::shared_ptr<type_expression> base, const std::uint32_t size); type_expression *base, const std::uint32_t size);
~array_type_expression();
void accept(parser_visitor *visitor) override; void accept(parser_visitor *visitor) override;
std::shared_ptr<array_type_expression> is_array() override; array_type_expression *is_array() override;
type_expression& base(); type_expression& base();
}; };
class pointer_type_expression : public type_expression class pointer_type_expression : public type_expression
{ {
std::shared_ptr<type_expression> m_base; type_expression *m_base;
public: public:
pointer_type_expression(const struct position position, std::shared_ptr<type_expression> base); pointer_type_expression(const struct position position, type_expression *base);
~pointer_type_expression();
void accept(parser_visitor *visitor) override; void accept(parser_visitor *visitor) override;
std::shared_ptr<pointer_type_expression> is_pointer() override; pointer_type_expression *is_pointer() override;
type_expression& base(); type_expression& base();
}; };
using field_declaration = std::pair<std::string, std::shared_ptr<type_expression>>; using field_declaration = std::pair<std::string, type_expression *>;
class record_type_expression : public type_expression class record_type_expression : public type_expression
{ {
@ -247,9 +251,10 @@ namespace elna::boot
const std::vector<field_declaration> fields; const std::vector<field_declaration> fields;
record_type_expression(const struct position position, 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; void accept(parser_visitor *visitor) override;
std::shared_ptr<record_type_expression> is_record() override; record_type_expression *is_record() override;
}; };
class union_type_expression : public type_expression class union_type_expression : public type_expression
@ -258,9 +263,10 @@ namespace elna::boot
std::vector<field_declaration> fields; std::vector<field_declaration> fields;
union_type_expression(const struct position position, 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; void accept(parser_visitor *visitor) override;
std::shared_ptr<union_type_expression> is_union() override; union_type_expression *is_union() override;
}; };
/** /**
@ -273,6 +279,7 @@ namespace elna::boot
public: public:
variable_declaration(const struct position position, const std::string& identifier, variable_declaration(const struct position position, const std::string& identifier,
std::shared_ptr<type_expression> variable_type, const bool exported = false); std::shared_ptr<type_expression> variable_type, const bool exported = false);
void accept(parser_visitor *visitor) override; void accept(parser_visitor *visitor) override;
type_expression& variable_type(); type_expression& variable_type();
@ -321,16 +328,16 @@ namespace elna::boot
class procedure_type_expression : public type_expression class procedure_type_expression : public type_expression
{ {
public: public:
using return_t = return_declaration<std::shared_ptr<type_expression>>; using return_t = return_declaration<type_expression *>;
const return_t return_type; const return_t return_type;
std::vector<std::shared_ptr<type_expression>> parameters; std::vector<type_expression *> parameters;
procedure_type_expression(const struct position position, procedure_type_expression(const struct position position, return_t return_type = return_t());
return_t return_type = return_t()); ~procedure_type_expression();
void accept(parser_visitor *visitor) override; void accept(parser_visitor *visitor) override;
std::shared_ptr<procedure_type_expression> is_procedure() override; procedure_type_expression *is_procedure() override;
}; };
/** /**
@ -338,14 +345,14 @@ namespace elna::boot
*/ */
class procedure_definition : public definition class procedure_definition : public definition
{ {
std::shared_ptr<procedure_type_expression> m_heading; procedure_type_expression *m_heading;
public: public:
block *const body; block *const body;
std::vector<std::string> parameter_names; std::vector<std::string> parameter_names;
procedure_definition(const struct position position, const std::string& identifier, procedure_definition(const struct position position, const std::string& identifier,
const bool exported, std::shared_ptr<procedure_type_expression> heading, block *body = nullptr); const bool exported, procedure_type_expression *heading, block *body = nullptr);
void accept(parser_visitor *visitor) override; void accept(parser_visitor *visitor) override;
procedure_type_expression& heading(); procedure_type_expression& heading();
@ -358,11 +365,13 @@ namespace elna::boot
*/ */
class type_definition : public definition class type_definition : public definition
{ {
std::shared_ptr<type_expression> m_body; type_expression *m_body;
public: public:
type_definition(const struct position position, const std::string& identifier, type_definition(const struct position position, const std::string& identifier,
const bool exported, std::shared_ptr<type_expression> expression); const bool exported, type_expression *expression);
~type_definition();
void accept(parser_visitor *visitor) override; void accept(parser_visitor *visitor) override;
type_expression& body(); type_expression& body();
@ -373,11 +382,11 @@ namespace elna::boot
*/ */
class cast_expression : public expression class cast_expression : public expression
{ {
std::shared_ptr<type_expression> m_target; type_expression *m_target;
expression *m_value; expression *m_value;
public: public:
cast_expression(const struct position position, std::shared_ptr<type_expression> target, expression *value); cast_expression(const struct position position, type_expression *target, expression *value);
void accept(parser_visitor *visitor) override; void accept(parser_visitor *visitor) override;
cast_expression *is_cast() override; cast_expression *is_cast() override;
@ -390,10 +399,12 @@ namespace elna::boot
class traits_expression : public expression class traits_expression : public expression
{ {
public: public:
std::vector<std::shared_ptr<type_expression>> parameters; std::vector<type_expression *> parameters;
const std::string name; const std::string name;
traits_expression(const struct position position, const std::string& name); traits_expression(const struct position position, const std::string& name);
~traits_expression();
void accept(parser_visitor *visitor) override; void accept(parser_visitor *visitor) override;
traits_expression *is_traits() override; traits_expression *is_traits() override;
}; };