Implement noreturn procedure declarations
This commit is contained in:
parent
39750f4656
commit
4d4976b4cd
@ -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 }
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -280,6 +280,9 @@ defer {
|
||||
@ {
|
||||
return yy::parser::make_AT(this->location);
|
||||
}
|
||||
! {
|
||||
return yy::parser::make_EXCLAMATION(this->location);
|
||||
}
|
||||
. {
|
||||
std::stringstream ss;
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
15
source.elna
15
source.elna
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user