Support while … else

This commit is contained in:
Eugen Wissner 2025-04-13 18:40:49 +02:00
parent 8ec407515a
commit 25bb24c694
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
4 changed files with 26 additions and 18 deletions

View File

@ -811,8 +811,9 @@ namespace elna::boot
} }
if_statement::if_statement(const struct position position, conditional_statements *body, if_statement::if_statement(const struct position position, conditional_statements *body,
std::vector<conditional_statements *>&& branches,
std::vector<statement *> *alternative) std::vector<statement *> *alternative)
: node(position), m_body(body), alternative(alternative) : node(position), m_body(body), branches(std::move(branches)), alternative(alternative)
{ {
} }
@ -848,14 +849,15 @@ namespace elna::boot
} }
while_statement::while_statement(const struct position position, conditional_statements *body, while_statement::while_statement(const struct position position, conditional_statements *body,
std::vector<conditional_statements *>&& branches) std::vector<conditional_statements *>&& branches, std::vector<statement *> *alternative)
: node(position), m_body(body), branches(std::move(branches)) : node(position), m_body(body), branches(std::move(branches)), alternative(alternative)
{ {
} }
while_statement::while_statement(const struct position position, conditional_statements *body, while_statement::while_statement(const struct position position, conditional_statements *body,
std::vector<conditional_statements *>&& branches, const std::string& label) std::vector<conditional_statements *>&& branches, const std::string& label,
: node(position), m_body(body), branches(std::move(branches)), label(label) std::vector<statement *> *alternative)
: node(position), m_body(body), branches(std::move(branches)), label(label), alternative(alternative)
{ {
} }

View File

@ -243,9 +243,7 @@ call_expression: designator_expression actual_parameter_list
std::swap($$->arguments, $2); std::swap($$->arguments, $2);
} }
cast_expression: "cast" "(" expression ":" type_expression ")" 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_do_statements:
"elsif" expression "do" statements elsif_do_statements "elsif" expression "do" statements elsif_do_statements
{ {
@ -258,15 +256,15 @@ else_statements:
"else" statements { $$ = new std::vector<boot::statement *>(std::move($2)); } "else" statements { $$ = new std::vector<boot::statement *>(std::move($2)); }
| { $$ = nullptr; } | { $$ = nullptr; }
while_statement: 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)); 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)); 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_then_statements:
"elsif" expression "then" statements elsif_then_statements "elsif" expression "then" statements elsif_then_statements
@ -422,9 +420,7 @@ statement:
| "if" expression "then" statements elsif_then_statements else_statements "end" | "if" expression "then" statements elsif_then_statements else_statements "end"
{ {
boot::conditional_statements *then = new boot::conditional_statements($2, std::move($4)); boot::conditional_statements *then = new boot::conditional_statements($2, std::move($4));
auto result = new boot::if_statement(boot::make_position(@1), then, $6); $$ = new boot::if_statement(boot::make_position(@1), then, std::move($5), $6);
std::swap($5, result->branches);
$$ = result;
} }
| return_statement { $$ = $1; } | return_statement { $$ = $1; }
| "break" IDENTIFIER | "break" IDENTIFIER

View File

@ -1277,6 +1277,13 @@ namespace elna::gcc
{ {
make_if_branch(*branch, goto_check); make_if_branch(*branch, goto_check);
} }
if (statement->alternative != nullptr)
{
enter_scope();
visit_statements(*statement->alternative);
tree mapping = leave_scope();
append_statement(mapping);
}
append_statement(branch_end_expression); append_statement(branch_end_expression);
this->current_expression = NULL_TREE; this->current_expression = NULL_TREE;
} }

View File

@ -595,10 +595,11 @@ namespace elna::boot
conditional_statements *m_body; conditional_statements *m_body;
public: public:
std::vector<conditional_statements *> branches; const std::vector<conditional_statements *> branches;
const std::vector<statement *> *alternative; const std::vector<statement *> *alternative;
if_statement(const struct position position, conditional_statements *body, if_statement(const struct position position, conditional_statements *body,
std::vector<conditional_statements *>&& branches,
std::vector<statement *> *alternative = nullptr); std::vector<statement *> *alternative = nullptr);
void accept(parser_visitor *visitor) override; void accept(parser_visitor *visitor) override;
@ -628,11 +629,13 @@ namespace elna::boot
public: public:
const std::vector<conditional_statements *> branches; const std::vector<conditional_statements *> branches;
const std::optional<std::string> label; const std::optional<std::string> label;
const std::vector<statement *> *alternative;
while_statement(const struct position position, conditional_statements *body, while_statement(const struct position position, conditional_statements *body,
std::vector<conditional_statements *>&& branches); std::vector<conditional_statements *>&& branches, std::vector<statement *> *alternative = nullptr);
while_statement(const struct position position, conditional_statements *body, while_statement(const struct position position, conditional_statements *body,
std::vector<conditional_statements *>&& branches, const std::string& label); std::vector<conditional_statements *>&& branches, const std::string& label,
std::vector<statement *> *alternative = nullptr);
void accept(parser_visitor *visitor) override; void accept(parser_visitor *visitor) override;
conditional_statements& body(); conditional_statements& body();