Implement defer

This commit is contained in:
2025-02-07 22:12:59 +01:00
parent 077de53c74
commit 8a0f282714
13 changed files with 484 additions and 335 deletions

View File

@ -71,7 +71,7 @@
%token <bool> BOOLEAN
%token IF WHILE DO THEN ELSE ELSIF RETURN
%token CONST VAR PROCEDURE ARRAY OF TYPE RECORD POINTER TO UNION
%token BEGIN_BLOCK END_BLOCK EXTERN
%token BEGIN_BLOCK END_BLOCK EXTERN DEFER
%token LEFT_PAREN RIGHT_PAREN LEFT_SQUARE RIGHT_SQUARE SEMICOLON DOT COMMA
%token AND OR NOT CAST AS SIZEOF
%token GREATER_EQUAL LESS_EQUAL LESS_THAN GREATER_THAN NOT_EQUAL EQUALS
@ -100,7 +100,7 @@
%type <elna::boot::return_statement *> return_statement;
%type <elna::boot::statement *> statement;
%type <std::vector<elna::boot::statement *>> statements optional_statements;
%type <elna::boot::procedure_definition *> procedure_definition;
%type <elna::boot::procedure_definition *> procedure_definition procedure_heading;
%type <std::vector<elna::boot::procedure_definition *>> procedure_definitions procedure_part;
%type <elna::boot::type_definition *> type_definition;
%type <std::vector<elna::boot::type_definition *>> type_definitions type_part;
@ -109,6 +109,8 @@
%type <std::vector<std::pair<std::string, elna::boot::type_expression *>>> field_list;
%type <std::vector<elna::boot::conditional_statements *>> elsif_statement_list;
%type <elna::boot::cast_expression *> cast_expression;
%type <elna::boot::defer_statement *> defer_statement;
%type <std::pair<std::string, bool>> identifier_definition;
%%
program:
constant_part type_part variable_part procedure_part BEGIN_BLOCK optional_statements END_BLOCK DOT
@ -131,27 +133,31 @@ block: constant_part variable_part BEGIN_BLOCK optional_statements END_BLOCK
std::swap($$->variables, $2);
std::swap($$->body, $4);
}
identifier_definition:
IDENTIFIER MULTIPLICATION
{
$$ = std::make_pair($1, true);
}
| IDENTIFIER
{
$$ = std::make_pair($1, false);
}
procedure_heading:
PROCEDURE identifier_definition formal_parameter_list SEMICOLON
{
$$ = new elna::boot::procedure_definition(elna::boot::make_position(@1),
$2.first, $2.second);
std::swap($3, $$->parameters);
}
| PROCEDURE identifier_definition formal_parameter_list COLON type_expression SEMICOLON
{
$$ = new elna::boot::procedure_definition(elna::boot::make_position(@1),
$2.first, $2.second, $5);
std::swap($3, $$->parameters);
}
procedure_definition:
PROCEDURE IDENTIFIER formal_parameter_list SEMICOLON block SEMICOLON
{
$$ = new elna::boot::procedure_definition(elna::boot::make_position(@1),
$2, std::move($3), nullptr, $5);
}
| PROCEDURE IDENTIFIER formal_parameter_list SEMICOLON EXTERN SEMICOLON
{
$$ = new elna::boot::procedure_definition(elna::boot::make_position(@1),
$2, std::move($3), nullptr, nullptr);
}
| PROCEDURE IDENTIFIER formal_parameter_list COLON type_expression SEMICOLON block SEMICOLON
{
$$ = new elna::boot::procedure_definition(elna::boot::make_position(@1),
$2, std::move($3), $5, $7);
}
| PROCEDURE IDENTIFIER formal_parameter_list COLON type_expression SEMICOLON EXTERN SEMICOLON
{
$$ = new elna::boot::procedure_definition(elna::boot::make_position(@1),
$2, std::move($3), $5, nullptr);
}
procedure_heading block { $$ = $1->add_body($2); }
| procedure_heading EXTERN { $$ = $1; }
procedure_definitions:
procedure_definition procedure_definitions
{
@ -206,11 +212,15 @@ if_statement:
$$ = new elna::boot::if_statement(elna::boot::make_position(@1), then, _else);
std::swap($5, $$->branches);
}
return_statement:
RETURN expression
return_statement: RETURN expression
{
$$ = new elna::boot::return_statement(elna::boot::make_position(@1), $2);
}
defer_statement: DEFER optional_statements END_BLOCK
{
$$ = new elna::boot::defer_statement(elna::boot::make_position(@1));
std::swap($2, $$->statements);
}
literal:
INTEGER
{
@ -238,7 +248,7 @@ literal:
}
| STRING
{
$$ = new elna::boot::string_literal(elna::boot::make_position(@1), $1);
$$ = new elna::boot::number_literal<std::string>(elna::boot::make_position(@1), $1);
}
operand:
literal { $$ = $1; }
@ -346,7 +356,7 @@ designator_expression:
{
$$ = new elna::boot::array_access_expression(elna::boot::make_position(@1), $1, $3);
}
| designator_expression DOT IDENTIFIER
| operand DOT IDENTIFIER
{
$$ = new elna::boot::field_access_expression(elna::boot::make_position(@2), $1, $3);
}
@ -367,6 +377,7 @@ statement:
{
$$ = new elna::boot::call_statement(elna::boot::make_position(@1), $1);
}
| defer_statement { $$ = $1; }
statements:
statement SEMICOLON statements
{
@ -407,9 +418,9 @@ type_expression:
{
$$ = new elna::boot::basic_type_expression(elna::boot::make_position(@1), $1);
}
variable_declaration: IDENTIFIER COLON type_expression
variable_declaration: identifier_definition COLON type_expression
{
$$ = new elna::boot::variable_declaration(elna::boot::make_position(@1), $1, $3);
$$ = new elna::boot::variable_declaration(elna::boot::make_position(@2), $1.first, $1.second, $3);
}
variable_declarations:
variable_declaration COMMA variable_declarations
@ -421,9 +432,9 @@ variable_declarations:
variable_part:
/* no variable declarations */ {}
| VAR variable_declarations SEMICOLON { std::swap($$, $2); }
constant_definition: IDENTIFIER EQUALS literal SEMICOLON
constant_definition: identifier_definition EQUALS literal SEMICOLON
{
$$ = new elna::boot::constant_definition(elna::boot::make_position(@1), $1, $3);
$$ = new elna::boot::constant_definition(elna::boot::make_position(@1), $1.first, $1.second, $3);
}
constant_definitions:
constant_definition constant_definitions
@ -436,9 +447,9 @@ constant_part:
/* no constant definitions */ {}
| CONST {}
| CONST constant_definitions { std::swap($$, $2); }
type_definition: IDENTIFIER EQUALS type_expression
type_definition: identifier_definition EQUALS type_expression
{
$$ = new elna::boot::type_definition(elna::boot::make_position(@1), $1, $3);
$$ = new elna::boot::type_definition(elna::boot::make_position(@1), $1.first, $1.second, $3);
}
type_definitions:
type_definition COMMA type_definitions