Add an else to the case statement
This commit is contained in:
13
boot/ast.cc
13
boot/ast.cc
@ -794,8 +794,8 @@ namespace elna::boot
|
||||
}
|
||||
|
||||
case_statement::case_statement(const struct position position,
|
||||
expression *condition, std::vector<switch_case>&& cases)
|
||||
: node(position), m_condition(condition), cases(std::move(cases))
|
||||
expression *condition, std::vector<switch_case>&& cases, std::vector<statement *> *alternative)
|
||||
: node(position), m_condition(condition), cases(std::move(cases)), alternative(alternative)
|
||||
{
|
||||
}
|
||||
|
||||
@ -862,7 +862,7 @@ namespace elna::boot
|
||||
|
||||
if_statement::if_statement(const struct position position, conditional_statements *body,
|
||||
std::vector<statement *> *alternative)
|
||||
: node(position), m_body(body), m_alternative(alternative)
|
||||
: node(position), m_body(body), alternative(alternative)
|
||||
{
|
||||
}
|
||||
|
||||
@ -881,11 +881,6 @@ namespace elna::boot
|
||||
return *m_body;
|
||||
}
|
||||
|
||||
std::vector<statement *> *if_statement::alternative()
|
||||
{
|
||||
return m_alternative;
|
||||
}
|
||||
|
||||
if_statement::~if_statement()
|
||||
{
|
||||
delete m_body;
|
||||
@ -893,7 +888,7 @@ namespace elna::boot
|
||||
{
|
||||
delete branch;
|
||||
}
|
||||
delete m_alternative;
|
||||
delete this->alternative;
|
||||
}
|
||||
|
||||
while_statement::while_statement(const struct position position, conditional_statements *body)
|
||||
|
@ -143,7 +143,6 @@ along with GCC; see the file COPYING3. If not see
|
||||
%type <elna::boot::designator_expression *> designator_expression;
|
||||
%type <elna::boot::procedure_call*> call_expression;
|
||||
%type <elna::boot::while_statement *> while_statement;
|
||||
%type <elna::boot::if_statement *> if_statement;
|
||||
%type <elna::boot::return_statement *> return_statement;
|
||||
%type <elna::boot::statement *> statement;
|
||||
%type <std::vector<elna::boot::statement *>> statements;
|
||||
@ -158,6 +157,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
%type <std::vector<std::pair<std::string, elna::boot::type_expression *>>>
|
||||
optional_fields required_fields formal_parameters;
|
||||
%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;
|
||||
@ -253,6 +253,9 @@ elsif_do_statements:
|
||||
$$.emplace($$.begin(), branch);
|
||||
}
|
||||
| {}
|
||||
else_statements:
|
||||
"else" statements { $$ = new std::vector<boot::statement *>(std::move($2)); }
|
||||
| { $$ = nullptr; }
|
||||
while_statement: "while" expression "do" statements elsif_do_statements "end"
|
||||
{
|
||||
auto body = new boot::conditional_statements($2);
|
||||
@ -269,22 +272,6 @@ elsif_then_statements:
|
||||
$$.emplace($$.begin(), branch);
|
||||
}
|
||||
| {}
|
||||
if_statement:
|
||||
"if" expression "then" statements elsif_then_statements "end"
|
||||
{
|
||||
auto then = new boot::conditional_statements($2);
|
||||
std::swap($4, then->statements);
|
||||
$$ = new boot::if_statement(boot::make_position(@1), then);
|
||||
std::swap($5, $$->branches);
|
||||
}
|
||||
| "if" expression "then" statements elsif_then_statements "else" statements "end"
|
||||
{
|
||||
auto then = new boot::conditional_statements($2);
|
||||
std::swap($4, then->statements);
|
||||
auto _else = new std::vector<boot::statement *>(std::move($7));
|
||||
$$ = new boot::if_statement(boot::make_position(@1), then, _else);
|
||||
std::swap($5, $$->branches);
|
||||
}
|
||||
return_statement:
|
||||
"return" expression
|
||||
{
|
||||
@ -428,12 +415,19 @@ statement:
|
||||
designator_expression ":=" expression
|
||||
{ $$ = new boot::assign_statement(boot::make_position(@1), $1, $3); }
|
||||
| while_statement { $$ = $1; }
|
||||
| if_statement { $$ = $1; }
|
||||
| "if" expression "then" statements elsif_then_statements else_statements "end"
|
||||
{
|
||||
auto then = new boot::conditional_statements($2);
|
||||
std::swap($4, then->statements);
|
||||
auto result = new boot::if_statement(boot::make_position(@1), then, $6);
|
||||
std::swap($5, result->branches);
|
||||
$$ = result;
|
||||
}
|
||||
| return_statement { $$ = $1; }
|
||||
| call_expression { $$ = $1; }
|
||||
| "defer" statements "end" { $$ = new boot::defer_statement(boot::make_position(@1), std::move($2)); }
|
||||
| "case" expression "of" switch_cases "end"
|
||||
{ $$ = new boot::case_statement(boot::make_position(@1), $2, std::move($4)); }
|
||||
| "case" expression "of" switch_cases else_statements "end"
|
||||
{ $$ = new boot::case_statement(boot::make_position(@1), $2, std::move($4), $5); }
|
||||
switch_case: case_labels ":" statements { $$ = { .labels = std::move($1), .statements = std::move($3) }; }
|
||||
switch_cases:
|
||||
switch_case "|" switch_cases
|
||||
|
@ -230,9 +230,9 @@ namespace elna::boot
|
||||
statement->accept(this);
|
||||
}
|
||||
}
|
||||
if (statement->alternative() != nullptr)
|
||||
if (statement->alternative != nullptr)
|
||||
{
|
||||
for (struct statement *const statement : *statement->alternative())
|
||||
for (struct statement *const statement : *statement->alternative)
|
||||
{
|
||||
statement->accept(this);
|
||||
}
|
||||
|
Reference in New Issue
Block a user