Support while … else
This commit is contained in:
		
							
								
								
									
										12
									
								
								boot/ast.cc
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								boot/ast.cc
									
									
									
									
									
								
							@@ -811,8 +811,9 @@ namespace elna::boot
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if_statement::if_statement(const struct position position, conditional_statements *body,
 | 
			
		||||
            std::vector<conditional_statements *>&& branches,
 | 
			
		||||
            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,
 | 
			
		||||
            std::vector<conditional_statements *>&& branches)
 | 
			
		||||
        : node(position), m_body(body), branches(std::move(branches))
 | 
			
		||||
            std::vector<conditional_statements *>&& branches, std::vector<statement *> *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<conditional_statements *>&& branches, const std::string& label)
 | 
			
		||||
        : node(position), m_body(body), branches(std::move(branches)), label(label)
 | 
			
		||||
            std::vector<conditional_statements *>&& branches, const std::string& label,
 | 
			
		||||
            std::vector<statement *> *alternative)
 | 
			
		||||
        : node(position), m_body(body), branches(std::move(branches)), label(label), alternative(alternative)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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<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 +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
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -595,10 +595,11 @@ namespace elna::boot
 | 
			
		||||
        conditional_statements *m_body;
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        std::vector<conditional_statements *> branches;
 | 
			
		||||
        const std::vector<conditional_statements *> branches;
 | 
			
		||||
        const std::vector<statement *> *alternative;
 | 
			
		||||
 | 
			
		||||
        if_statement(const struct position position, conditional_statements *body,
 | 
			
		||||
                std::vector<conditional_statements *>&& branches,
 | 
			
		||||
                std::vector<statement *> *alternative = nullptr);
 | 
			
		||||
        void accept(parser_visitor *visitor) override;
 | 
			
		||||
 | 
			
		||||
@@ -628,11 +629,13 @@ namespace elna::boot
 | 
			
		||||
    public:
 | 
			
		||||
        const std::vector<conditional_statements *> branches;
 | 
			
		||||
        const std::optional<std::string> label;
 | 
			
		||||
        const std::vector<statement *> *alternative;
 | 
			
		||||
 | 
			
		||||
        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,
 | 
			
		||||
                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;
 | 
			
		||||
 | 
			
		||||
        conditional_statements& body();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user