// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
xorps %xmm0, %xmm0
leaq -0x40(%rbp), %rax
movaps %xmm0, (%rax)
andq $0x0, 0x10(%rax)
leaq -0x98(%rbp), %rax
movaps %xmm0, -0x8(%rax)
andq $0x0, 0x8(%rax)
movq %rdi, -0x48(%rbp)
leaq 0x8(%rdi), %rax
movq %rax, -0x80(%rbp)
xorl %r12d, %r12d
leaq -0x78(%rbp), %r14
leaq -0xc0(%rbp), %rbx
leaq -0x100(%rbp), %r13
leaq -0xe0(%rbp), %r15
movq -0x48(%rbp), %rax
cmpq 0x20(%rax), %r12
jae 0x9163
pushq $0x20
popq %rdi
callq 0x3200
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rax)
andq $0x0, 0x18(%rax)
movq %rax, -0x58(%rbp)
movl $0x1, (%rax)
movq -0x40(%rbp), %rcx
movq -0x38(%rbp), %rax
cmpq %rcx, %rax
je 0x8ed0
cmpl $0x4, -0x4(%rax)
movq -0x48(%rbp), %rdx
movq 0x18(%rdx), %rsi
jne 0x8ed8
cmpb $0xa, (%rsi,%r12)
jne 0x915b
addq $-0x4, %rax
movq %rax, -0x38(%rbp)
jmp 0x915b
movq -0x48(%rbp), %rdx
movq 0x18(%rdx), %rsi
movzbl (%rsi,%r12), %edx
leal -0x20(%rdx), %edi
cmpl $0x9, %edi
ja 0x8f0d
leaq 0x3524(%rip), %r8       # 0xc410
movslq (%r8,%rdi,4), %rdx
addq %r8, %rdx
jmpq *%rdx
movl $0x4, -0x78(%rbp)
leaq -0x40(%rbp), %rdi
movq %r14, %rsi
callq 0xb730
jmp 0x915b
cmpl $0x9, %edx
je 0x8f40
cmpl $0xa, %edx
je 0x915b
andl $0x0, -0x78(%rbp)
leaq -0x40(%rbp), %rdi
movq %r14, %rsi
callq 0xb730
movq -0x48(%rbp), %rdi
movq 0x18(%rdi), %rsi
addq %r12, %rsi
callq 0x9ad2
jmp 0x915b
cmpq %rcx, %rax
je 0x8f4f
cmpl $0x3, -0x4(%rax)
je 0x915b
addq %r12, %rsi
movq -0x48(%rbp), %rdi
callq 0x9ad2
movl $0x3, -0x78(%rbp)
leaq -0x40(%rbp), %rdi
movq %r14, %rsi
callq 0xb730
jmp 0x915b
movq %r14, %rdi
leaq 0x3605(%rip), %rsi      # 0xc582
movq %rbx, %rdx
callq 0x3100
movq -0x58(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x50(%rbp)
movq -0x38(%rbp), %rax
cmpq -0x40(%rbp), %rax
je 0x90b8
movl -0x4(%rax), %eax
testl %eax, %eax
je 0x903e
cmpl $0x1, %eax
je 0x90b8
leaq -0x78(%rbp), %rdi
leaq 0x35c4(%rip), %rsi      # 0xc582
callq 0x9ac4
testb %al, %al
je 0x900d
movq %r15, %rdi
leaq -0x78(%rbp), %rsi
callq 0x3290
movq %r15, %rdi
callq 0x8a15
movq %rax, %r14
movq %r15, %rdi
callq 0x3140
movq %r14, -0xc0(%rbp)
movq -0x50(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x74b0
leaq -0x78(%rbp), %rdi
leaq 0x357a(%rip), %rsi      # 0xc582
callq 0x3360
movq -0x38(%rbp), %rax
cmpl $0x2, -0x4(%rax)
movq -0x80(%rbp), %rax
pushq $-0x1
popq %rcx
jne 0x908c
movq -0x98(%rbp), %rsi
addq $-0x8, %rsi
movq -0x50(%rbp), %rdi
callq 0x74b0
leaq -0x98(%rbp), %rax
pushq $-0x8
popq %rcx
jmp 0x908c
movq %r13, %r15
movq %r12, %r13
movq -0x80(%rbp), %r12
movq (%r12), %rax
movsbl -0x1(%rax), %esi
leaq -0xc0(%rbp), %rbx
movq %rbx, %rdi
leaq -0x78(%rbp), %r14
movq %r14, %rdx
callq 0x9a5a
movq %r14, %rdi
movq %rbx, %rsi
callq 0x3260
movq %rbx, %rdi
callq 0x3140
movq %r12, %rax
pushq $-0x1
popq %rcx
movq %r13, %r12
movq %r15, %r13
leaq -0xe0(%rbp), %r15
addq %rcx, (%rax)
movq -0x38(%rbp), %rax
addq $-0x4, %rax
movq %rax, -0x38(%rbp)
jmp 0x8f95
movl $0x1, -0x78(%rbp)
leaq -0x40(%rbp), %rdi
movq %r14, %rsi
callq 0xb730
jmp 0x915b
leaq -0x78(%rbp), %rdi
leaq 0x34bf(%rip), %rsi      # 0xc582
callq 0x9ac4
testb %al, %al
je 0x9102
movq %r13, %rdi
leaq -0x78(%rbp), %rsi
callq 0x3290
movq %r13, %rdi
callq 0x8a15
movq %rax, %r14
movq %r13, %rdi
callq 0x3140
movq %r14, -0xc0(%rbp)
movq -0x50(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x74b0
movq -0x58(%rbp), %rax
movq 0x8(%rax), %rdi
movq 0x10(%rax), %rsi
callq 0xb8b0
addq $-0x4, -0x38(%rbp)
movl $0x2, -0xc0(%rbp)
leaq -0x40(%rbp), %rdi
leaq -0xc0(%rbp), %rbx
movq %rbx, %rsi
callq 0xb730
leaq -0x78(%rbp), %r14
movq -0x58(%rbp), %rax
movq %rax, -0xc0(%rbp)
leaq -0xa0(%rbp), %rdi
movq %rbx, %rsi
callq 0x7abc
movq %r14, %rdi
callq 0x3140
incq %r12
jmp 0x8e71
movq -0x38(%rbp), %rax
cmpq -0x40(%rbp), %rax
je 0x9193
cmpl $0x2, -0x4(%rax)
jne 0x9193
addq $-0x4, %rax
movq -0x98(%rbp), %rcx
movq -0x8(%rcx), %rbx
addq $-0x8, %rcx
movq %rcx, -0x98(%rbp)
movq %rax, -0x38(%rbp)
jmp 0x9195
xorl %ebx, %ebx
leaq -0xa0(%rbp), %rdi
callq 0x397a
leaq -0x40(%rbp), %rdi
callq 0xb6f2
movq %rbx, %rax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq -0x100(%rbp), %rdi
jmp 0x91e7
jmp 0x91f7
jmp 0x91f7
jmp 0x91f2
jmp 0x91f2
jmp 0x91f7
jmp 0x91f7
jmp 0x91f2
jmp 0x91f2
jmp 0x91f2
movq %rax, %rbx
leaq -0xe0(%rbp), %rdi
callq 0x3140
jmp 0x91fa
jmp 0x91f7
jmp 0x91f7
movq %rax, %rbx
jmp 0x9203
movq %rax, %rbx
leaq -0x78(%rbp), %rdi
callq 0x3140
leaq -0xa0(%rbp), %rdi
callq 0x397a
leaq -0x40(%rbp), %rdi
callq 0xb6f2
movq %rbx, %rdi
callq 0x3320