Implement noreturn procedure declarations

This commit is contained in:
Eugen Wissner 2025-02-18 16:09:27 +01:00
parent 39750f4656
commit 4d4976b4cd
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
6 changed files with 35 additions and 12 deletions

View File

@ -419,7 +419,13 @@ namespace boot
procedure_definition::procedure_definition(const struct position position, const std::string& identifier,
const bool exported, std::shared_ptr<top_type> return_type)
: definition(position, identifier, exported), m_return_type(return_type)
: definition(position, identifier, exported), m_return_type(return_type), no_return{ false }
{
}
procedure_definition::procedure_definition(const struct position position, const std::string& identifier,
const bool exported, no_return_t)
: definition(position, identifier, exported), m_return_type(nullptr), no_return{ true }
{
}

View File

@ -280,6 +280,9 @@ defer {
@ {
return yy::parser::make_AT(this->location);
}
! {
return yy::parser::make_EXCLAMATION(this->location);
}
. {
std::stringstream ss;

View File

@ -85,13 +85,12 @@ along with GCC; see the file COPYING3. If not see
%token CONST VAR PROCEDURE TYPE RECORD UNION
%token BEGIN_BLOCK END_BLOCK EXTERN DEFER
%token LEFT_PAREN RIGHT_PAREN LEFT_SQUARE RIGHT_SQUARE SEMICOLON DOT COMMA
%token AND OR NOT CAST SHIFT_LEFT SHIFT_RIGHT
%token GREATER_EQUAL LESS_EQUAL LESS_THAN GREATER_THAN NOT_EQUAL EQUALS
%token PLUS MINUS MULTIPLICATION DIVISION REMAINDER
%token NOT CAST EXCLAMATION
%token ASSIGNMENT COLON HAT AT NIL ARROW
%left OR AND XOR
%left EQUALS NOT_EQUAL LESS_THAN GREATER_THAN LESS_EQUAL GREATER_EQUAL
%left SHIFT_LEFT SHIFT_RIGHT
%left PLUS MINUS
%left MULTIPLICATION DIVISION REMAINDER
@ -169,6 +168,12 @@ procedure_heading:
$2.first, $2.second);
std::swap($3, $$->parameters);
}
| PROCEDURE identifier_definition formal_parameter_list ARROW EXCLAMATION SEMICOLON
{
$$ = new elna::boot::procedure_definition(elna::boot::make_position(@1),
$2.first, $2.second, elna::boot::procedure_definition::no_return_t{});
std::swap($3, $$->parameters);
}
| PROCEDURE identifier_definition formal_parameter_list ARROW type_expression SEMICOLON
{
$$ = new elna::boot::procedure_definition(elna::boot::make_position(@1),

View File

@ -256,6 +256,10 @@ namespace gcc
tree fndecl = build_fn_decl(definition->identifier.c_str(), declaration_type);
this->symbol_map->enter(definition->identifier, fndecl);
if (definition->no_return)
{
TREE_THIS_VOLATILE(fndecl) = 1;
}
if (definition->body() != nullptr)
{
tree resdecl = build_decl(UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, return_type);

View File

@ -366,10 +366,16 @@ namespace boot
block *m_body{ nullptr };
public:
struct no_return_t
{
};
const bool no_return{ false };
std::vector<variable_declaration *> parameters;
procedure_definition(const struct position position, const std::string& identifier,
const bool exported, std::shared_ptr<top_type> return_type = nullptr);
procedure_definition(const struct position position, const std::string& identifier,
const bool exported, no_return_t);
virtual void accept(parser_visitor *visitor) override;
std::shared_ptr<top_type> return_type();

View File

@ -60,6 +60,7 @@ const
TOKEN_CHARACTER* = 55
TOKEN_STRING* = 56
TOKEN_DEFER* = 57
TOKEN_EXCLAMATION* = 58
type
Position* = record
@ -134,7 +135,7 @@ proc strlen(ptr: ^Char) -> Word; extern
proc strtol(nptr: ^Char, endptr: ^^Char, base: Int) -> Int; extern
proc perror(s: ^Char); extern
proc exit(code: Int); extern
proc exit(code: Int) -> !; extern
(*
Standard procedures.
@ -567,6 +568,8 @@ begin
write_s("\"...\"")
elsif current_token^.kind = TOKEN_DEFER then
write_s("DEFER")
elsif current_token^.kind = TOKEN_EXCLAMATION then
write_c('!')
else
write_s("UNKNOWN<")
write_i(current_token^.kind)
@ -800,6 +803,9 @@ begin
elsif first_char = '@' then
current_token^.kind := TOKEN_AT
source_code := advance_source(source_code, 1u)
elsif first_char = '!' then
current_token^.kind := TOKEN_EXCLAMATION
source_code := advance_source(source_code, 1u)
else
current_token^.kind := 0
source_code := advance_source(source_code, 1u)
@ -818,11 +824,6 @@ begin
return tokens
end
proc parse_literal(tokens: ^^Token, tokens_size: ^Word) -> ^Literal;
begin
return cast(calloc(1u, Literal.size): ^Literal)
end
proc parse_constant_definition(tokens: ^^Token,
tokens_size: ^Word) -> ^ConstantDefinition;
var
@ -839,8 +840,6 @@ begin
write_z(result^.name)
write_c('\n')
result^.body := parse_literal(tokens, tokens_size)
tokens^ := tokens^ + 2u
tokens_size := tokens_size - 2u