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, procedure_definition::procedure_definition(const struct position position, const std::string& identifier,
const bool exported, std::shared_ptr<top_type> return_type) 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_AT(this->location);
} }
! {
return yy::parser::make_EXCLAMATION(this->location);
}
. { . {
std::stringstream ss; 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 CONST VAR PROCEDURE TYPE RECORD UNION
%token BEGIN_BLOCK END_BLOCK EXTERN DEFER %token BEGIN_BLOCK END_BLOCK EXTERN DEFER
%token LEFT_PAREN RIGHT_PAREN LEFT_SQUARE RIGHT_SQUARE SEMICOLON DOT COMMA %token LEFT_PAREN RIGHT_PAREN LEFT_SQUARE RIGHT_SQUARE SEMICOLON DOT COMMA
%token AND OR NOT CAST SHIFT_LEFT SHIFT_RIGHT %token NOT CAST EXCLAMATION
%token GREATER_EQUAL LESS_EQUAL LESS_THAN GREATER_THAN NOT_EQUAL EQUALS
%token PLUS MINUS MULTIPLICATION DIVISION REMAINDER
%token ASSIGNMENT COLON HAT AT NIL ARROW %token ASSIGNMENT COLON HAT AT NIL ARROW
%left OR AND XOR %left OR AND XOR
%left EQUALS NOT_EQUAL LESS_THAN GREATER_THAN LESS_EQUAL GREATER_EQUAL %left EQUALS NOT_EQUAL LESS_THAN GREATER_THAN LESS_EQUAL GREATER_EQUAL
%left SHIFT_LEFT SHIFT_RIGHT
%left PLUS MINUS %left PLUS MINUS
%left MULTIPLICATION DIVISION REMAINDER %left MULTIPLICATION DIVISION REMAINDER
@ -169,6 +168,12 @@ procedure_heading:
$2.first, $2.second); $2.first, $2.second);
std::swap($3, $$->parameters); 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 | PROCEDURE identifier_definition formal_parameter_list ARROW type_expression SEMICOLON
{ {
$$ = new elna::boot::procedure_definition(elna::boot::make_position(@1), $$ = 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); tree fndecl = build_fn_decl(definition->identifier.c_str(), declaration_type);
this->symbol_map->enter(definition->identifier, fndecl); this->symbol_map->enter(definition->identifier, fndecl);
if (definition->no_return)
{
TREE_THIS_VOLATILE(fndecl) = 1;
}
if (definition->body() != nullptr) if (definition->body() != nullptr)
{ {
tree resdecl = build_decl(UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, return_type); tree resdecl = build_decl(UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, return_type);

View File

@ -366,10 +366,16 @@ namespace boot
block *m_body{ nullptr }; block *m_body{ nullptr };
public: public:
struct no_return_t
{
};
const bool no_return{ false };
std::vector<variable_declaration *> parameters; std::vector<variable_declaration *> parameters;
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<top_type> return_type = nullptr); 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; virtual void accept(parser_visitor *visitor) override;
std::shared_ptr<top_type> return_type(); std::shared_ptr<top_type> return_type();

View File

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