// File: /workspace/github_c_makefile_star2_O2/theandrew168[P]squeaky/src/reader.c
// Function: read_symbol
struct value*
read_symbol(struct vm* vm, FILE* fp)
{
    // temp buffer to hold the symbol's contents
    char buf[MAX_STRING_SIZE] = { 0 };
    long i = 0;

    // grab the first character
    int c = advance(fp);
    buf[i++] = c;

    // check for peculiar identifier
    if (is_peculiar_identifier(c)) {
        if (c == '+' || c == '-') {
            peek_expect_delimiter(fp);
            return vm_make_symbol(vm, buf);
        }

        // only other peculiar identifier left at this point is "..."
        buf[i++] = advance(fp);
        buf[i++] = advance(fp);
        if (strcmp(buf, "...") == 0) {
            peek_expect_delimiter(fp);
            return vm_make_symbol(vm, buf);
        }

        fprintf(stderr, "reader: invalid symbol: %s\n", buf);
        exit(EXIT_FAILURE);
    }

    // at this point, the first char in buf must be an 'initial'

    // read characters into the buffer until:
    // EOF is reached, non-subsequent char is read, or buffer is filled
    while ((c = advance(fp)) != EOF) {
        if (!is_subsequent(c)) break;

        // "- 2" here to account for terminator
        if (i >= MAX_SYMBOL_SIZE - 2) {
            fprintf(stderr, "reader: symbol larger than %d characters\n", MAX_SYMBOL_SIZE);
            exit(EXIT_FAILURE);
        }

        buf[i++] = c;
    }

    // put non-symbol char back and ensure it was a delimiter
    rollback(fp, c);
    peek_expect_delimiter(fp);
    return vm_make_symbol(vm, buf);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x118, %rsp            # imm = 0x118
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x10(%rsp), %r15
movl $0x100, %edx            # imm = 0x100
movq %r15, %rdi
xorl %esi, %esi
callq 0x10d0
movq %r14, %rdi
callq 0x1240
movb %al, (%r15)
cmpb $0x2e, %al
ja 0x5cd2
movzbl %al, %ecx
movabsq $0x680000000000, %rdx   # imm = 0x680000000000
btq %rcx, %rdx
jae 0x5cd2
cmpl $0x2b, %eax
je 0x5d45
cmpl $0x2d, %eax
je 0x5d45
movq %r14, %rdi
callq 0x1240
movb %al, 0x11(%rsp)
movq %r14, %rdi
callq 0x1240
movb %al, 0x12(%rsp)
cmpl $0x2e2e2e, 0x10(%rsp)   # imm = 0x2E2E2E
je 0x5d45
movq 0x6329(%rip), %rax      # 0xbfe0
movq (%rax), %rdi
leaq 0x1e06(%rip), %rsi      # 0x7ac7
leaq 0x10(%rsp), %rdx
xorl %eax, %eax
callq 0x1220
jmp 0x5d89
movq %rbx, 0x8(%rsp)
pushq $0x1
popq %rbx
leaq 0x1f4b(%rip), %r15      # 0x7c2c
pushq $0x5
popq %r12
movq %r14, %rdi
callq 0x1240
movl %eax, %ebp
cmpl $-0x1, %eax
je 0x5d36
movsbl %bpl, %r13d
movl %r13d, %edi
callq 0x610d
addb $-0x30, %r13b
cmpb $0xa, %r13b
setb %cl
orb %al, %cl
jne 0x5d23
movsbl %bpl, %esi
movq %r15, %rdi
movq %r12, %rdx
callq 0x1170
testq %rax, %rax
je 0x5d36
cmpq $0xfe, %rbx
je 0x5d6c
movb %bpl, 0x10(%rsp,%rbx)
incq %rbx
jmp 0x5ce5
movl %ebp, %edi
movq %r14, %rsi
callq 0x1090
movq 0x8(%rsp), %rbx
movq %r14, %rdi
callq 0x5a59
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
callq 0x6875
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x626d(%rip), %rax      # 0xbfe0
movq (%rax), %rdi
leaq 0x1d66(%rip), %rsi      # 0x7ae3
movl $0x100, %edx            # imm = 0x100
xorl %eax, %eax
callq 0x1220
pushq $0x1
popq %rdi
callq 0x11b0