aboutsummaryrefslogtreecommitdiff
path: root/boot/parser.yy
diff options
context:
space:
mode:
Diffstat (limited to 'boot/parser.yy')
-rw-r--r--boot/parser.yy67
1 files changed, 38 insertions, 29 deletions
diff --git a/boot/parser.yy b/boot/parser.yy
index eaf1a7c..01dfa80 100644
--- a/boot/parser.yy
+++ b/boot/parser.yy
@@ -135,7 +135,7 @@ along with GCC; see the file COPYING3. If not see
%type <elna::boot::switch_case> switch_case;
%type <std::vector<elna::boot::switch_case>> switch_cases;
%type <elna::boot::variable_declaration *> variable_declaration;
-%type <std::vector<elna::boot::variable_declaration *>> variable_declarations;
+%type <std::vector<elna::boot::variable_declaration *>> variable_declarations variable_part;
%type <elna::boot::type_expression *> type_expression;
%type <std::vector<elna::boot::type_expression *>> type_expressions;
%type <elna::boot::expression *> expression operand simple_expression procedure_return unary_expression;
@@ -145,6 +145,7 @@ along with GCC; see the file COPYING3. If not see
%type <std::unique_ptr<elna::boot::procedure_call>> call_expression;
%type <elna::boot::statement *> statement;
%type <std::vector<elna::boot::statement *>> statements statement_part;
+%type <elna::boot::block> block;
%type <elna::boot::procedure_declaration *> procedure_declaration;
%type <std::unique_ptr<elna::boot::procedure_type_expression>> procedure_heading;
%type <elna::boot::procedure_type_expression::return_t> return_declaration;
@@ -157,7 +158,7 @@ along with GCC; see the file COPYING3. If not see
%type <std::unique_ptr<elna::boot::field_initializer>> field_initializer;
%type <std::vector<elna::boot::field_initializer>> field_initializers;
%type <std::vector<elna::boot::conditional_statements *>> elsif_then_statements elsif_do_statements;
-%type <std::vector<elna::boot::statement *> *> else_statements;
+%type <elna::boot::block *> else_statements;
%type <std::unique_ptr<elna::boot::identifier>> identifier with_counter;
%type <std::unique_ptr<elna::boot::identifier_definition>> identifier_definition attributed_identifier;
%type <std::vector<elna::boot::identifier_definition>> identifier_definitions;
@@ -188,9 +189,9 @@ program:
}
module_declaration:
"type" type_declarations { $$ = $2; }
- | "var" variable_declarations
+ | variable_part
{
- std::vector<boot::variable_declaration *> variables = $2;
+ std::vector<boot::variable_declaration *> variables = $1;
$$.insert($$.end(), variables.begin(), variables.end());
}
@@ -215,12 +216,19 @@ module_declarations:
$$.insert($$.end(), appendix.begin(), appendix.end());
}
procedure_body:
- "var" variable_declarations statement_part procedure_return
- { $$ = std::make_unique<boot::procedure_body>($2, $3, $4); }
- | statement_part procedure_return
- {
- $$ = std::make_unique<boot::procedure_body>(std::vector<boot::variable_declaration *>(), $1, $2);
- }
+ block procedure_return
+ { $$ = std::make_unique<boot::procedure_body>(std::move($1), $2); }
+
+variable_part:
+ "var" variable_declarations { $$ = $2; }
+
+block:
+ variable_part statement_part
+ { $$ = boot::block(std::move($1), std::move($2)); }
+ | "begin" statements
+ { $$ = boot::block(std::vector<boot::variable_declaration *>(), std::move($2)); }
+ | statements
+ { $$ = boot::block(std::vector<boot::variable_declaration *>(), std::move($1)); }
statement_part:
%empty {}
@@ -284,20 +292,20 @@ with_counter:
"with" identifier { $$ = $2; }
| %empty { $$ = nullptr; }
elsif_do_statements:
- "elsif" expression "do" statements elsif_do_statements
+ "elsif" expression "do" block elsif_do_statements
{
- boot::conditional_statements *branch = new boot::conditional_statements($2, $4);
+ boot::conditional_statements *branch = new boot::conditional_statements($2, std::move($4));
$$ = $5;
$$.emplace($$.begin(), branch);
}
| %empty {}
else_statements:
- "else" statements { $$ = new std::vector<boot::statement *>($2); }
+ "else" block { $$ = new boot::block(std::move($2)); }
| %empty { $$ = nullptr; }
elsif_then_statements:
- "elsif" expression "then" statements elsif_then_statements
+ "elsif" expression "then" block elsif_then_statements
{
- boot::conditional_statements *branch = new boot::conditional_statements($2, $4);
+ boot::conditional_statements *branch = new boot::conditional_statements($2, std::move($4));
$$ = $5;
$$.emplace($$.begin(), branch);
}
@@ -563,36 +571,37 @@ name_reference:
statement:
designator_expression ":=" expression
{ $$ = new boot::assign_statement(boot::make_position(@$), $1, $3); }
- | "while" expression "do" statements elsif_do_statements "end"
+ | "while" expression "do" block elsif_do_statements "end"
{
- boot::conditional_statements *body = new boot::conditional_statements($2, $4);
+ boot::conditional_statements *body = new boot::conditional_statements($2, std::move($4));
$$ = new boot::while_statement(boot::make_position(@$), body, $5);
}
- | "repeat" statements "until" expression
+ | "repeat" block "until" expression
{
- $$ = new boot::repeat_statement(boot::make_position(@$), $2, $4);
+ $$ = new boot::repeat_statement(boot::make_position(@$), std::move($2), $4);
}
- | "for" identifier "of" expression with_counter "do" statements "end"
+ | "for" identifier "of" expression with_counter "do" block "end"
{
- $$ = new boot::for_statement(boot::make_position(@$), std::move(*$2), $4, $7, $5.release());
+ $$ = new boot::for_statement(boot::make_position(@$), std::move(*$2), $4,
+ std::move($7), $5.release());
}
- | "if" expression "then" statements elsif_then_statements else_statements "end"
+ | "if" expression "then" block elsif_then_statements else_statements "end"
{
- boot::conditional_statements *then = new boot::conditional_statements($2, $4);
+ boot::conditional_statements *then = new boot::conditional_statements($2, std::move($4));
$$ = new boot::if_statement(boot::make_position(@$), then, $5, $6);
}
| call_expression { $$ = $1.release(); }
- | "defer" statements "end"
- { $$ = new boot::defer_statement(boot::make_position(@$), $2); }
- | "block" identifier statements "end"
- { $$ = new boot::block_statement(boot::make_position(@$), std::move(*$2), $3); }
+ | "defer" block "end"
+ { $$ = new boot::defer_statement(boot::make_position(@$), std::move($2)); }
+ | "block" identifier block "end"
+ { $$ = new boot::block_statement(boot::make_position(@$), std::move(*$2), std::move($3)); }
| "break" identifier
{ $$ = new boot::break_statement(boot::make_position(@$), std::move(*$2)); }
| "case" expression "of" switch_cases else_statements "end"
{ $$ = new boot::case_statement(boot::make_position(@$), $2, $4, $5); }
| %empty { $$ = new boot::empty_statement(boot::make_position(@$)); }
-switch_case: case_labels ":" statements
- { $$ = { .labels = $1, .statements = $3 }; }
+switch_case: case_labels ":" block
+ { $$ = { .labels = $1, .body = std::move($3) }; }
switch_cases:
switch_case "|" switch_cases
{