// File: /workspace/github_cpp_makefile_star2_O3/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 0x472e
movq %rdi, %rbx
movq (%rdi), %rdi
movl $0x1, %esi
callq 0x6f46
movq %rax, %r14
movq %rbx, %rdi
callq 0x794a
movq %rax, 0x8(%r14)
movq 0x10(%rbx), %rdi
movl (%rdi), %eax
cmpl $0xa, %eax
jle 0x4670
cmpl $0xb, %eax
je 0x46bd
cmpl $0x1b, %eax
je 0x46df
cmpl $0x1a, %eax
jne 0x474d
movl $0xb, (%r14)
movb $0x1, 0x10(%r14)
jmp 0x4701
cmpl $0x1, %eax
je 0x46ed
cmpl $0x2, %eax
jne 0x474d
movq 0x8(%rbx), %rax
testq %rax, %rax
movl $0x18, %ecx
cmoveq %rax, %rcx
addq %rcx, %rdi
xorl %ecx, %ecx
subq $0x1, %rax
cmovaeq %rax, %rcx
movq %rdi, 0x10(%rbx)
movq %rcx, 0x8(%rbx)
movq %rbx, %rdi
callq 0x3d52
movq %rax, %r14
movq %rbx, %rdi
movl $0x3, %esi
callq 0x78c4
jmp 0x46fd
movl $0x0, (%r14)
addq $0x8, %rdi
callq 0x7a2e
testb $0x1, %al
je 0x4778
shrq $0x20, %rax
movq %rax, 0x10(%r14)
jmp 0x46fd
movl $0xb, (%r14)
movb $0x0, 0x10(%r14)
jmp 0x4701
movl $0x1, (%r14)
movups 0x8(%rdi), %xmm0
movups %xmm0, 0x10(%r14)
movq 0x10(%rbx), %rdi
movq 0x8(%rbx), %rax
testq %rax, %rax
movl $0x18, %ecx
cmoveq %rax, %rcx
addq %rdi, %rcx
xorl %edx, %edx
subq $0x1, %rax
cmovaeq %rax, %rdx
movq %rcx, 0x10(%rbx)
movq %rdx, 0x8(%rbx)
movq %r14, %rax
popq %rbx
popq %r14
popq %rbp
retq
leaq 0x532f(%rip), %rdi      # 0x9a64
leaq 0x5339(%rip), %rsi      # 0x9a75
leaq 0x537c(%rip), %rcx      # 0x9abf
movl $0x204, %edx            # imm = 0x204
callq 0x1090
leaq 0x18(%rbx), %r14
movq %rbx, %rdi
callq 0x794a
movq 0x10(%rbx), %rcx
movl (%rcx), %ecx
leaq 0x538f(%rip), %rdx      # 0x9af5
leaq 0x4f34(%rip), %r8       # 0x96a1
movq %r14, %rdi
movq %rax, %rsi
callq 0x7aac
leaq 0x18(%rbx), %r14
movq %rbx, %rdi
callq 0x794a
movq 0x10(%rbx), %rdx
movq 0x8(%rdx), %rcx
movq 0x10(%rdx), %r8
leaq 0x4f0a(%rip), %rdx      # 0x96a1
leaq 0x5345(%rip), %r9       # 0x9ae3
movq %r14, %rdi
movq %rax, %rsi
callq 0x6e08
nop