// File: Mespyr[P]bop-lisp/src/parser.cpp
// Function: parse(TokenList)
AST parse(TokenList tokens) 
{
    AST ast;
    Reader reader{tokens};

    if ((int) tokens.token_stream.size() == 0) 
    {
        ast.error = ParsingError{"Unexpected EOF while parsing."};
        ast.error.empty_stream = true;
        ast.error_found = true;
        return ast;
    }

    while(!reader.eof) 
    {
        Node node = read_next(reader);
        if (reader.error_found) 
        {
            ast.error_found = true;
            ast.error = reader.error;
            break;
        } 
        else if (node.type == ATOM) 
        {
            ast.error_found = true;
            ast.error = ParsingError{"Unexpected '" + node.atom.token.value + "' token found while parsing.", node.atom.token};
            break;
        }
        ast.nodes.push_back(node);
    }
    return ast;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x210, %rsp            # imm = 0x210
movq %rsi, -0x1e0(%rbp)
movq %rdi, -0x1f0(%rbp)
movq %rdi, %rax
movq %rax, -0x1e8(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movb $0x0, -0x11(%rbp)
callq 0x1a260
movq -0x1e0(%rbp), %rsi
leaq -0x90(%rbp), %rdi
callq 0x17830
jmp 0x19c29
movl $0x0, -0x78(%rbp)
movb $0x0, -0x74(%rbp)
leaq -0x90(%rbp), %rdi
addq $0x20, %rdi
movq %rdi, -0x1f8(%rbp)
callq 0x3450
movq -0x1f8(%rbp), %rdi
addq $0x20, %rdi
movl $0x0, -0x50(%rbp)
addq $0x8, %rdi
callq 0x3450
movq -0x1e0(%rbp), %rdi
movb $0x0, -0x28(%rbp)
movb $0x0, -0x20(%rbp)
callq 0x17aa0
cmpl $0x0, %eax
jne 0x19d62
leaq -0xf1(%rbp), %rdi
movq %rdi, -0x200(%rbp)
callq 0x3520
movq -0x200(%rbp), %rdx
leaq 0x31bf(%rip), %rsi      # 0x1ce63
leaq -0xf0(%rbp), %rdi
callq 0x3df0
jmp 0x19cb2
leaq -0xf0(%rbp), %rdi
addq $0x20, %rdi
movl $0x0, -0xd0(%rbp)
addq $0x8, %rdi
callq 0x3450
movq -0x1f0(%rbp), %rdi
movb $0x0, -0xa8(%rbp)
addq $0x20, %rdi
leaq -0xf0(%rbp), %rsi
callq 0x1a0f0
leaq -0xf0(%rbp), %rdi
callq 0x18c10
leaq -0xf1(%rbp), %rdi
callq 0x3370
movq -0x1f0(%rbp), %rax
movb $0x1, 0x68(%rax)
movb $0x1, 0x18(%rax)
movb $0x1, -0x11(%rbp)
movl $0x1, -0xf8(%rbp)
jmp 0x19f35
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x19f73
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
leaq -0xf1(%rbp), %rdi
callq 0x3370
jmp 0x19f49
jmp 0x19d64
movb -0x74(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x19d72
jmp 0x19f27
leaq -0x168(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x19480
jmp 0x19d87
testb $0x1, -0x20(%rbp)
je 0x19de4
movq -0x1f0(%rbp), %rdi
movb $0x1, 0x18(%rdi)
leaq -0x70(%rbp), %rsi
addq $0x20, %rdi
callq 0x1a290
jmp 0x19da7
movl $0x3, -0xf8(%rbp)
jmp 0x19efa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x19f49
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x19f19
cmpl $0x1, -0x168(%rbp)
jne 0x19ed9
movq -0x1f0(%rbp), %rax
movb $0x1, 0x18(%rax)
leaq -0x1b8(%rbp), %rax
movq %rax, -0x208(%rbp)
leaq -0x118(%rbp), %rdx
leaq 0x3093(%rip), %rsi      # 0x1ceab
leaq -0x1d8(%rbp), %rdi
callq 0x13e70
jmp 0x19e26
movq -0x208(%rbp), %rdi
leaq 0x305a(%rip), %rdx      # 0x1ce8e
leaq -0x1d8(%rbp), %rsi
callq 0x8970
jmp 0x19e42
leaq -0x198(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0x15530
jmp 0x19e57
movq -0x1f0(%rbp), %rdi
movb $0x0, -0x170(%rbp)
addq $0x20, %rdi
leaq -0x1b8(%rbp), %rsi
callq 0x1a0f0
leaq -0x1b8(%rbp), %rdi
callq 0x18c10
leaq -0x1d8(%rbp), %rdi
callq 0x3210
movl $0x3, -0xf8(%rbp)
jmp 0x19efa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x19ecb
movq -0x208(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
callq 0x3210
leaq -0x1d8(%rbp), %rdi
callq 0x3210
jmp 0x19f19
jmp 0x19edb
movq -0x1f0(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x1a2e0
jmp 0x19ef0
movl $0x0, -0xf8(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x141d0
movl -0xf8(%rbp), %eax
testl %eax, %eax
je 0x19f14
jmp 0x19f12
jmp 0x19f27
jmp 0x19d64
leaq -0x168(%rbp), %rdi
callq 0x141d0
jmp 0x19f49
movb $0x1, -0x11(%rbp)
movl $0x1, -0xf8(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x1a350
testb $0x1, -0x11(%rbp)
jne 0x19f63
jmp 0x19f57
leaq -0x90(%rbp), %rdi
callq 0x1a350
jmp 0x19f73
movq -0x1f0(%rbp), %rdi
callq 0x17980
movq -0x1e8(%rbp), %rax
addq $0x210, %rsp            # imm = 0x210
popq %rbp
retq
movq -0x1f0(%rbp), %rdi
callq 0x17980
movq -0x98(%rbp), %rdi
callq 0x3510
nopl (%rax,%rax)