Add an else to the case statement

This commit is contained in:
2025-04-11 15:28:43 +02:00
parent f68667d5e5
commit 6fd1bda112
6 changed files with 173 additions and 169 deletions

View File

@ -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)

View File

@ -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

View File

@ -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);
}