// File: /workspace/github_c_makefile_star2_O0/mahrr[P]raven/src/compiler.c
// Function: match
static void match(Parser *parser) {
    Debug_Log(parser);

    expression(parser); // Value
    consume(parser, TOKEN_DO, "expect 'do' after match value");

    int cases_exit[MATCH_LIMIT];
    int cases_count = 0;

    do {
        if (cases_count == MATCH_LIMIT) {
            error_limit(parser, "match cases", MATCH_LIMIT);
            break;
        }

        begin_scope(parser);

        Pattern_Context context = {0};
        pattern(parser, &context, false);
        consume(parser, TOKEN_ARROW, "expect '->' after pattern");

        // Match succeeded.
        expression(parser);

        // Save the expression value in X and rewind the stack.
        emit_byte(parser, OP_POP_X);
        unwind_stack(parser, parser->context->scope_depth);
        emit_byte(parser, OP_PUSH_X);
        cases_exit[cases_count++] = emit_jump(parser, OP_JMP);

        // Match failed.
        for (int i = 0; i < context.cases_count; ++i) {
            patch_jump(parser, context.cases_next[i]);
        }

        // Discard the case scope.
        parser->context->scope_depth--;
    } while (consume_if(parser, TOKEN_COMMA));

    // If all patterns didn't match.
    emit_bytes(parser, OP_POP, OP_PUSH_NIL);

    for (int i = 0; i < cases_count; i++) {
        patch_jump(parser, cases_exit[i]);
    }

    consume(parser, TOKEN_END, "expect 'end' after match cases");

    Debug_Exit(parser);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x8b0, %rsp            # imm = 0x8B0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
callq 0x8fe0
movq -0x8(%rbp), %rdi
movl $0x22, %esi
leaq 0x4c7f(%rip), %rdx      # 0xeae7
callq 0x9240
movl $0x0, -0x814(%rbp)
cmpl $0x200, -0x814(%rbp)    # imm = 0x200
jne 0x9e9d
movq -0x8(%rbp), %rdi
leaq 0x4ca4(%rip), %rsi      # 0xeb32
movl $0x200, %edx            # imm = 0x200
callq 0x9580
jmp 0x9fb3
movq -0x8(%rbp), %rdi
callq 0x97e0
leaq -0x89c(%rbp), %rdi
xorl %esi, %esi
movl $0x88, %edx
callq 0x2100
movq -0x8(%rbp), %rdi
leaq -0x89c(%rbp), %rsi
xorl %edx, %edx
callq 0xadc0
movq -0x8(%rbp), %rdi
movl $0x24, %esi
leaq 0x4c2a(%rip), %rdx      # 0xeb05
callq 0x9240
movq -0x8(%rbp), %rdi
callq 0x8fe0
movq -0x8(%rbp), %rdi
movl $0x5, %esi
callq 0x9000
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x221c(%rax), %esi
callq 0x99e0
movq -0x8(%rbp), %rdi
movl $0x4, %esi
callq 0x9000
movq -0x8(%rbp), %rdi
movl $0x1e, %esi
callq 0xab90
movl %eax, %ecx
movl -0x814(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x814(%rbp)
cltq
movl %ecx, -0x810(%rbp,%rax,4)
movl $0x0, -0x8a0(%rbp)
movl -0x8a0(%rbp), %eax
cmpl -0x81c(%rbp), %eax
jge 0x9f86
movq -0x8(%rbp), %rdi
movslq -0x8a0(%rbp), %rax
movl -0x89c(%rbp,%rax,4), %esi
callq 0xabe0
movl -0x8a0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8a0(%rbp)
jmp 0x9f50
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x221c(%rax), %ecx
addl $-0x1, %ecx
movl %ecx, 0x221c(%rax)
movq -0x8(%rbp), %rdi
movl $0x25, %esi
callq 0x8c60
testb $0x1, %al
jne 0x9e77
movq -0x8(%rbp), %rdi
movl $0x7, %esi
movl $0x2, %edx
callq 0x9620
movl $0x0, -0x8a4(%rbp)
movl -0x8a4(%rbp), %eax
cmpl -0x814(%rbp), %eax
jge 0xa006
movq -0x8(%rbp), %rdi
movslq -0x8a4(%rbp), %rax
movl -0x810(%rbp,%rax,4), %esi
callq 0xabe0
movl -0x8a4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8a4(%rbp)
jmp 0x9fd0
movq -0x8(%rbp), %rdi
movl $0x23, %esi
leaq 0x4b09(%rip), %rdx      # 0xeb1f
callq 0x9240
addq $0x8b0, %rsp            # imm = 0x8B0
popq %rbp
retq
nopw %cs:(%rax,%rax)