Implement defer
This commit is contained in:
@ -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
|
||||
|
Reference in New Issue
Block a user