// File: tsoding[P]wcc/src/./wcc_parser.cpp
// Function: Parser::parse_statement()
Statement Parser::parse_statement()
{
    Statement result = {};

    assert(tokens.count > 0);
    result.offset = current_offset();

    switch (tokens.items->type) {
    case Token_Type::While:
        result.kind = Statement_Kind::While;
        result.hwile = parse_while();
        break;
    case Token_Type::If:
        result.kind = Statement_Kind::If;
        result.iph = parse_if();
        break;
    case Token_Type::Local:
        result.kind = Statement_Kind::Local_Var_Def;
        result.local_var_def = parse_local_var_def();
        break;
    case Token_Type::Symbol:
        assert(tokens.count > 1);
        switch (tokens.items[1].type) {
        case Token_Type::Equals:
            result.kind = Statement_Kind::Assignment;
            result.assignment = parse_assignment();
            break;
        case Token_Type::Minus_Equals:
            result.kind = Statement_Kind::Assignment;
            result.assignment = parse_subtract_assignment();
            break;
        case Token_Type::Plus_Equals:
            result.kind = Statement_Kind::Assignment;
            result.assignment = parse_add_assignment();
            break;
        default:
            result.kind = Statement_Kind::Expression;
            result.expression = parse_expression();
            expect_token_type(Token_Type::Semicolon);
            tokens.chop(1);
        }
        break;
    case Token_Type::Return:
        result.kind = Statement_Kind::Return;
        result.reeturn = parse_return();
        break;
    default:
        result.kind = Statement_Kind::Expression;
        result.expression = parse_expression();
        expect_token_type(Token_Type::Semicolon);
        tokens.chop(1);
    }

    return result;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movq %rdi, -0xb8(%rbp)
movq %rdi, %rax
movq %rax, -0xb0(%rbp)
movq %rsi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xa8(%rbp)
xorl %esi, %esi
movl $0x30, %edx
callq 0x10b0
movq -0xa8(%rbp), %rax
cmpq $0x0, 0x8(%rax)
jbe 0x5ea7
jmp 0x5ec6
leaq 0x8e94(%rip), %rdi      # 0xed42
leaq 0x8e9e(%rip), %rsi      # 0xed53
movl $0x18d, %edx            # imm = 0x18D
leaq 0x8ea7(%rip), %rcx      # 0xed68
callq 0x10c0
movq -0xa8(%rbp), %rdi
callq 0xb270
movq -0xb8(%rbp), %rcx
movq %rax, %rdx
movq -0xa8(%rbp), %rax
movq %rdx, 0x8(%rcx)
movq 0x10(%rax), %rax
movl (%rax), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0xc0(%rbp)
subl $0x18, %eax
ja 0x61a2
movq -0xc0(%rbp), %rax
leaq 0x83c9(%rip), %rcx      # 0xe2d8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0xb8(%rbp), %rax
movq -0xa8(%rbp), %rdi
movl $0x1, (%rax)
callq 0x5980
movq %rax, %rcx
movq -0xb8(%rbp), %rax
movq %rcx, -0x18(%rbp)
movq %rdx, -0x10(%rbp)
movq -0x18(%rbp), %rcx
movq %rcx, 0x10(%rax)
movq -0x10(%rbp), %rcx
movq %rcx, 0x18(%rax)
jmp 0x61ef
movq -0xb8(%rbp), %rax
movq -0xa8(%rbp), %rsi
movl $0x2, (%rax)
leaq -0x30(%rbp), %rdi
callq 0x5730
movq -0xb8(%rbp), %rax
movq -0x30(%rbp), %rcx
movq %rcx, 0x10(%rax)
movq -0x28(%rbp), %rcx
movq %rcx, 0x18(%rax)
movq -0x20(%rbp), %rcx
movq %rcx, 0x20(%rax)
jmp 0x61ef
movq -0xb8(%rbp), %rax
movq -0xa8(%rbp), %rsi
movl $0x0, (%rax)
leaq -0x50(%rbp), %rdi
callq 0x6200
movq -0xb8(%rbp), %rax
movq -0x50(%rbp), %rcx
movq %rcx, 0x10(%rax)
movq -0x48(%rbp), %rcx
movq %rcx, 0x18(%rax)
movq -0x40(%rbp), %rcx
movq %rcx, 0x20(%rax)
movq -0x38(%rbp), %rcx
movq %rcx, 0x28(%rax)
jmp 0x61ef
movq -0xa8(%rbp), %rax
cmpq $0x1, 0x8(%rax)
jbe 0x5ff2
jmp 0x6011
leaq 0x8d93(%rip), %rdi      # 0xed8c
leaq 0x8d53(%rip), %rsi      # 0xed53
movl $0x19e, %edx            # imm = 0x19E
leaq 0x8d5c(%rip), %rcx      # 0xed68
callq 0x10c0
movq -0xa8(%rbp), %rax
movq 0x10(%rax), %rax
movl 0x18(%rax), %eax
movl %eax, -0xc4(%rbp)
subl $0x9, %eax
je 0x604d
jmp 0x602c
movl -0xc4(%rbp), %eax
subl $0x10, %eax
je 0x608e
jmp 0x6039
movl -0xc4(%rbp), %eax
subl $0x11, %eax
je 0x60cf
jmp 0x6119
movq -0xb8(%rbp), %rax
movq -0xa8(%rbp), %rsi
movl $0x3, (%rax)
leaq -0x68(%rbp), %rdi
callq 0x5ac0
movq -0xb8(%rbp), %rax
movq -0x68(%rbp), %rcx
movq %rcx, 0x10(%rax)
movq -0x60(%rbp), %rcx
movq %rcx, 0x18(%rax)
movq -0x58(%rbp), %rcx
movq %rcx, 0x20(%rax)
jmp 0x6166
movq -0xb8(%rbp), %rax
movq -0xa8(%rbp), %rsi
movl $0x3, (%rax)
leaq -0x80(%rbp), %rdi
callq 0x5cb0
movq -0xb8(%rbp), %rax
movq -0x80(%rbp), %rcx
movq %rcx, 0x10(%rax)
movq -0x78(%rbp), %rcx
movq %rcx, 0x18(%rax)
movq -0x70(%rbp), %rcx
movq %rcx, 0x20(%rax)
jmp 0x6166
movq -0xb8(%rbp), %rax
movq -0xa8(%rbp), %rsi
movl $0x3, (%rax)
leaq -0x98(%rbp), %rdi
callq 0x5b80
movq -0xb8(%rbp), %rax
movq -0x98(%rbp), %rcx
movq %rcx, 0x10(%rax)
movq -0x90(%rbp), %rcx
movq %rcx, 0x18(%rax)
movq -0x88(%rbp), %rcx
movq %rcx, 0x20(%rax)
jmp 0x6166
movq -0xa8(%rbp), %rdi
movq -0xb8(%rbp), %rax
movl $0x4, (%rax)
callq 0x5830
movq -0xa8(%rbp), %rdi
movq %rax, %rcx
movq -0xb8(%rbp), %rax
movq %rcx, 0x10(%rax)
movl $0x13, %esi
callq 0xb150
movq -0xa8(%rbp), %rdi
addq $0x8, %rdi
movl $0x1, %esi
callq 0xb210
jmp 0x61ef
movq -0xb8(%rbp), %rax
movq -0xa8(%rbp), %rdi
movl $0x5, (%rax)
callq 0x5de0
movq %rax, %rcx
movq -0xb8(%rbp), %rax
movq %rcx, -0xa0(%rbp)
movq -0xa0(%rbp), %rcx
movq %rcx, 0x10(%rax)
jmp 0x61ef
movq -0xa8(%rbp), %rdi
movq -0xb8(%rbp), %rax
movl $0x4, (%rax)
callq 0x5830
movq -0xa8(%rbp), %rdi
movq %rax, %rcx
movq -0xb8(%rbp), %rax
movq %rcx, 0x10(%rax)
movl $0x13, %esi
callq 0xb150
movq -0xa8(%rbp), %rdi
addq $0x8, %rdi
movl $0x1, %esi
callq 0xb210
movq -0xb0(%rbp), %rax
addq $0xd0, %rsp
popq %rbp
retq
nop