// File: /workspace/github_cpp_makefile_star2_O2/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 %r15
pushq %r14
pushq %rbx
pushq %rax
cmpq $0x0, 0x8(%rdi)
je 0x3d24
movq %rdi, %r14
leaq 0x8(%rdi), %rbx
movq (%rdi), %rdi
pushq $0x1
popq %rsi
callq 0x5ce2
movq %rax, %r15
movq %r14, %rdi
callq 0x6528
movq %rax, 0x8(%r15)
movq 0x10(%r14), %rdi
movl (%rdi), %eax
cmpl $0x1, %eax
je 0x3cd2
cmpl $0x2, %eax
je 0x3caf
cmpl $0xb, %eax
je 0x3ce4
cmpl $0x1b, %eax
je 0x3cff
cmpl $0x1a, %eax
jne 0x3d74
movl $0xb, (%r15)
movb $0x1, 0x10(%r15)
jmp 0x3d0b
pushq $0x1
popq %rsi
movq %rbx, %rdi
callq 0x64f6
movq %r14, %rdi
callq 0x35a2
movq %rax, %r15
pushq $0x3
popq %rsi
movq %r14, %rdi
callq 0x6470
jmp 0x3d0b
movl $0x1, (%r15)
movups 0x8(%rdi), %xmm0
movups %xmm0, 0x10(%r15)
jmp 0x3d0b
andl $0x0, (%r15)
addq $0x8, %rdi
callq 0x65e0
testb $0x1, %al
je 0x3d43
shrq $0x20, %rax
movq %rax, 0x10(%r15)
jmp 0x3d0b
movl $0xb, (%r15)
movb $0x0, 0x10(%r15)
pushq $0x1
popq %rsi
movq %rbx, %rdi
callq 0x64f6
movq %r15, %rax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x4d2d(%rip), %rdi      # 0x8a58
leaq 0x4d37(%rip), %rsi      # 0x8a69
leaq 0x4d7a(%rip), %rcx      # 0x8ab3
movl $0x204, %edx            # imm = 0x204
callq 0x1090
leaq 0x18(%r14), %rbx
movq %r14, %rdi
callq 0x6528
movq 0x10(%r14), %rdx
movq 0x8(%rdx), %rcx
movq 0x10(%rdx), %r8
leaq 0x4933(%rip), %rdx      # 0x8695
leaq 0x4d6e(%rip), %r9       # 0x8ad7
movq %rbx, %rdi
movq %rax, %rsi
callq 0x5bb6
leaq 0x18(%r14), %rbx
movq %r14, %rdi
callq 0x6528
movq 0x10(%r14), %rcx
movl (%rcx), %ecx
leaq 0x4d5c(%rip), %rdx      # 0x8ae9
leaq 0x4901(%rip), %r8       # 0x8695
movq %rbx, %rdi
movq %rax, %rsi
callq 0x6656
nop