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,
|
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 }
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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),
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
15
source.elna
15
source.elna
@ -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
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user