Support while … else
This commit is contained in:
@ -161,8 +161,8 @@ along with GCC; see the file COPYING3. If not see
|
||||
%type <std::vector<elna::boot::conditional_statements *>> elsif_then_statements elsif_do_statements;
|
||||
%type <std::vector<elna::boot::statement *> *> else_statements;
|
||||
%type <elna::boot::cast_expression *> cast_expression;
|
||||
%type <std::pair<std::string, bool>> identifier_definition;
|
||||
%type <std::vector<std::pair<std::string, bool>>> identifier_definitions;
|
||||
%type <elna::boot::identifier_definition> identifier_definition;
|
||||
%type <std::vector<elna::boot::identifier_definition>> identifier_definitions;
|
||||
%type <std::vector<std::string>> identifiers;
|
||||
%%
|
||||
program:
|
||||
@ -187,14 +187,8 @@ block: constant_part variable_part "begin" statements "end"
|
||||
std::swap($$->body, $4);
|
||||
}
|
||||
identifier_definition:
|
||||
IDENTIFIER "*"
|
||||
{
|
||||
$$ = std::make_pair($1, true);
|
||||
}
|
||||
| IDENTIFIER
|
||||
{
|
||||
$$ = std::make_pair($1, false);
|
||||
}
|
||||
IDENTIFIER "*" { $$ = boot::identifier_definition{ $1, true }; }
|
||||
| IDENTIFIER { $$ = boot::identifier_definition{ $1, false }; }
|
||||
identifier_definitions:
|
||||
identifier_definition "," identifier_definitions
|
||||
{
|
||||
@ -219,12 +213,12 @@ procedure_heading:
|
||||
procedure_definition:
|
||||
"proc" identifier_definition procedure_heading ";" block
|
||||
{
|
||||
$$ = new boot::procedure_definition(boot::make_position(@1), $2.first, $2.second, $3.second, $5);
|
||||
$$ = new boot::procedure_definition(boot::make_position(@1), std::move($2), $3.second, $5);
|
||||
std::swap($3.first, $$->parameter_names);
|
||||
}
|
||||
| "proc" identifier_definition procedure_heading ";" "extern"
|
||||
{
|
||||
$$ = new boot::procedure_definition(boot::make_position(@1), $2.first, $2.second, $3.second);
|
||||
$$ = new boot::procedure_definition(boot::make_position(@1), std::move($2), $3.second);
|
||||
std::swap($3.first, $$->parameter_names);
|
||||
}
|
||||
procedure_definitions:
|
||||
@ -243,9 +237,7 @@ call_expression: designator_expression actual_parameter_list
|
||||
std::swap($$->arguments, $2);
|
||||
}
|
||||
cast_expression: "cast" "(" expression ":" type_expression ")"
|
||||
{
|
||||
$$ = new boot::cast_expression(boot::make_position(@1), $5, $3);
|
||||
}
|
||||
{ $$ = new boot::cast_expression(boot::make_position(@1), $5, $3); }
|
||||
elsif_do_statements:
|
||||
"elsif" expression "do" statements elsif_do_statements
|
||||
{
|
||||
@ -258,15 +250,15 @@ else_statements:
|
||||
"else" statements { $$ = new std::vector<boot::statement *>(std::move($2)); }
|
||||
| { $$ = nullptr; }
|
||||
while_statement:
|
||||
"while" expression "do" statements elsif_do_statements "end"
|
||||
"while" expression "do" statements elsif_do_statements else_statements "end"
|
||||
{
|
||||
boot::conditional_statements *body = new boot::conditional_statements($2, std::move($4));
|
||||
$$ = new boot::while_statement(boot::make_position(@1), body, std::move($5));
|
||||
$$ = new boot::while_statement(boot::make_position(@1), body, std::move($5), $6);
|
||||
}
|
||||
| "while" expression "," IDENTIFIER "do" statements elsif_do_statements "end"
|
||||
| "while" expression "," IDENTIFIER "do" statements elsif_do_statements else_statements "end"
|
||||
{
|
||||
boot::conditional_statements *body = new boot::conditional_statements($2, std::move($6));
|
||||
$$ = new boot::while_statement(boot::make_position(@1), body, std::move($7), $4);
|
||||
$$ = new boot::while_statement(boot::make_position(@1), body, std::move($7), $4, $8);
|
||||
}
|
||||
elsif_then_statements:
|
||||
"elsif" expression "then" statements elsif_then_statements
|
||||
@ -422,9 +414,7 @@ statement:
|
||||
| "if" expression "then" statements elsif_then_statements else_statements "end"
|
||||
{
|
||||
boot::conditional_statements *then = new boot::conditional_statements($2, std::move($4));
|
||||
auto result = new boot::if_statement(boot::make_position(@1), then, $6);
|
||||
std::swap($5, result->branches);
|
||||
$$ = result;
|
||||
$$ = new boot::if_statement(boot::make_position(@1), then, std::move($5), $6);
|
||||
}
|
||||
| return_statement { $$ = $1; }
|
||||
| "break" IDENTIFIER
|
||||
@ -512,32 +502,32 @@ variable_declaration: identifier_definitions ":" type_expression
|
||||
{
|
||||
std::shared_ptr<boot::type_expression> shared_type{ $3 };
|
||||
|
||||
for (const std::pair<std::string, bool>& identifier : $1)
|
||||
for (boot::identifier_definition& identifier : $1)
|
||||
{
|
||||
boot::variable_declaration *declaration = new boot::variable_declaration(
|
||||
boot::make_position(@2), identifier.first, shared_type, identifier.second);
|
||||
boot::make_position(@2), std::move(identifier), shared_type);
|
||||
$$.push_back(declaration);
|
||||
}
|
||||
}
|
||||
variable_declarations:
|
||||
variable_declaration ";" variable_declarations
|
||||
/* no variable declarations */ {}
|
||||
| variable_declaration variable_declarations
|
||||
{
|
||||
std::swap($$, $1);
|
||||
$$.reserve($$.size() + $3.size());
|
||||
$$.insert(std::end($$), std::begin($3), std::end($3));
|
||||
$$.reserve($$.size() + $2.size());
|
||||
$$.insert(std::end($$), std::begin($2), std::end($2));
|
||||
}
|
||||
| /* no variable declarations */ {}
|
||||
variable_part:
|
||||
/* no variable declarations */ {}
|
||||
| "var" variable_declarations { std::swap($$, $2); }
|
||||
constant_definition: identifier_definition ":=" expression
|
||||
{
|
||||
$$ = new boot::constant_definition(boot::make_position(@1), $1.first, $1.second, $3);
|
||||
$$ = new boot::constant_definition(boot::make_position(@1), std::move($1), $3);
|
||||
}
|
||||
constant_definitions:
|
||||
constant_definition ";" constant_definitions
|
||||
constant_definition constant_definitions
|
||||
{
|
||||
std::swap($$, $3);
|
||||
std::swap($$, $2);
|
||||
$$.insert($$.cbegin(), $1);
|
||||
}
|
||||
| /* no constant definitions */ {}
|
||||
@ -546,12 +536,12 @@ constant_part:
|
||||
| "const" constant_definitions { std::swap($$, $2); }
|
||||
type_definition: identifier_definition "=" type_expression
|
||||
{
|
||||
$$ = new boot::type_definition(boot::make_position(@1), $1.first, $1.second, $3);
|
||||
$$ = new boot::type_definition(boot::make_position(@1), std::move($1), $3);
|
||||
}
|
||||
type_definitions:
|
||||
type_definition ";" type_definitions
|
||||
type_definition type_definitions
|
||||
{
|
||||
std::swap($$, $3);
|
||||
std::swap($$, $2);
|
||||
$$.insert($$.cbegin(), $1);
|
||||
}
|
||||
| /* no type definitions */ {}
|
||||
|
Reference in New Issue
Block a user