// File: baziotis[P]minijava-cpp/parse.cpp
// Function: parse_expr_primary()
static Expression *parse_expr_primary() {
    if (match_token(TOK::LPAR)) {
        Expression *expr = parse_expr();
        expect_token(TOK::RPAR);
        return expr;
    }
    Expression *expr = new Expression;
    expr->loc = loc;
    switch (token.kind) {
    case TOK::FALSE:
    {
        next_token();
        expr->kind = EXPR::BOOL_LIT;
        expr->lit_val = 0;
    } break;
    case TOK::ID:
    {
        expr->kind = EXPR::ID;
        expr->id = token.id;
        next_token();
    } break;
    case TOK::INTLIT:
    {
        expr->kind = EXPR::INT_LIT;
        expr->lit_val = token.val;
        next_token();
    } break;
    case TOK::THIS:
    {
        next_token();
        expr->kind = EXPR::THIS;
    } break;
    case TOK::NEW:
    {
        next_token();
        if (match_token(TOK::INT)) { // ArrayAllocationExpression
            expr->kind = EXPR::ARR_ALLOC;
            expect_token_in_rule(TOK::LBRACKET, "array allocation expression");
            expr->e1 = parse_expr();
            expect_token_in_rule(TOK::RBRACKET, "array allocation expression");
        } else if (is_token(TOK::ID)) {
            expr->kind = EXPR::ALLOC;
            expr->id = token.id;
            next_token();
            expect_token_in_rule(TOK::LPAR, "allocation expression");
            expect_token_in_rule(TOK::RPAR, "allocation expression");
        }
    } break;
    case TOK::TRUE:
    {
        next_token();
        expr->kind = EXPR::BOOL_LIT;
        expr->lit_val = 1;
    } break;
    default:
    {
        syntax_error("An expression can't start with: `", token, "`");
        expr->kind = EXPR::UNDEFINED;
    }
    }
    return expr;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movl $0x3, %edi
callq 0x82c0
testb $0x1, %al
jne 0xa108
jmp 0xa12a
callq 0x9990
movq %rax, -0x10(%rbp)
movl $0x19, %edi
xorl %esi, %esi
callq 0x98d0
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xa30e
movl $0x18, %edi
callq 0xae40
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
leaq 0x1a55d(%rip), %rcx     # 0x246a0
movl (%rcx), %ecx
movl %ecx, (%rax)
leaq 0x1a55a(%rip), %rax     # 0x246a8
movl (%rax), %eax
addl $-0x2, %eax
movl %eax, %ecx
movq %rcx, -0x30(%rbp)
subl $0x13, %eax
ja 0xa2cb
movq -0x30(%rbp), %rax
leaq 0x10997(%rip), %rcx     # 0x1ab04
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
callq 0x4370
movq -0x18(%rbp), %rax
movl $0xc, 0x4(%rax)
movq -0x18(%rbp), %rax
movl $0x0, 0x10(%rax)
jmp 0xa306
movq -0x18(%rbp), %rax
movl $0xa, 0x4(%rax)
leaq 0x1a500(%rip), %rax     # 0x246a8
movq 0x8(%rax), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
callq 0x4370
jmp 0xa306
movq -0x18(%rbp), %rax
movl $0xb, 0x4(%rax)
leaq 0x1a4d8(%rip), %rax     # 0x246a8
movl 0x8(%rax), %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x10(%rax)
callq 0x4370
jmp 0xa306
callq 0x4370
movq -0x18(%rbp), %rax
movl $0xd, 0x4(%rax)
jmp 0xa306
callq 0x4370
movl $0x6, %edi
callq 0x82c0
testb $0x1, %al
jne 0xa20e
jmp 0xa251
movq -0x18(%rbp), %rax
movl $0xe, 0x4(%rax)
movl $0x24, %edi
leaq 0x10f9b(%rip), %rsi     # 0x1b1c0
xorl %edx, %edx
callq 0x8300
callq 0x9990
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
movl $0x1b, %edi
leaq 0x10f78(%rip), %rsi     # 0x1b1c0
xorl %edx, %edx
callq 0x8300
jmp 0xa2ac
movl $0x8, %edi
callq 0x8070
testb $0x1, %al
jne 0xa261
jmp 0xa2aa
movq -0x18(%rbp), %rax
movl $0xf, 0x4(%rax)
leaq 0x1a435(%rip), %rax     # 0x246a8
movq 0x8(%rax), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
callq 0x4370
movl $0x3, %edi
leaq 0x10f36(%rip), %rsi     # 0x1b1c6
xorl %edx, %edx
callq 0x8300
movl $0x19, %edi
leaq 0x10f23(%rip), %rsi     # 0x1b1c6
xorl %edx, %edx
callq 0x8300
jmp 0xa2ac
jmp 0xa306
callq 0x4370
movq -0x18(%rbp), %rax
movl $0xc, 0x4(%rax)
movq -0x18(%rbp), %rax
movl $0x1, 0x10(%rax)
jmp 0xa306
leaq 0x1a3d6(%rip), %rax     # 0x246a8
movq (%rax), %rcx
movq %rcx, -0x28(%rbp)
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
movl -0x28(%rbp), %esi
movq -0x20(%rbp), %rdx
leaq 0x10eed(%rip), %rdi     # 0x1b1dc
leaq 0x10a37(%rip), %rcx     # 0x1ad2d
callq 0xa320
movq -0x18(%rbp), %rax
movl $0x0, 0x4(%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x30, %rsp
popq %rbp
retq
nopl (%rax,%rax)