// File: /workspace/github_c_makefile_star2_O0/mahrr[P]raven/src/compiler.c
// Function: while_
static void while_(Parser *parser) {
    // While Control Flow
    //
    // Condition       <----------.
    // OP_JMP_POP_FALSE   -----.  |
    //                         |  |
    // [continue]              |  |
    // OP_JMP_BACK        --------|
    //                         |  |
    // Loop Body               |  |
    // OP_JMP_BACK        ---------
    //                         |
    // ....            <--------

    Debug_Log(parser);

    // Register the surrounding loop state.
    int previous_inner_loop_start = parser->inner_loop_start;
    int previous_inner_loop_depth = parser->inner_loop_depth;

    int loop_start = parser_chunk(parser)->count;             // <-----.
                                                              //       |
    // Push the current loop state                            //       |
    parser->inner_loop_start = loop_start;                    //       |
    parser->inner_loop_depth = parser->context->scope_depth;  //       |
                                                              //       |
    expression(parser); // Condition                          //       |
                                                              //       |
    consume(parser, TOKEN_DO, "expect 'do' after while condition"); // |
                                                              //       |
    int exit_jump = emit_jump(parser, OP_JMP_POP_FALSE);      // ---.  |
                                                              //    |  |
    loop_block(parser);                                       //    |  |
                                                              //    |  |
    emit_loop(parser, loop_start);                            // -------
                                                              //    |
    patch_jump(parser, exit_jump);                            // <---

    // The resulting expression of a loop is always nil.
    emit_byte(parser, OP_PUSH_NIL);

    // Pop the current loop state.
    parser->inner_loop_start = previous_inner_loop_start;
    parser->inner_loop_depth = previous_inner_loop_depth;

    Debug_Exit(parser);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movl 0x4c(%rax), %eax
movl %eax, -0xc(%rbp)
movq -0x8(%rbp), %rax
movl 0x50(%rax), %eax
movl %eax, -0x10(%rbp)
movq -0x8(%rbp), %rdi
callq 0x9560
movl (%rax), %eax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x4c(%rax)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x221c(%rax), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x50(%rax)
movq -0x8(%rbp), %rdi
callq 0x8fe0
movq -0x8(%rbp), %rdi
movl $0x22, %esi
leaq 0x4b8a(%rip), %rdx      # 0xec40
callq 0x9240
movq -0x8(%rbp), %rdi
movl $0x21, %esi
callq 0xab90
movl %eax, -0x18(%rbp)
movq -0x8(%rbp), %rdi
callq 0xb620
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x9ae0
movq -0x8(%rbp), %rdi
movl -0x18(%rbp), %esi
callq 0xabe0
movq -0x8(%rbp), %rdi
movl $0x2, %esi
callq 0x9000
movl -0xc(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x4c(%rax)
movl -0x10(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x50(%rax)
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)