// File: tsoding[P]wcc/src/./wcc_parser.cpp
// Function: Parser::parse_primary()
Expression *Parser::parse_primary()
{
    assert(tokens.count > 0);

    Expression *primary_expression = memory->alloc<Expression>();
    primary_expression->offset = current_offset();

    switch (tokens.items->type) {
    case Token_Type::True: {
        primary_expression->kind = Expression_Kind::Bool_Literal;
        primary_expression->bool_literal = {true};
        tokens.chop(1);
    } break;

    case Token_Type::False: {
        primary_expression->kind = Expression_Kind::Bool_Literal;
        primary_expression->bool_literal = {false};
        tokens.chop(1);
    } break;

    case Token_Type::Number_Literal: {
        primary_expression->kind = Expression_Kind::Number_Literal;
        auto x = tokens.items->text.as_integer<uint32_t>();
        if (!x.has_value) {
            reporter.fail(current_offset(), "`", tokens.items->text, "` is not a number");
        }
        primary_expression->number_literal.unwrap = x.unwrap;
        tokens.chop(1);
    } break;

    case Token_Type::Symbol: {
        primary_expression->kind = Expression_Kind::Variable;
        primary_expression->variable.name = tokens.items->text;
        tokens.chop(1);
    } break;

    case Token_Type::Open_Paren: {
        tokens.chop(1);
        primary_expression = parse_expression();
        expect_token_type(Token_Type::Closed_Paren);
        tokens.chop(1);
    } break;

    default:
        reporter.fail(current_offset(), "Unexpected token in an expression `", tokens.items->type, "`");
    }

    return primary_expression;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x38(%rbp)
cmpq $0x0, 0x8(%rax)
jbe 0x63dd
jmp 0x63fc
leaq 0x895e(%rip), %rdi      # 0xed42
leaq 0x8968(%rip), %rsi      # 0xed53
movl $0x204, %edx            # imm = 0x204
leaq 0x89a6(%rip), %rcx      # 0xed9d
callq 0x10c0
movq -0x38(%rbp), %rax
movq (%rax), %rdi
movl $0x1, %esi
callq 0xa300
movq -0x38(%rbp), %rdi
movq %rax, -0x10(%rbp)
callq 0xb270
movq %rax, %rdx
movq -0x38(%rbp), %rax
movq -0x10(%rbp), %rcx
movq %rdx, 0x8(%rcx)
movq 0x10(%rax), %rax
movl (%rax), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x40(%rbp)
subl $0x1a, %eax
ja 0x65c0
movq -0x40(%rbp), %rax
leaq 0x7ef1(%rip), %rcx      # 0xe33c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x38(%rbp), %rdi
movq -0x10(%rbp), %rax
movl $0xb, (%rax)
movb $0x1, -0x11(%rbp)
movq -0x10(%rbp), %rax
movb -0x11(%rbp), %cl
movb %cl, 0x10(%rax)
addq $0x8, %rdi
movl $0x1, %esi
callq 0xb210
jmp 0x65f8
movq -0x38(%rbp), %rdi
movq -0x10(%rbp), %rax
movl $0xb, (%rax)
movb $0x0, -0x12(%rbp)
movq -0x10(%rbp), %rax
movb -0x12(%rbp), %cl
movb %cl, 0x10(%rax)
addq $0x8, %rdi
movl $0x1, %esi
callq 0xb210
jmp 0x65f8
movq -0x38(%rbp), %rax
movq -0x10(%rbp), %rcx
movl $0x0, (%rcx)
movq 0x10(%rax), %rdi
addq $0x8, %rdi
callq 0xb380
movq %rax, -0x1c(%rbp)
testb $0x1, -0x1c(%rbp)
jne 0x6525
movq -0x38(%rbp), %rdi
movq %rdi, %rax
addq $0x18, %rax
movq %rax, -0x48(%rbp)
callq 0xb270
movq -0x48(%rbp), %rdi
movq %rax, %rsi
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rcx
movq %rcx, -0x30(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x30(%rbp), %rcx
movq -0x28(%rbp), %r8
leaq 0x83c4(%rip), %rdx      # 0xe8dd
leaq 0x88a1(%rip), %r9       # 0xedc1
callq 0xa110
movq -0x38(%rbp), %rdi
movl -0x18(%rbp), %eax
movl %eax, %ecx
movq -0x10(%rbp), %rax
movq %rcx, 0x10(%rax)
addq $0x8, %rdi
movl $0x1, %esi
callq 0xb210
jmp 0x65f8
movq -0x38(%rbp), %rdi
movq -0x10(%rbp), %rax
movl $0x1, (%rax)
movq 0x10(%rdi), %rcx
movq -0x10(%rbp), %rax
movq 0x8(%rcx), %rdx
movq %rdx, 0x10(%rax)
movq 0x10(%rcx), %rcx
movq %rcx, 0x18(%rax)
addq $0x8, %rdi
movl $0x1, %esi
callq 0xb210
jmp 0x65f8
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
movl $0x1, %esi
callq 0xb210
movq -0x38(%rbp), %rdi
callq 0x5830
movq -0x38(%rbp), %rdi
movq %rax, -0x10(%rbp)
movl $0x3, %esi
callq 0xb150
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
movl $0x1, %esi
callq 0xb210
jmp 0x65f8
movq -0x38(%rbp), %rdi
movq %rdi, %rax
addq $0x18, %rax
movq %rax, -0x50(%rbp)
callq 0xb270
movq -0x50(%rbp), %rdi
movq %rax, %rsi
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movl (%rax), %ecx
leaq 0x87e7(%rip), %rdx      # 0xedd3
leaq 0x82ea(%rip), %r8       # 0xe8dd
callq 0xb450
movq -0x10(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)