// File: /workspace/github_cpp_makefile_star2_O3/ajuc[P]c--_lisp_sexp_parser/lispparser.cpp
// Function: AjucLispParser::parse(std::istream&, int&, bool)
std::shared_ptr< Expression> parse(std::istream& input, int& line_no, bool topLevel) {
	std::string buffer("");
	char c;
	
	while (input.good()) {
		input.get(c);
		if (whitespace(c)) {
			if (c == '\n') {
				line_no++;
			}
			if (buffer.empty()) {
				;//nothing to do
			} else {
				if (digit(buffer[0])) {
					return std::make_shared<Float>(buffer);
				} else if (doubleQuote(buffer[0])) {
					buffer += c;
				} else if (colon(buffer[0])) {
					return std::make_shared<Atom>(buffer.substr(1));
				} else if (alphanumeric(buffer[0])) {
					return std::make_shared<Identifier>(buffer);
				//} else {
				//	return new Identifier(buffer);
				}
			}
		} else if (digit(c)) {
			buffer += c;
		} else if (dot(c)) {
			if (buffer.empty()) {
				buffer += c;
			} else {
				if (digit(buffer[0])) {
					if (!dotIn(buffer)) {
						buffer += c;
					} else {
						SYNTAX_ERROR(line_no, "Second dot found in Float literal " << buffer + c );
					}
				} else {
					buffer += c;
				}
			}
		} else if (colon(c)) {
			if (buffer.empty()) {
				buffer += c;
			} else {
				SYNTAX_ERROR(line_no, "Colon found in the middle of token " << buffer + c );
			}
		} else if (doubleQuote(c)) {
			if (buffer.empty()) {
				buffer += c;
			} else {
				if (doubleQuote(buffer[0])) {
					buffer += c;
					return std::make_shared<String>(buffer);
				} else {
					SYNTAX_ERROR(line_no, "Double-quote found in the middle of token " << buffer + c );
				}
			}
		} else if (parenthenesis(c)) { //BEWARE - THE TRICKY PART //TODO refactor to smaller functions
			if (buffer.empty()) {
				if (openParenthenesis(c)) {
					std::vector< std::shared_ptr<Expression>> list;
					char c2;
					input.get(c2);
					while (!closeParenthenesis(c2)) {
						input.unget();
						std::shared_ptr<Expression> tmpExp = parse(input, line_no, false);
						if (tmpExp) {
						    list.push_back(tmpExp);
						} else {
						    input.unget();
						}
						input.get(c2);
					}
					if (!parenMatches(c, c2)) {
						SYNTAX_ERROR(line_no, "Parenthenesis " << c << " is closed by not matching paren : " << c2);
					}
					return std::make_shared<List>(list);
				} else {//closeParenthenesis(c)
					if (topLevel) {
					    SYNTAX_ERROR(line_no, "Found unmatched close parenthenesis " << c);
					} else {
					    return NULL;//oznacza, ze trzeba wyjsc
					}
				}
			} else {
				//end of some token
				//return c back to the ctream and return expression as a result
				//or possibly it was ending paren inside a string and we add it simply
                          
				if (digit(buffer[0])) {
					input.unget();
					return std::make_shared<Float>(buffer);
				} else if (doubleQuote(buffer[0])) {
					buffer += c; //no unget, cause it's inside a string literal
                                } else if (colon(buffer[0])) {
					input.unget();
					return std::make_shared<Atom>(buffer);
				} else if (alphanumeric(buffer[0])) {
					input.unget();
					return std::make_shared<Identifier>(buffer);
				}  else {
					SYNTAX_ERROR(line_no, "Situation impossible : buffer == " << buffer);
				}
			}
		} else if (alphanumeric(c)) {
			if (buffer.empty()) {
				buffer += c;
			} else {
				if (!digit(buffer[0])) {
					buffer += c;
				} else {
					SYNTAX_ERROR(line_no, "Non-digit found in the middle of Float literal " << buffer + c );
				}
			}
		} else {
			SYNTAX_ERROR(line_no, "Unrecognised char " << c);
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movl %ecx, -0x94(%rbp)
movq %rdx, -0x58(%rbp)
movq %rsi, %r15
movq %rdi, -0x90(%rbp)
leaq -0x78(%rbp), %rax
movq %rax, -0x10(%rax)
leaq 0x216b(%rip), %rdx      # 0x6008
leaq -0x88(%rbp), %rdi
movq %rdx, %rsi
callq 0x4bde
leaq -0x29(%rbp), %r12
movabsq $0x100100000600, %rbx   # imm = 0x100100000600
movq %r15, %rdi
movq %r12, %rsi
callq 0x31e0
movb -0x29(%rbp), %r14b
movzbl %r14b, %r13d
cmpl $0x1f, %r13d
jg 0x3ee7
cmpl $0x9, %r13d
je 0x3ef3
cmpl $0xa, %r13d
jne 0x3f3e
movq -0x58(%rbp), %rax
incl (%rax)
jmp 0x3ef3
cmpl $0x20, %r13d
je 0x3ef3
cmpl $0x2c, %r13d
jne 0x3f3e
cmpq $0x0, -0x80(%rbp)
je 0x3eba
movq -0x88(%rbp), %rax
movzbl (%rax), %eax
leal -0x30(%rax), %ecx
cmpb $0x9, %cl
jbe 0x40ad
cmpl $0x3a, %eax
ja 0x3f2d
movl %eax, %ecx
btq %rcx, %rbx
jb 0x3eba
cmpq $0x22, %rcx
je 0x3f46
cmpq $0x3a, %rcx
je 0x410a
movsbl %al, %edi
callq 0x3d71
testb %al, %al
jne 0x3eba
jmp 0x417e
leal -0x30(%r14), %eax
cmpb $0xa, %al
jae 0x3f5b
movsbl %r14b, %esi
leaq -0x88(%rbp), %rdi
callq 0x3140
jmp 0x3eba
cmpl $0x22, %r13d
je 0x3fbf
cmpl $0x3a, %r13d
je 0x3fb0
cmpl $0x2e, %r13d
jne 0x3fd2
movb $0x2e, %r14b
cmpq $0x0, -0x80(%rbp)
je 0x3f46
movq -0x88(%rbp), %rax
movb (%rax), %al
addb $-0x30, %al
cmpb $0x9, %al
ja 0x3f46
movl $0x1, %ecx
leaq -0x88(%rbp), %rdi
leaq 0x2076(%rip), %rsi      # 0x600f
xorl %edx, %edx
callq 0x3270
cmpq $-0x1, %rax
jne 0x4527
movb -0x29(%rbp), %r14b
jmp 0x3f46
movb $0x3a, %r14b
cmpq $0x0, -0x80(%rbp)
je 0x3f46
jmp 0x44bc
movb $0x22, %r14b
cmpq $0x0, -0x80(%rbp)
je 0x3f46
jmp 0x41a3
movsbl %r14b, %edi
callq 0x3d71
testb %al, %al
je 0x400e
cmpq $0x0, -0x80(%rbp)
je 0x4239
movq -0x88(%rbp), %rax
movzbl (%rax), %eax
leal -0x30(%rax), %ecx
cmpb $0x9, %cl
jbe 0x42ec
cmpl $0x22, %eax
je 0x3f46
jmp 0x41f0
cmpl $0x2c, %r13d
ja 0x4021
movl %r13d, %eax
btq %rax, %rbx
jb 0x43ff
cmpq $0x0, -0x80(%rbp)
je 0x3f46
movq -0x88(%rbp), %rax
movb (%rax), %al
addb $-0x30, %al
cmpb $0x9, %al
ja 0x3f46
movq -0x58(%rbp), %rax
movl (%rax), %esi
movq 0x4fa4(%rip), %rdi      # 0x8ff0
callq 0x3260
movq %rax, %rbx
leaq 0x2058(%rip), %rsi      # 0x60b3
movl $0x2, %edx
movq %rax, %rdi
callq 0x31a0
leaq 0x208e(%rip), %rsi      # 0x60fd
movl $0x2f, %edx
movq %rbx, %rdi
callq 0x31a0
movsbl -0x29(%rbp), %edx
leaq -0x50(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x4a8d
movq -0x50(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq %rbx, %rdi
callq 0x31a0
movq %rax, %rdi
callq 0x30c0
jmp 0x4590
leaq -0x48(%rbp), %rdi
movq $0x0, -0x8(%rdi)
leaq -0x50(%rbp), %rsi
leaq -0x68(%rbp), %rdx
leaq -0x88(%rbp), %rcx
callq 0x4d4a
movq -0x50(%rbp), %rax
movq -0x90(%rbp), %rbx
movq %rax, (%rbx)
movq -0x48(%rbp), %rax
movq %rax, 0x8(%rbx)
leaq -0x78(%rbp), %rax
movq -0x88(%rbp), %rdi
cmpq %rax, %rdi
je 0x40f8
callq 0x3160
movq %rbx, %rax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq -0x50(%rbp), %rdi
leaq -0x88(%rbp), %rsi
movl $0x1, %edx
movq $-0x1, %rcx
callq 0x3190
movq -0x90(%rbp), %rbx
leaq -0x60(%rbp), %rdi
movq $0x0, -0x8(%rdi)
leaq -0x68(%rbp), %rsi
leaq -0x2b(%rbp), %rdx
leaq -0x50(%rbp), %rcx
callq 0x4e34
movq -0x68(%rbp), %rax
movq %rax, (%rbx)
movq -0x60(%rbp), %rax
xorl %ecx, %ecx
movq %rcx, -0x60(%rbp)
movq %rax, 0x8(%rbx)
movq %rcx, -0x68(%rbp)
leaq -0x40(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x40e3
callq 0x3160
jmp 0x40e3
leaq -0x48(%rbp), %rdi
movq $0x0, -0x8(%rdi)
leaq -0x50(%rbp), %rsi
leaq -0x68(%rbp), %rdx
leaq -0x88(%rbp), %rcx
callq 0x4f1e
jmp 0x40cd
movq -0x88(%rbp), %rax
cmpb $0x22, (%rax)
movq -0x90(%rbp), %rbx
jne 0x45a3
leaq -0x88(%rbp), %rdi
movl $0x22, %esi
callq 0x3140
leaq -0x48(%rbp), %rdi
movq $0x0, -0x8(%rdi)
leaq -0x50(%rbp), %rsi
leaq -0x68(%rbp), %rdx
leaq -0x88(%rbp), %rcx
callq 0x5008
jmp 0x43d7
cmpl $0x3a, %eax
ja 0x4398
movl %eax, %ecx
cmpq $0x3a, %rcx
jne 0x438e
movq %r15, %rdi
callq 0x3060
movq -0x90(%rbp), %rbx
leaq -0x48(%rbp), %rdi
movq $0x0, -0x8(%rdi)
leaq -0x50(%rbp), %rsi
leaq -0x68(%rbp), %rdx
leaq -0x88(%rbp), %rcx
callq 0x5444
jmp 0x43d7
cmpl $0x28, %r13d
je 0x424f
cmpl $0x7b, %r13d
je 0x424f
cmpl $0x5b, %r13d
jne 0x43e0
xorps %xmm0, %xmm0
movaps %xmm0, -0x50(%rbp)
movq $0x0, -0x40(%rbp)
leaq -0x2a(%rbp), %rsi
movq %r15, %rdi
callq 0x31e0
movq -0x90(%rbp), %rbx
leaq -0x68(%rbp), %r12
leaq -0x2a(%rbp), %r13
leaq -0x50(%rbp), %r14
movzbl -0x2a(%rbp), %eax
cmpl $0x29, %eax
je 0x4320
cmpl $0x5d, %eax
je 0x4320
cmpl $0x7d, %eax
je 0x4320
movq %r15, %rdi
callq 0x3060
movq %r12, %rdi
movq %r15, %rsi
movq -0x58(%rbp), %rdx
xorl %ecx, %ecx
callq 0x3e69
cmpq $0x0, -0x68(%rbp)
je 0x42c9
movq %r14, %rdi
movq %r12, %rsi
callq 0x4af2
jmp 0x42d1
movq %r15, %rdi
callq 0x3060
movq %r15, %rdi
movq %r13, %rsi
callq 0x31e0
movq -0x60(%rbp), %rdi
testq %rdi, %rdi
je 0x427d
callq 0x35ac
jmp 0x427d
movq %r15, %rdi
callq 0x3060
movq -0x90(%rbp), %rbx
leaq -0x48(%rbp), %rdi
movq $0x0, -0x8(%rdi)
leaq -0x50(%rbp), %rsi
leaq -0x68(%rbp), %rdx
leaq -0x88(%rbp), %rcx
callq 0x4d4a
jmp 0x43d7
movb -0x29(%rbp), %cl
movl %ecx, %edx
xorb $0x28, %dl
movl %eax, %esi
xorb $0x29, %sil
orb %dl, %sil
je 0x4354
movl %ecx, %edx
xorb $0x5b, %dl
movl %eax, %esi
xorb $0x5d, %sil
orb %dl, %sil
je 0x4354
cmpb $0x7d, %al
jne 0x466e
cmpb $0x7b, %cl
jne 0x466e
leaq -0x60(%rbp), %rdi
movq $0x0, -0x8(%rdi)
leaq -0x68(%rbp), %rsi
leaq -0x2b(%rbp), %rdx
leaq -0x50(%rbp), %rcx
callq 0x5260
movq -0x68(%rbp), %rax
movq %rax, (%rbx)
movq -0x60(%rbp), %rax
movq %rax, 0x8(%rbx)
leaq -0x50(%rbp), %rdi
callq 0x49da
jmp 0x40e3
btq %rcx, %rbx
jb 0x445f
movsbl %al, %edi
callq 0x3d71
testb %al, %al
jne 0x445f
movq %r15, %rdi
callq 0x3060
movq -0x90(%rbp), %rbx
leaq -0x48(%rbp), %rdi
movq $0x0, -0x8(%rdi)
leaq -0x50(%rbp), %rsi
leaq -0x68(%rbp), %rdx
leaq -0x88(%rbp), %rcx
callq 0x4f1e
movq -0x50(%rbp), %rax
jmp 0x40d8
cmpb $0x0, -0x94(%rbp)
movq -0x90(%rbp), %rbx
jne 0x460e
xorps %xmm0, %xmm0
movups %xmm0, (%rbx)
jmp 0x40e3
movq -0x58(%rbp), %rax
movl (%rax), %esi
movq 0x4be4(%rip), %rdi      # 0x8ff0
callq 0x3260
movq %rax, %rbx
leaq 0x1c98(%rip), %rsi      # 0x60b3
movl $0x2, %edx
movq %rax, %rdi
callq 0x31a0
leaq 0x1cfe(%rip), %rsi      # 0x612d
movl $0x12, %edx
movq %rbx, %rdi
callq 0x31a0
movb -0x29(%rbp), %al
leaq -0x50(%rbp), %rsi
movb %al, (%rsi)
movl $0x1, %edx
movq %rbx, %rdi
callq 0x31a0
movq %rax, %rdi
callq 0x30c0
jmp 0x4599
movq -0x58(%rbp), %rax
movl (%rax), %esi
movq 0x4b84(%rip), %rdi      # 0x8ff0
callq 0x3260
movq %rax, %rbx
leaq 0x1c38(%rip), %rsi      # 0x60b3
movl $0x2, %edx
movq %rax, %rdi
callq 0x31a0
leaq 0x1c4c(%rip), %rsi      # 0x60db
movl $0x21, %edx
movq %rbx, %rdi
callq 0x31a0
movq -0x88(%rbp), %rsi
movq -0x80(%rbp), %rdx
movq %rbx, %rdi
callq 0x31a0
movq %rax, %rdi
callq 0x30c0
jmp 0x4599
movq -0x58(%rbp), %rax
movl (%rax), %esi
movq 0x4b27(%rip), %rdi      # 0x8ff0
callq 0x3260
movq %rax, %rbx
leaq 0x1bdb(%rip), %rsi      # 0x60b3
movl $0x2, %edx
movq %rax, %rdi
callq 0x31a0
leaq 0x1b48(%rip), %rsi      # 0x6034
movl $0x23, %edx
movq %rbx, %rdi
callq 0x31a0
movsbl -0x29(%rbp), %edx
leaq -0x50(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x4a8d
movq -0x50(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq %rbx, %rdi
callq 0x31a0
movq %rax, %rdi
callq 0x30c0
jmp 0x4590
movq -0x58(%rbp), %rax
movl (%rax), %esi
movq 0x4abc(%rip), %rdi      # 0x8ff0
callq 0x3260
movq %rax, %rbx
leaq 0x1b70(%rip), %rsi      # 0x60b3
movl $0x2, %edx
movq %rax, %rdi
callq 0x31a0
leaq 0x1aba(%rip), %rsi      # 0x6011
movl $0x22, %edx
movq %rbx, %rdi
callq 0x31a0
movsbl -0x29(%rbp), %edx
leaq -0x50(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x4a8d
movq -0x50(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq %rbx, %rdi
callq 0x31a0
movq %rax, %rdi
callq 0x30c0
leaq -0x50(%rbp), %rdi
callq 0x30b0
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x31b0
movq -0x58(%rbp), %rax
movl (%rax), %esi
movq 0x4a40(%rip), %rdi      # 0x8ff0
callq 0x3260
movq %rax, %rbx
leaq 0x1af4(%rip), %rsi      # 0x60b3
movl $0x2, %edx
movq %rax, %rdi
callq 0x31a0
leaq 0x1a85(%rip), %rsi      # 0x6058
movl $0x2a, %edx
movq %rbx, %rdi
callq 0x31a0
movsbl -0x29(%rbp), %edx
leaq -0x50(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x4a8d
movq -0x50(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq %rbx, %rdi
callq 0x31a0
movq %rax, %rdi
callq 0x30c0
jmp 0x4590
movq -0x58(%rbp), %rax
movl (%rax), %esi
movq 0x49d5(%rip), %rdi      # 0x8ff0
callq 0x3260
movq %rax, %rbx
leaq 0x1a89(%rip), %rsi      # 0x60b3
movl $0x2, %edx
movq %rax, %rdi
callq 0x31a0
leaq 0x1a78(%rip), %rsi      # 0x60b6
movl $0x24, %edx
movq %rbx, %rdi
callq 0x31a0
movb -0x29(%rbp), %al
leaq -0x50(%rbp), %rsi
movb %al, (%rsi)
movl $0x1, %edx
movq %rbx, %rdi
callq 0x31a0
movq %rax, %rdi
callq 0x30c0
jmp 0x4599
movq -0x58(%rbp), %rax
movl (%rax), %esi
movq 0x4975(%rip), %rdi      # 0x8ff0
callq 0x3260
movq %rax, %rbx
leaq 0x1a29(%rip), %rsi      # 0x60b3
movl $0x2, %edx
movq %rax, %rdi
callq 0x31a0
leaq 0x19e5(%rip), %rsi      # 0x6083
movl $0xe, %edx
movq %rbx, %rdi
callq 0x31a0
movb -0x29(%rbp), %al
leaq -0x68(%rbp), %rsi
movb %al, (%rsi)
movl $0x1, %edx
movq %rbx, %rdi
callq 0x31a0
movq %rax, %rbx
leaq 0x19c7(%rip), %rsi      # 0x6092
movl $0x23, %edx
movq %rax, %rdi
callq 0x31a0
movb -0x2a(%rbp), %al
leaq -0x68(%rbp), %rsi
movb %al, (%rsi)
movl $0x1, %edx
movq %rbx, %rdi
callq 0x31a0
movq %rax, %rdi
callq 0x30c0
jmp 0x4599
jmp 0x4719
jmp 0x4759
jmp 0x4734
jmp 0x4759
jmp 0x4759
jmp 0x4734
jmp 0x4719
jmp 0x4719
jmp 0x4759
jmp 0x4759
jmp 0x4759
jmp 0x4759
jmp 0x4719
jmp 0x4759
jmp 0x4759
movq %rax, %rbx
leaq -0x40(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x475c
callq 0x3160
jmp 0x475c
jmp 0x4759
jmp 0x4734
movq %rax, %rbx
jmp 0x474a
movq %rax, %rbx
movq -0x60(%rbp), %rdi
testq %rdi, %rdi
je 0x474a
callq 0x35ac
leaq -0x50(%rbp), %rdi
callq 0x49da
jmp 0x475c
jmp 0x4759
jmp 0x4759
movq %rax, %rbx
movq -0x88(%rbp), %rdi
leaq -0x78(%rbp), %rax
cmpq %rax, %rdi
je 0x4771
callq 0x3160
movq %rbx, %rdi
callq 0x3280