// File: Mespyr[P]bop-lisp/src/parser.cpp
// Function: read_next(Reader&)
Node read_next(Reader& reader) 
{
    Token token = reader.next();


    // Detect EOF and raise error
    if (reader.eof == true) 
    {
        reader.error = ParsingError{"Unexpected EOF while parsing.", token};
        reader.error_found = true;
        return Node{ATOM};
    }

    if (token.value == "(") 
    {
        Node node{LIST};
        token = reader.peek();
        while (token.value != ")")
        {
            node.nodes.push_back(read_next(reader));
            if (reader.eof == true) 
            {
                reader.error = ParsingError{"Unexpected EOF while parsing.", token};
                reader.error_found = true;
                return node;
            }
            token = reader.peek();
        }
        reader.next();
        return node;
    } 
    else if (token.value == ")") 
    {
        reader.error = ParsingError{"Unexpected ')' token found while parsing.", token};
        reader.error_found = true;
        return Node{ATOM};
    } 

    Node node{ATOM};
    node.atom = create_atom(token);
    return node;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x330, %rsp            # imm = 0x330
movq %rdi, -0x2c8(%rbp)
movq %rdi, %rax
movq %rax, -0x2c0(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rsi
leaq -0x38(%rbp), %rdi
callq 0x1a070
movq -0x10(%rbp), %rax
movb 0x1c(%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x19613
leaq -0x88(%rbp), %rax
movq %rax, -0x2d8(%rbp)
leaq -0x89(%rbp), %rdi
movq %rdi, -0x2d0(%rbp)
callq 0x3520
movq -0x2d8(%rbp), %rdi
movq -0x2d0(%rbp), %rdx
leaq 0x3967(%rip), %rsi      # 0x1ce63
callq 0x3df0
jmp 0x19503
leaq -0x68(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x15530
jmp 0x19512
movb $0x0, -0x40(%rbp)
movq -0x10(%rbp), %rdi
addq $0x20, %rdi
leaq -0x88(%rbp), %rsi
callq 0x1a0f0
leaq -0x88(%rbp), %rdi
callq 0x18c10
leaq -0x89(%rbp), %rdi
callq 0x3370
movq -0x2c8(%rbp), %rdi
movq -0x10(%rbp), %rax
movb $0x1, 0x70(%rax)
movl $0x1, (%rdi)
addq $0x8, %rdi
movq %rdi, -0x2e8(%rbp)
xorl %esi, %esi
movl $0x18, %edx
callq 0x31d0
movq -0x2e8(%rbp), %rdi
callq 0x1a140
movq -0x2c8(%rbp), %rdi
addq $0x20, %rdi
movq %rdi, -0x2e0(%rbp)
callq 0x3450
movq -0x2e0(%rbp), %rdi
movq -0x2c8(%rbp), %rax
movl $0x0, 0x40(%rax)
movl $0x0, 0x44(%rax)
addq $0x28, %rdi
movl $0x0, 0x48(%rax)
addq $0x8, %rdi
callq 0x3450
movl $0x1, -0xa0(%rbp)
jmp 0x19bad
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x19602
movq -0x2d8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
callq 0x3210
leaq -0x89(%rbp), %rdi
callq 0x3370
jmp 0x19bc6
leaq -0x30(%rbp), %rdi
leaq 0x3843(%rip), %rsi      # 0x1ce61
callq 0x140d0
movb %al, -0x2e9(%rbp)
jmp 0x1962b
movb -0x2e9(%rbp), %al
testb $0x1, %al
jne 0x1963a
jmp 0x1990b
movq -0x2c8(%rbp), %rax
movb $0x0, -0xa1(%rbp)
movl $0x0, (%rax)
movq %rax, %rdi
addq $0x8, %rdi
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rax)
movq $0x0, 0x18(%rax)
callq 0x1a140
movq -0x2c8(%rbp), %rdi
addq $0x20, %rdi
callq 0x3450
movq -0x2c8(%rbp), %rdi
movl $0x0, 0x40(%rdi)
movl $0x0, 0x44(%rdi)
movl $0x0, 0x48(%rdi)
addq $0x50, %rdi
callq 0x3450
movq -0x10(%rbp), %rsi
leaq -0xd0(%rbp), %rdi
callq 0x1a160
jmp 0x196b0
leaq -0x38(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x1a1a0
leaq -0xd0(%rbp), %rdi
callq 0x15570
leaq -0x30(%rbp), %rdi
leaq 0x3661(%rip), %rsi      # 0x1cd38
callq 0x14840
movb %al, -0x2ea(%rbp)
jmp 0x196e4
movb -0x2ea(%rbp), %al
testb $0x1, %al
jne 0x196f3
jmp 0x198b1
movq -0x2c8(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x2f8(%rbp)
movq -0x10(%rbp), %rsi
leaq -0x140(%rbp), %rdi
callq 0x19480
jmp 0x19717
movq -0x2f8(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0x1a1e0
jmp 0x1972c
leaq -0x140(%rbp), %rdi
callq 0x141d0
movq -0x10(%rbp), %rax
movb 0x1c(%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x1987e
leaq -0x190(%rbp), %rax
movq %rax, -0x308(%rbp)
leaq -0x191(%rbp), %rdi
movq %rdi, -0x300(%rbp)
callq 0x3520
movq -0x308(%rbp), %rdi
movq -0x300(%rbp), %rdx
leaq 0x36e0(%rip), %rsi      # 0x1ce63
callq 0x3df0
jmp 0x1978a
leaq -0x170(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x15530
jmp 0x1979c
movb $0x0, -0x148(%rbp)
movq -0x10(%rbp), %rdi
addq $0x20, %rdi
leaq -0x190(%rbp), %rsi
callq 0x1a0f0
leaq -0x190(%rbp), %rdi
callq 0x18c10
leaq -0x191(%rbp), %rdi
callq 0x3370
movq -0x10(%rbp), %rax
movb $0x1, 0x70(%rax)
movb $0x1, -0xa1(%rbp)
movl $0x1, -0xa0(%rbp)
jmp 0x198e0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x19bc6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x198fa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x141d0
jmp 0x198fa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x19870
movq -0x308(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
callq 0x3210
leaq -0x191(%rbp), %rdi
callq 0x3370
jmp 0x198fa
movq -0x10(%rbp), %rsi
leaq -0x1c0(%rbp), %rdi
callq 0x1a160
jmp 0x19890
leaq -0x38(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
callq 0x1a1a0
leaq -0x1c0(%rbp), %rdi
callq 0x15570
jmp 0x196cc
movq -0x10(%rbp), %rsi
leaq -0x1e8(%rbp), %rdi
callq 0x1a070
jmp 0x198c3
leaq -0x1e8(%rbp), %rdi
callq 0x15570
movb $0x1, -0xa1(%rbp)
movl $0x1, -0xa0(%rbp)
testb $0x1, -0xa1(%rbp)
jne 0x198f5
movq -0x2c8(%rbp), %rdi
callq 0x141d0
jmp 0x19bad
movq -0x2c8(%rbp), %rdi
callq 0x141d0
jmp 0x19bc6
leaq -0x30(%rbp), %rdi
leaq 0x3422(%rip), %rsi      # 0x1cd38
callq 0x140d0
movb %al, -0x309(%rbp)
jmp 0x19923
movb -0x309(%rbp), %al
testb $0x1, %al
jne 0x19932
jmp 0x19a85
leaq -0x238(%rbp), %rax
movq %rax, -0x320(%rbp)
leaq -0x239(%rbp), %rdi
movq %rdi, -0x318(%rbp)
callq 0x3520
movq -0x320(%rbp), %rdi
movq -0x318(%rbp), %rdx
leaq 0x3519(%rip), %rsi      # 0x1ce81
callq 0x3df0
jmp 0x1996f
leaq -0x218(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x15530
jmp 0x19981
movb $0x0, -0x1f0(%rbp)
movq -0x10(%rbp), %rdi
addq $0x20, %rdi
leaq -0x238(%rbp), %rsi
callq 0x1a0f0
leaq -0x238(%rbp), %rdi
callq 0x18c10
leaq -0x239(%rbp), %rdi
callq 0x3370
movq -0x2c8(%rbp), %rdi
movq -0x10(%rbp), %rax
movb $0x1, 0x70(%rax)
movl $0x1, (%rdi)
addq $0x8, %rdi
movq %rdi, -0x330(%rbp)
xorl %esi, %esi
movl $0x18, %edx
callq 0x31d0
movq -0x330(%rbp), %rdi
callq 0x1a140
movq -0x2c8(%rbp), %rdi
addq $0x20, %rdi
movq %rdi, -0x328(%rbp)
callq 0x3450
movq -0x328(%rbp), %rdi
movq -0x2c8(%rbp), %rax
movl $0x0, 0x40(%rax)
movl $0x0, 0x44(%rax)
addq $0x28, %rdi
movl $0x0, 0x48(%rax)
addq $0x8, %rdi
callq 0x3450
movl $0x1, -0xa0(%rbp)
jmp 0x19bad
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x19a74
movq -0x320(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
callq 0x3210
leaq -0x239(%rbp), %rdi
callq 0x3370
jmp 0x19bc6
jmp 0x19a87
movq -0x2c8(%rbp), %rax
movb $0x0, -0x23a(%rbp)
movl $0x1, (%rax)
movq %rax, %rdi
addq $0x8, %rdi
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rax)
movq $0x0, 0x18(%rax)
callq 0x1a140
movq -0x2c8(%rbp), %rdi
addq $0x20, %rdi
callq 0x3450
movq -0x2c8(%rbp), %rdi
movl $0x0, 0x40(%rdi)
movl $0x0, 0x44(%rdi)
movl $0x0, 0x48(%rdi)
addq $0x50, %rdi
callq 0x3450
leaq -0x2b8(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x15530
jmp 0x19afd
leaq -0x290(%rbp), %rdi
leaq -0x2b8(%rbp), %rsi
callq 0x19380
jmp 0x19b12
movq -0x2c8(%rbp), %rdi
addq $0x20, %rdi
leaq -0x290(%rbp), %rsi
callq 0x1a210
leaq -0x290(%rbp), %rdi
callq 0x140a0
leaq -0x2b8(%rbp), %rdi
callq 0x15570
movb $0x1, -0x23a(%rbp)
movl $0x1, -0xa0(%rbp)
testb $0x1, -0x23a(%rbp)
jne 0x19b9d
jmp 0x19b91
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x19b9f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
leaq -0x2b8(%rbp), %rdi
callq 0x15570
jmp 0x19b9f
movq -0x2c8(%rbp), %rdi
callq 0x141d0
jmp 0x19bad
movq -0x2c8(%rbp), %rdi
callq 0x141d0
jmp 0x19bc6
leaq -0x38(%rbp), %rdi
callq 0x15570
movq -0x2c0(%rbp), %rax
addq $0x330, %rsp            # imm = 0x330
popq %rbp
retq
leaq -0x38(%rbp), %rdi
callq 0x15570
movq -0x98(%rbp), %rdi
callq 0x3510
nopl (%rax,%rax)