// File: /workspace/github_c_makefile_star2_O0/johnvtan[P]ccccc/parse.c
// Function: parse_primary
static expr_t *parse_primary(list_t *tokens, env_t *env) {
    debug("parse primary\n");
    token_t *curr = list_peek(tokens);

    if (curr->type == TOK_INT_LIT) {
        list_pop(tokens);
        debug("Found integer literal: %d\n", curr->int_literal);
        return new_primary_int(curr->int_literal);
    }

    if (curr->type == TOK_CHAR_LIT) {
        list_pop(tokens);
        debug("Found character literal\n");
        return new_primary_char(curr->char_literal);
    }

    if (curr->type == TOK_IDENT) {
        // Ident can be either a variable or function call
        // It seems like really, functions are variables in the global
        // environment.
        list_pop(tokens);

        var_info_t *var_info;
        if ((var_info = env_get(env, curr->ident))) {
            // First, assume that the identifier is a variable.
            debug("Found variable: %s\n", string_get(curr->ident));
            return new_primary_var(curr->ident, var_info->type);
        }

        fn_def_t *fn_def;
        if ((fn_def = map_get(program->fn_defs, curr->ident))) {
            // Otherwise, try to see if it's a function call.
            debug("Found function call: %s\n", string_get(curr->ident));
            return new_fn_call(fn_def, tokens, env);
        }

        UNREACHABLE("Primary: bad ident\n");
    }

    if (curr->type == TOK_OPEN_PAREN) {
        list_pop(tokens);
        debug("Found nested expr\n");
        expr_t *expr = parse_expr(tokens, env);
        expect_next(tokens, TOK_CLOSE_PAREN);
        return new_primary_expr(expr);
    }
    UNREACHABLE("parse: Unrecognized expression\n");
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
jmp 0x7402
movq -0x10(%rbp), %rdi
callq 0x48b0
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x1, (%rax)
jne 0x7438
movq -0x10(%rbp), %rdi
callq 0x47d0
jmp 0x7423
movq -0x20(%rbp), %rax
movl 0x8(%rax), %edi
callq 0x63c0
movq %rax, -0x8(%rbp)
jmp 0x758e
movq -0x20(%rbp), %rax
cmpl $0x2, (%rax)
jne 0x7462
movq -0x10(%rbp), %rdi
callq 0x47d0
jmp 0x744c
movq -0x20(%rbp), %rax
movsbl 0x8(%rax), %edi
callq 0x75a0
movq %rax, -0x8(%rbp)
jmp 0x758e
movq -0x20(%rbp), %rax
cmpl $0x3, (%rax)
jne 0x751f
movq -0x10(%rbp), %rdi
callq 0x47d0
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x44b0
movq %rax, -0x28(%rbp)
cmpq $0x0, %rax
je 0x74b3
jmp 0x7495
jmp 0x7497
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x28(%rbp), %rax
movl (%rax), %esi
callq 0x75e0
movq %rax, -0x8(%rbp)
jmp 0x758e
movq 0x5bfe(%rip), %rax      # 0xd0b8
movq (%rax), %rdi
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x4ba0
movq %rax, -0x30(%rbp)
cmpq $0x0, %rax
je 0x74f2
jmp 0x74d6
jmp 0x74d8
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x7690
movq %rax, -0x8(%rbp)
jmp 0x758e
jmp 0x74f4
leaq 0x1b09(%rip), %rdi      # 0x9004
leaq 0x22df(%rip), %rsi      # 0x97e1
movl $0x119, %edx            # imm = 0x119
leaq 0x2539(%rip), %rcx      # 0x9a47
movb $0x0, %al
callq 0x1070
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x1110
movq -0x20(%rbp), %rax
cmpl $0xe, (%rax)
jne 0x7561
movq -0x10(%rbp), %rdi
callq 0x47d0
jmp 0x7533
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x6180
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movl $0xf, %esi
callq 0x5800
movq -0x38(%rbp), %rdi
callq 0x7910
movq %rax, -0x8(%rbp)
jmp 0x758e
jmp 0x7563
leaq 0x1a9a(%rip), %rdi      # 0x9004
leaq 0x2270(%rip), %rsi      # 0x97e1
movl $0x123, %edx            # imm = 0x123
leaq 0x24de(%rip), %rcx      # 0x9a5b
movb $0x0, %al
callq 0x1070
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x1110
movq -0x8(%rbp), %rax
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax,%rax)