// File: /workspace/github_c_makefile_star2_O0/theandrew168[P]squeaky/src/reader.c
// Function: reader_read
struct value*
reader_read(struct vm* vm, FILE* fp)
{
    assert(fp != NULL);

    eat_whitespace(fp);
    int c = peek(fp);

    if (c == EOF) {
        return vm_make_eof(vm);
    }

    // sharp expr: boolean, character, vector, etc
    if (c == '#') {
        advance(fp);  // skip sharp
        c = advance(fp);
        if (c == 't') {
            return vm_make_boolean(vm, true);
        } else if (c == 'f') {
            return vm_make_boolean(vm, false);
        } else if (c == '\\') {
            return read_character(vm, fp);
        // TODO: read vectors
//        } else if (c == '(') {
//            return read_vector(fp);
        } else {
            fprintf(stderr, "reader: invalid sharp expression\n");
            exit(EXIT_FAILURE);
        }
    }

    // numeric literal
    if (is_digit(c)) {
        return read_number(vm, fp);
    }

    // string literal
    if (c == '"') {
        return read_string(vm, fp);
    }

    // symbol
    if (is_initial(c) || is_peculiar_identifier(c)) {
        return read_symbol(vm, fp);
    }

    // quoted expr
    if (c == '\'') {
        advance(fp);  // skip quote
        struct value* exp = reader_read(vm, fp);
        return vm_make_pair(vm, vm_make_symbol(vm, "quote"),
                                vm_make_pair(vm, exp,
                                                 vm_make_empty_list(vm)));
    }

    // quasiquoted expr
    if (c == '`') {
        advance(fp);  // skip quasiquote
        struct value* exp = reader_read(vm, fp);
        return vm_make_pair(vm, vm_make_symbol(vm, "quasiquote"),
                                vm_make_pair(vm, exp,
                                                 vm_make_empty_list(vm)));
    }

    // unquote / unquote-splicing expr
    if (c == ',') {
        advance(fp);  // skip unquote
        if (peek(fp) == '@') {
            advance(fp);  // skip splicing
            struct value* exp = reader_read(vm, fp);
            return vm_make_pair(vm, vm_make_symbol(vm, "unquote-splicing"),
                                    vm_make_pair(vm, exp,
                                                     vm_make_empty_list(vm)));
        }

        struct value* exp = reader_read(vm, fp);
        return vm_make_pair(vm, vm_make_symbol(vm, "unquote"),
                                vm_make_pair(vm, exp,
                                                 vm_make_empty_list(vm)));
    }

    // pair / list / s-expression
    if (c == '(') {
        advance(fp);  // skip opening paren
        return read_pair(vm, fp);
    }

    fprintf(stderr, "reader: invalid expression\n");
    exit(EXIT_FAILURE);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x7cac
jmp 0x7ccb
leaq 0x2f61(%rip), %rdi      # 0xac14
leaq 0x2f65(%rip), %rsi      # 0xac1f
movl $0x14b, %edx            # imm = 0x14B
leaq 0x2f66(%rip), %rcx      # 0xac2c
callq 0x1100
movq -0x18(%rbp), %rdi
callq 0x7c10
movq -0x18(%rbp), %rdi
callq 0x74f0
movl %eax, -0x1c(%rbp)
cmpl $-0x1, -0x1c(%rbp)
jne 0x7cf8
movq -0x10(%rbp), %rdi
callq 0x9500
movq %rax, -0x8(%rbp)
jmp 0x807e
cmpl $0x23, -0x1c(%rbp)
jne 0x7d8c
movq -0x18(%rbp), %rdi
callq 0x74d0
movq -0x18(%rbp), %rdi
callq 0x74d0
movl %eax, -0x1c(%rbp)
cmpl $0x74, -0x1c(%rbp)
jne 0x7d34
movq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x8e90
movq %rax, -0x8(%rbp)
jmp 0x807e
cmpl $0x66, -0x1c(%rbp)
jne 0x7d4e
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0x8e90
movq %rax, -0x8(%rbp)
jmp 0x807e
cmpl $0x5c, -0x1c(%rbp)
jne 0x7d6a
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x73a0
movq %rax, -0x8(%rbp)
jmp 0x807e
movq 0x626f(%rip), %rax      # 0xdfe0
movq (%rax), %rdi
leaq 0x2ee0(%rip), %rsi      # 0xac5b
movb $0x0, %al
callq 0x1200
movl $0x1, %edi
callq 0x11a0
movl -0x1c(%rbp), %eax
movsbl %al, %edi
callq 0x76e0
testb $0x1, %al
jne 0x7d9d
jmp 0x7db3
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x75e0
movq %rax, -0x8(%rbp)
jmp 0x807e
cmpl $0x22, -0x1c(%rbp)
jne 0x7dcf
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x7740
movq %rax, -0x8(%rbp)
jmp 0x807e
movl -0x1c(%rbp), %eax
movsbl %al, %edi
callq 0x8090
testb $0x1, %al
jne 0x7def
movl -0x1c(%rbp), %eax
movsbl %al, %edi
callq 0x7a60
testb $0x1, %al
jne 0x7def
jmp 0x7e05
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x7840
movq %rax, -0x8(%rbp)
jmp 0x807e
cmpl $0x27, -0x1c(%rbp)
jne 0x7e83
movq -0x18(%rbp), %rdi
callq 0x74d0
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x7c90
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rdi
leaq 0x2e4a(%rip), %rsi      # 0xac82
callq 0x9070
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x10(%rbp), %rdi
callq 0x8dc0
movq -0x60(%rbp), %rdi
movq -0x58(%rbp), %rsi
movq %rax, %rdx
callq 0x9100
movq -0x50(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq %rax, %rdx
callq 0x9100
movq %rax, -0x8(%rbp)
jmp 0x807e
cmpl $0x60, -0x1c(%rbp)
jne 0x7f01
movq -0x18(%rbp), %rdi
callq 0x74d0
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x7c90
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x10(%rbp), %rdi
leaq 0x2dc7(%rip), %rsi      # 0xac7d
callq 0x9070
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x10(%rbp), %rdi
callq 0x8dc0
movq -0x80(%rbp), %rdi
movq -0x78(%rbp), %rsi
movq %rax, %rdx
callq 0x9100
movq -0x70(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq %rax, %rdx
callq 0x9100
movq %rax, -0x8(%rbp)
jmp 0x807e
cmpl $0x2c, -0x1c(%rbp)
jne 0x803a
movq -0x18(%rbp), %rdi
callq 0x74d0
movq -0x18(%rbp), %rdi
callq 0x74f0
cmpl $0x40, %eax
jne 0x7fb6
movq -0x18(%rbp), %rdi
callq 0x74d0
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x7c90
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rdi
leaq 0x2d32(%rip), %rsi      # 0xac88
callq 0x9070
movq %rax, -0x88(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x10(%rbp), %rdi
callq 0x8dc0
movq -0xa0(%rbp), %rdi
movq -0x98(%rbp), %rsi
movq %rax, %rdx
callq 0x9100
movq -0x90(%rbp), %rdi
movq -0x88(%rbp), %rsi
movq %rax, %rdx
callq 0x9100
movq %rax, -0x8(%rbp)
jmp 0x807e
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x7c90
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x10(%rbp), %rdi
leaq 0x2cbc(%rip), %rsi      # 0xac99
callq 0x9070
movq %rax, -0xa8(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0x10(%rbp), %rdi
callq 0x8dc0
movq -0xc0(%rbp), %rdi
movq -0xb8(%rbp), %rsi
movq %rax, %rdx
callq 0x9100
movq -0xb0(%rbp), %rdi
movq -0xa8(%rbp), %rsi
movq %rax, %rdx
callq 0x9100
movq %rax, -0x8(%rbp)
jmp 0x807e
cmpl $0x28, -0x1c(%rbp)
jne 0x805c
movq -0x18(%rbp), %rdi
callq 0x74d0
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x7af0
movq %rax, -0x8(%rbp)
jmp 0x807e
movq 0x5f7d(%rip), %rax      # 0xdfe0
movq (%rax), %rdi
leaq 0x2c34(%rip), %rsi      # 0xaca1
movb $0x0, %al
callq 0x1200
movl $0x1, %edi
callq 0x11a0
movq -0x8(%rbp), %rax
addq $0xc0, %rsp
popq %rbp
retq
nopl (%rax,%rax)