// File: BlinfoldKing[P]lisval/src/lib/parser.cpp
// Function: Parser::parse()
Token* Parser::parse() {
	vector<State> state;
	Token* res = NULL;

	vector<Token*> list_stack;
	for (size_t i = 0; i < this->str.length(); i++) {
        /* debugState(state); */
		List* new_token_list = new List();
		new_token_list->type = TokenType::LIST;

        if (state.size() > 0 && state.back() == State::COMMENT) {
            if (this->str[i] == '\n') state.pop_back();
        } else if(this->str[i] == '#') {
            state.push_back(State::COMMENT);
        } else if (this->str[i] == '(') {
			state.push_back(State::LIST_START);
		} else if (this->str[i] == ')') {
			string newItem = "";
			while(state.size() && state.back() != State::LIST_START) {
				if (state.back() == State::CHAR) {
					newItem = this->parse_stack.back() + newItem;
					this->parse_stack.pop_back();
				} else {
					if (newItem != "") {
						Token* new_token = createSingularToken(newItem);
						new_token_list->list.push_back(new_token);

						newItem = "";
					}

					if (state.back() == State::LIST_TOKEN) {
						new_token_list->list.push_back(list_stack.back());
						list_stack.pop_back();
					} else {
						this->parse_stack.pop_back();
					}
				}

				state.pop_back();
			}

			if (newItem != "") {
				Token* new_token = createSingularToken(newItem);
				new_token_list->list.push_back(new_token);
			}

			reverse(new_token_list->list.begin(), new_token_list->list.end());

			state.pop_back();
			state.push_back(State::LIST_TOKEN);
			list_stack.push_back(new_token_list);
		} else if (this->str[i] == ' ' || this->str[i] == '\t') {
            if (state.size() < 1 || state.back() != State::SPACE) {
				this->parse_stack.push_back(this->str[i]);
				state.push_back(State::SPACE);
			}
		} else if (this->str[i] == '\n') {
            continue;
        } else {
			state.push_back(State::CHAR);
			this->parse_stack.push_back(this->str[i]);
		}

	}

	if (state.size() > 0 && state.back() == State::LIST_TOKEN) {
		res = list_stack.back();
		list_stack.pop_back();
		state.pop_back();
	}

	return res;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1e0, %rsp            # imm = 0x1E0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x130(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x18d90
movq $0x0, -0x28(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x11ca0
movq $0x0, -0x48(%rbp)
movq -0x130(%rbp), %rdi
movq -0x48(%rbp), %rax
movq %rax, -0x138(%rbp)
addq $0x18, %rdi
callq 0x33f0
movq %rax, %rcx
movq -0x138(%rbp), %rax
cmpq %rcx, %rax
jae 0x17891
movl $0x20, %edi
callq 0x32b0
movq %rax, -0x140(%rbp)
jmp 0x1723d
movq -0x140(%rbp), %rdi
callq 0x11870
jmp 0x1724b
movq -0x140(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movl $0x1, (%rax)
leaq -0x20(%rbp), %rdi
callq 0x18d50
cmpq $0x0, %rax
jbe 0x172ec
leaq -0x20(%rbp), %rdi
callq 0x18db0
cmpl $0x4, (%rax)
jne 0x172ec
movq -0x130(%rbp), %rdi
addq $0x18, %rdi
movq -0x48(%rbp), %rsi
callq 0x3500
movq %rax, -0x148(%rbp)
jmp 0x1729a
movq -0x148(%rbp), %rax
movsbl (%rax), %eax
cmpl $0xa, %eax
jne 0x172e7
leaq -0x20(%rbp), %rdi
callq 0x18df0
jmp 0x172e7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x178fd
movq -0x140(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
movl $0x20, %esi
callq 0x32c0
jmp 0x178fd
jmp 0x1787e
movq -0x130(%rbp), %rdi
addq $0x18, %rdi
movq -0x48(%rbp), %rsi
callq 0x3500
movq %rax, -0x150(%rbp)
jmp 0x17309
movq -0x150(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x23, %eax
jne 0x17333
movl $0x4, -0x60(%rbp)
leaq -0x20(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x18e20
jmp 0x1732e
jmp 0x1787c
movq -0x130(%rbp), %rdi
addq $0x18, %rdi
movq -0x48(%rbp), %rsi
callq 0x3500
movq %rax, -0x158(%rbp)
jmp 0x17350
movq -0x158(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x28, %eax
jne 0x1737a
movl $0x1, -0x64(%rbp)
leaq -0x20(%rbp), %rdi
leaq -0x64(%rbp), %rsi
callq 0x18e20
jmp 0x17375
jmp 0x1787a
movq -0x130(%rbp), %rdi
addq $0x18, %rdi
movq -0x48(%rbp), %rsi
callq 0x3500
movq %rax, -0x160(%rbp)
jmp 0x17397
movq -0x160(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x29, %eax
jne 0x17718
leaq -0x89(%rbp), %rdi
movq %rdi, -0x168(%rbp)
callq 0x34a0
movq -0x168(%rbp), %rdx
leaq 0xc28c(%rip), %rsi      # 0x23657
leaq -0x88(%rbp), %rdi
callq 0x33b0
jmp 0x173d9
leaq -0x89(%rbp), %rdi
callq 0x3300
leaq -0x20(%rbp), %rdi
callq 0x18d50
movq %rax, %rcx
xorl %eax, %eax
cmpq $0x0, %rcx
movb %al, -0x169(%rbp)
je 0x17414
leaq -0x20(%rbp), %rdi
callq 0x18db0
cmpl $0x1, (%rax)
setne %al
movb %al, -0x169(%rbp)
movb -0x169(%rbp), %al
testb $0x1, %al
jne 0x17423
jmp 0x175cd
leaq -0x20(%rbp), %rdi
callq 0x18db0
cmpl $0x0, (%rax)
jne 0x174b7
movq -0x130(%rbp), %rdi
callq 0x18f50
movsbl (%rax), %esi
leaq -0xb0(%rbp), %rdi
leaq -0x88(%rbp), %rdx
callq 0x18e50
jmp 0x17459
leaq -0x88(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x3340
leaq -0xb0(%rbp), %rdi
callq 0x31c0
movq -0x130(%rbp), %rdi
callq 0x18f90
jmp 0x175bf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x89(%rbp), %rdi
callq 0x3300
jmp 0x178fd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x17707
leaq 0xc199(%rip), %rsi      # 0x23657
leaq -0x88(%rbp), %rdi
callq 0x18fc0
movb %al, -0x16a(%rbp)
jmp 0x174d2
movb -0x16a(%rbp), %al
testb $0x1, %al
jne 0x174e1
jmp 0x1756f
leaq -0xd8(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x3140
jmp 0x174f6
leaq -0xd8(%rbp), %rdi
callq 0x16940
movq %rax, -0x178(%rbp)
jmp 0x1750b
leaq -0xd8(%rbp), %rdi
callq 0x31c0
movq -0x178(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0x50(%rbp), %rdi
addq $0x8, %rdi
leaq -0xb8(%rbp), %rsi
callq 0x118b0
jmp 0x1753b
leaq 0xc115(%rip), %rsi      # 0x23657
leaq -0x88(%rbp), %rdi
callq 0x33a0
jmp 0x17550
jmp 0x1756f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x31c0
jmp 0x17707
leaq -0x20(%rbp), %rdi
callq 0x18db0
cmpl $0x2, (%rax)
jne 0x175b1
movq -0x50(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x180(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x18ff0
movq -0x180(%rbp), %rdi
movq %rax, %rsi
callq 0x118b0
jmp 0x175a6
leaq -0x40(%rbp), %rdi
callq 0x12020
jmp 0x175bd
movq -0x130(%rbp), %rdi
callq 0x18f90
jmp 0x175bf
leaq -0x20(%rbp), %rdi
callq 0x18df0
jmp 0x173e5
leaq 0xc083(%rip), %rsi      # 0x23657
leaq -0x88(%rbp), %rdi
callq 0x18fc0
movb %al, -0x181(%rbp)
jmp 0x175e8
movb -0x181(%rbp), %al
testb $0x1, %al
jne 0x175f4
jmp 0x1766d
leaq -0x100(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x3140
jmp 0x17609
leaq -0x100(%rbp), %rdi
callq 0x16940
movq %rax, -0x190(%rbp)
jmp 0x1761e
leaq -0x100(%rbp), %rdi
callq 0x31c0
movq -0x190(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0x50(%rbp), %rdi
addq $0x8, %rdi
leaq -0xe0(%rbp), %rsi
callq 0x118b0
jmp 0x1764e
jmp 0x1766d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x31c0
jmp 0x17707
movq -0x50(%rbp), %rdi
addq $0x8, %rdi
callq 0x12870
movq %rax, -0x108(%rbp)
movq -0x50(%rbp), %rdi
addq $0x8, %rdi
callq 0x12700
movq %rax, -0x110(%rbp)
movq -0x108(%rbp), %rdi
movq -0x110(%rbp), %rsi
callq 0x19030
jmp 0x176aa
leaq -0x20(%rbp), %rdi
movq %rdi, -0x198(%rbp)
callq 0x18df0
movq -0x198(%rbp), %rdi
movl $0x2, -0x114(%rbp)
leaq -0x114(%rbp), %rsi
callq 0x18e20
jmp 0x176d9
movq -0x50(%rbp), %rax
movq %rax, -0x120(%rbp)
leaq -0x40(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0x11bf0
jmp 0x176f6
leaq -0x88(%rbp), %rdi
callq 0x31c0
jmp 0x17878
leaq -0x88(%rbp), %rdi
callq 0x31c0
jmp 0x178fd
movq -0x130(%rbp), %rdi
addq $0x18, %rdi
movq -0x48(%rbp), %rsi
callq 0x3500
movq %rax, -0x1a0(%rbp)
jmp 0x17735
movq -0x1a0(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x20, %eax
je 0x17770
movq -0x130(%rbp), %rdi
addq $0x18, %rdi
movq -0x48(%rbp), %rsi
callq 0x3500
movq %rax, -0x1a8(%rbp)
jmp 0x17761
movq -0x1a8(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x9, %eax
jne 0x177ec
leaq -0x20(%rbp), %rdi
callq 0x18d50
cmpq $0x1, %rax
jb 0x1778d
leaq -0x20(%rbp), %rdi
callq 0x18db0
cmpl $0x3, (%rax)
je 0x177e7
movq -0x130(%rbp), %rdi
movq %rdi, %rax
movq %rax, -0x1b8(%rbp)
addq $0x18, %rdi
movq -0x48(%rbp), %rsi
callq 0x3500
movq %rax, -0x1b0(%rbp)
jmp 0x177b4
movq -0x1b0(%rbp), %rsi
movq -0x1b8(%rbp), %rdi
callq 0x19070
jmp 0x177c9
movl $0x3, -0x124(%rbp)
leaq -0x20(%rbp), %rdi
leaq -0x124(%rbp), %rsi
callq 0x18e20
jmp 0x177e5
jmp 0x177e7
jmp 0x17876
movq -0x130(%rbp), %rdi
addq $0x18, %rdi
movq -0x48(%rbp), %rsi
callq 0x3500
movq %rax, -0x1c0(%rbp)
jmp 0x17809
movq -0x1c0(%rbp), %rax
movsbl (%rax), %eax
cmpl $0xa, %eax
jne 0x1781a
jmp 0x17880
movl $0x0, -0x128(%rbp)
leaq -0x20(%rbp), %rdi
leaq -0x128(%rbp), %rsi
callq 0x18e20
jmp 0x17836
movq -0x130(%rbp), %rdi
movq %rdi, %rax
movq %rax, -0x1d0(%rbp)
addq $0x18, %rdi
movq -0x48(%rbp), %rsi
callq 0x3500
movq %rax, -0x1c8(%rbp)
jmp 0x1785d
movq -0x1c8(%rbp), %rsi
movq -0x1d0(%rbp), %rdi
callq 0x19070
jmp 0x17872
jmp 0x17874
jmp 0x17876
jmp 0x17878
jmp 0x1787a
jmp 0x1787c
jmp 0x1787e
jmp 0x17880
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x171fc
leaq -0x20(%rbp), %rdi
callq 0x18d50
cmpq $0x0, %rax
jbe 0x178d0
leaq -0x20(%rbp), %rdi
callq 0x18db0
cmpl $0x2, (%rax)
jne 0x178d0
leaq -0x40(%rbp), %rdi
callq 0x18ff0
movq (%rax), %rax
movq %rax, -0x28(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x12020
leaq -0x20(%rbp), %rdi
callq 0x18df0
movq -0x28(%rbp), %rax
movq %rax, -0x1d8(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x3ef0
leaq -0x20(%rbp), %rdi
callq 0x190e0
movq -0x1d8(%rbp), %rax
addq $0x1e0, %rsp            # imm = 0x1E0
popq %rbp
retq
leaq -0x40(%rbp), %rdi
callq 0x3ef0
leaq -0x20(%rbp), %rdi
callq 0x190e0
movq -0x58(%rbp), %rdi
callq 0x3490
nopl (%rax,%rax)