// File: /workspace/github_cpp_makefile_star2_O1/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
pushq %r14
pushq %rbx
cmpq $0x0, 0x8(%rdi)
je 0x492e
movq %rdi, %rbx
movq (%rdi), %rdi
movl $0x1, %esi
callq 0x71e2
movq %rax, %r14
movq %rbx, %rdi
callq 0x7be6
movq %rax, 0x8(%r14)
movq 0x10(%rbx), %rdi
movl (%rdi), %eax
cmpl $0xa, %eax
jle 0x4866
cmpl $0xb, %eax
je 0x488e
cmpl $0x1b, %eax
je 0x48b0
cmpl $0x1a, %eax
jne 0x494d
movl $0xb, (%r14)
movb $0x1, 0x10(%r14)
jmp 0x48fa
cmpl $0x1, %eax
je 0x48be
cmpl $0x2, %eax
jne 0x494d
movq 0x8(%rbx), %rax
movq 0x10(%rbx), %rcx
testq %rax, %rax
je 0x48d0
addq $0x18, %rcx
movq %rcx, 0x10(%rbx)
decq %rax
jmp 0x48de
movl $0x0, (%r14)
addq $0x8, %rdi
callq 0x7cca
testb $0x1, %al
je 0x4978
shrq $0x20, %rax
movq %rax, 0x10(%r14)
jmp 0x48fa
movl $0xb, (%r14)
movb $0x0, 0x10(%r14)
jmp 0x48fa
movl $0x1, (%r14)
movups 0x8(%rdi), %xmm0
movups %xmm0, 0x10(%r14)
jmp 0x48fa
leaq (%rax,%rax,2), %rax
leaq (%rcx,%rax,8), %rax
movq %rax, 0x10(%rbx)
xorl %eax, %eax
movq %rax, 0x8(%rbx)
movq %rbx, %rdi
callq 0x3e52
movq %rax, %r14
movq %rbx, %rdi
movl $0x3, %esi
callq 0x7b60
movq 0x8(%rbx), %rax
movq 0x10(%rbx), %rcx
testq %rax, %rax
je 0x4914
addq $0x18, %rcx
movq %rcx, 0x10(%rbx)
decq %rax
jmp 0x4922
leaq (%rax,%rax,2), %rax
leaq (%rcx,%rax,8), %rax
movq %rax, 0x10(%rbx)
xorl %eax, %eax
movq %rax, 0x8(%rbx)
movq %r14, %rax
popq %rbx
popq %r14
popq %rbp
retq
leaq 0x610f(%rip), %rdi      # 0xaa44
leaq 0x6119(%rip), %rsi      # 0xaa55
leaq 0x615c(%rip), %rcx      # 0xaa9f
movl $0x204, %edx            # imm = 0x204
callq 0x1090
leaq 0x18(%rbx), %r14
movq %rbx, %rdi
callq 0x7be6
movq 0x10(%rbx), %rcx
movl (%rcx), %ecx
leaq 0x616f(%rip), %rdx      # 0xaad5
leaq 0x5d14(%rip), %r8       # 0xa681
movq %r14, %rdi
movq %rax, %rsi
callq 0x7d48
leaq 0x18(%rbx), %r14
movq %rbx, %rdi
callq 0x7be6
movq 0x10(%rbx), %rdx
movq 0x8(%rdx), %rcx
movq 0x10(%rdx), %r8
leaq 0x5cea(%rip), %rdx      # 0xa681
leaq 0x6125(%rip), %r9       # 0xaac3
movq %r14, %rdi
movq %rax, %rsi
callq 0x70a4
nop