diff --git a/boot/ast.cc b/boot/ast.cc index 92e5bf5..dca3fd9 100644 --- a/boot/ast.cc +++ b/boot/ast.cc @@ -811,8 +811,9 @@ namespace elna::boot } if_statement::if_statement(const struct position position, conditional_statements *body, + std::vector&& branches, std::vector *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, - std::vector&& branches) - : node(position), m_body(body), branches(std::move(branches)) + std::vector&& branches, std::vector *alternative) + : node(position), m_body(body), branches(std::move(branches)), alternative(alternative) { } while_statement::while_statement(const struct position position, conditional_statements *body, - std::vector&& branches, const std::string& label) - : node(position), m_body(body), branches(std::move(branches)), label(label) + std::vector&& branches, const std::string& label, + std::vector *alternative) + : node(position), m_body(body), branches(std::move(branches)), label(label), alternative(alternative) { } diff --git a/boot/parser.yy b/boot/parser.yy index e4bc9c2..cf3e353 100644 --- a/boot/parser.yy +++ b/boot/parser.yy @@ -243,9 +243,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 +256,15 @@ else_statements: "else" statements { $$ = new std::vector(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 +420,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 diff --git a/gcc/elna-generic.cc b/gcc/elna-generic.cc index ba4a96e..2337046 100644 --- a/gcc/elna-generic.cc +++ b/gcc/elna-generic.cc @@ -1277,6 +1277,13 @@ namespace elna::gcc { 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); this->current_expression = NULL_TREE; } diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h index c2ae0ee..90c8290 100644 --- a/include/elna/boot/ast.h +++ b/include/elna/boot/ast.h @@ -595,10 +595,11 @@ namespace elna::boot conditional_statements *m_body; public: - std::vector branches; + const std::vector branches; const std::vector *alternative; if_statement(const struct position position, conditional_statements *body, + std::vector&& branches, std::vector *alternative = nullptr); void accept(parser_visitor *visitor) override; @@ -628,11 +629,13 @@ namespace elna::boot public: const std::vector branches; const std::optional label; + const std::vector *alternative; while_statement(const struct position position, conditional_statements *body, - std::vector&& branches); + std::vector&& branches, std::vector *alternative = nullptr); while_statement(const struct position position, conditional_statements *body, - std::vector&& branches, const std::string& label); + std::vector&& branches, const std::string& label, + std::vector *alternative = nullptr); void accept(parser_visitor *visitor) override; conditional_statements& body();