// File: /workspace/github_cpp_makefile_star2_O2/havluj[P]spreadsheet/src/CExpressionParser.cpp
// Function: CExpressionParser::Tokenize(std::__cxx11::list<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
void CExpressionParser::Tokenize(std::list<std::string>& tokens,
	  const std::string& delimiter) {
    // Insert whitepaces before and after each special characters
    size_t size = sizeof (charSet) / sizeof (std::string);

    for (int i = 0; i < static_cast<int> (size); i++) {
	  std::string s = charSet[i];
	  ReplaceAll(m_strInput, s, " " + s + " ");
    }

    size_t next_pos = 0;
    size_t init_pos = m_strInput.find_first_not_of(delimiter, next_pos);

    while (next_pos != std::string::npos &&
		init_pos != std::string::npos) {
	  // Get next delimiter position    
	  next_pos = m_strInput.find(delimiter, init_pos);

	  std::string token = m_strInput.substr(init_pos, next_pos - init_pos);
	  tokens.push_back(token);

	  init_pos = m_strInput.find_first_not_of(delimiter, next_pos);
    }

    // Deal with start token being a minus sign
    std::string firstToken = tokens.front();
    if (firstToken == "-") {
	  std::list<std::string>::iterator it = tokens.begin();
	  it++;

	  if (it == tokens.end()) {
		return;
	  }

	  std::string nextToken = *(it);

	  if (IsNumber(nextToken) || IsFloat(nextToken)) {
		tokens.pop_front();
		tokens.front() = firstToken + nextToken;
	  } else if (nextToken == "(" || IsFunction(nextToken)) {
		tokens.front() = firstToken + "1";
		tokens.insert(it, "*");
	  }// minus minus is a plus
	  else if (nextToken == "-" && firstToken == "-") {
		std::list<std::string>::iterator nit = it;
		std::advance(nit, -1);
		tokens.erase(it);
		tokens.erase(nit);
	  }
    }

    // Deal with minus sign after opening parenthesis or operator
    typedef std::list<std::string>::iterator t_iter;
    std::string prevToken = "";
    for (t_iter it = tokens.begin(); it != std::prev(tokens.end()); it++) {
	  std::string token = *it;

	  std::list<std::string>::iterator nit = it;
	  std::advance(nit, 1);

	  if (nit == tokens.end()) {
		break;
	  }

	  std::string ntoken = *nit;

	  if (token == "-" && prevToken == "(") {
		if (IsNumber(ntoken) || IsFloat(ntoken)) {
		    tokens.erase(nit);
		    *it = "-" + ntoken;
		    token = *it;
		}
	  } else if (token == "-" &&
		    (IsOperator(prevToken) || prevToken == "^" || prevToken == "%")) {
		// Minus minus becomes a plus
		if (token == "-" && prevToken == "-") {
		    std::list<std::string>::iterator nit = it;
		    std::list<std::string>::iterator nnit = nit;
		    nnit++;
		    std::advance(nit, -1);
		    tokens.erase(it);
		    //tokens.erase( nit );
		    *nit = "+";

		    std::list<std::string>::iterator pnit = nit;
		    std::advance(pnit, -1);

		    if (IsOperator(*pnit) || *pnit == "(") {
			  tokens.erase(nit);
		    }

		    token = *nnit;
		    it = nnit;

		    if (it == std::prev(tokens.end())) {
			  break;
		    }
		} else if (IsNumber(ntoken) || IsFloat(ntoken) || IsFunction(ntoken)) {
		    bool exit = false;
		    if (nit == std::prev(tokens.end())) {
			  exit = true;
		    }

		    tokens.erase(nit);
		    *it = "-" + ntoken;
		    token = *it;

		    if (exit) break;
		} else if (ntoken == "(") {
		    *it = "-1";
		    token = *it;
		    tokens.insert(nit, "*");
		}
	  }

	  prevToken = token;
    }

    // Deal with minus sign before opening parenthesis
    prevToken = "";
    t_iter prevIt;

    for (t_iter it = tokens.begin(); it != tokens.end(); it++) {
	  std::string token = *it;

	  if (token == "(" && prevToken == "-") {
		tokens.insert(it, "1");
		tokens.insert(it, "*");
	  }

	  prevToken = token;
	  prevIt = it;
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rdx, 0xc0(%rsp)
movq %rsi, 0x8(%rsp)
movq %rdi, %r15
xorl %r12d, %r12d
leaq 0xa0(%rsp), %rbx
leaq 0x3a44(%rip), %r14      # 0xd853
leaq 0x40(%rsp), %rbp
cmpq $0x120, %r12            # imm = 0x120
je 0x9e85
leaq 0x9b5c(%rip), %rax      # 0x13980
leaq (%rax,%r12), %rsi
movq %rbx, %rdi
callq 0x4440
leaq 0x10(%rsp), %r13
movq %r13, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0xb4bc
movq %rbp, %rdi
movq %r13, %rsi
movq %r14, %r13
movq %r14, %rdx
callq 0xb49d
movq %r15, %rsi
movq %rbx, %rdx
movq %rbp, %rcx
callq 0xa5f0
movq %rbp, %rdi
callq 0x4150
leaq 0x10(%rsp), %rdi
callq 0x4150
movq %rbx, %rdi
callq 0x4150
addq $0x20, %r12
movq %r13, %r14
jmp 0x9e14
xorl %r12d, %r12d
movq %r15, %rdi
movq 0xc0(%rsp), %r14
movq %r14, %rsi
xorl %edx, %edx
callq 0x42c0
movq %rax, %r13
leaq 0xa0(%rsp), %rbx
movq 0x8(%rsp), %rbp
cmpq $-0x1, %r13
je 0x9f04
cmpq $-0x1, %r12
je 0x9f04
movq %r15, %rdi
movq %r14, %rsi
movq %r13, %rdx
callq 0x4650
movq %rax, %r12
movq %rax, %rcx
subq %r13, %rcx
movq %rbx, %rdi
movq %r15, %rsi
movq %r13, %rdx
callq 0x4330
movq %rbp, %rdi
movq %rbx, %rsi
callq 0xb532
movq %r15, %rdi
movq %r14, %rsi
movq %r12, %rdx
callq 0x42c0
movq %rax, %r13
movq %rbx, %rdi
callq 0x4150
jmp 0x9ead
movq (%rbp), %rsi
addq $0x10, %rsi
leaq 0xa0(%rsp), %rbx
movq %rbx, %rdi
callq 0x4440
leaq 0x30e7(%rip), %rsi      # 0xd00a
movq %rbx, %rdi
callq 0xb473
testb %al, %al
je 0x9fb7
movq (%rbp), %rax
movq (%rax), %r14
cmpq %rbp, %r14
je 0xa445
leaq 0x10(%r14), %rsi
leaq 0x40(%rsp), %rdi
callq 0x4440
leaq 0x40(%rsp), %rdi
callq 0x9c9f
testb %al, %al
jne 0x9f71
leaq 0x40(%rsp), %rdi
callq 0x9c2a
testb %al, %al
je 0xa464
movq %rbp, %rdi
callq 0xb53e
leaq 0x10(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
leaq 0x40(%rsp), %rdx
callq 0xb546
movq (%rbp), %rdi
addq $0x10, %rdi
leaq 0x10(%rsp), %rbx
movq %rbx, %rsi
callq 0x43b0
movq %rbx, %rdi
callq 0x4150
leaq 0x40(%rsp), %rdi
callq 0x4150
leaq 0x3896(%rip), %rsi      # 0xd854
leaq 0x40(%rsp), %rdi
leaq 0x10(%rsp), %rdx
callq 0x5138
pushq $0x1
popq %r15
movq %rbp, %rbx
movq (%rbx), %r12
movq %rbp, %rdi
movq %r15, %rsi
callq 0xb5c4
cmpq %rax, %r12
je 0xa35f
leaq 0x10(%r12), %r14
leaq 0x10(%rsp), %rdi
movq %r14, %rsi
callq 0x4440
movq %r12, 0x30(%rsp)
leaq 0x30(%rsp), %rdi
movq %r15, %rsi
callq 0xb676
movq 0x30(%rsp), %rsi
cmpq %rbp, %rsi
leaq 0x40(%rsp), %rbx
je 0xa355
addq $0x10, %rsi
leaq 0x60(%rsp), %rdi
callq 0x4440
leaq 0x10(%rsp), %rdi
leaq 0x2fce(%rip), %rsi      # 0xd00a
callq 0xb473
testb %al, %al
je 0xa0cc
movq %rbx, %rdi
leaq 0x2fb1(%rip), %rsi      # 0xd004
callq 0xb473
testb %al, %al
je 0xa0cc
leaq 0x60(%rsp), %rdi
callq 0x9c9f
testb %al, %al
jne 0xa07c
leaq 0x60(%rsp), %rdi
callq 0x9c2a
testb %al, %al
je 0xa29f
movq 0x30(%rsp), %rsi
movq 0x8(%rsp), %rdi
callq 0xb5b6
leaq 0x80(%rsp), %rbx
movq %rbx, %rdi
leaq 0x2f6d(%rip), %rsi      # 0xd00a
leaq 0x60(%rsp), %rdx
callq 0xb4bc
movq %r14, %rdi
movq %rbx, %rsi
callq 0x43b0
movq %rbx, %rdi
callq 0x4150
leaq 0x10(%rsp), %rdi
movq %r14, %rsi
callq 0x41b0
jmp 0xa29f
leaq 0x10(%rsp), %rdi
leaq 0x2f32(%rip), %rsi      # 0xd00a
callq 0xb473
testb %al, %al
je 0xa29f
movq %rbx, %rdi
callq 0x9980
testb %al, %al
jne 0xa11b
movq %rbx, %rdi
leaq 0x32da(%rip), %rsi      # 0xd3d5
callq 0xb473
testb %al, %al
jne 0xa11b
movq %rbx, %rdi
leaq 0x2ef8(%rip), %rsi      # 0xd006
callq 0xb473
testb %al, %al
je 0xa29f
leaq 0x10(%rsp), %rdi
leaq 0x2ee3(%rip), %rsi      # 0xd00a
callq 0xb473
testb %al, %al
je 0xa20d
movq %rbx, %rdi
leaq 0x2ecc(%rip), %rsi      # 0xd00a
callq 0xb473
testb %al, %al
je 0xa20d
movq %r12, 0x80(%rsp)
movq (%r12), %rbx
leaq 0x80(%rsp), %rdi
pushq $-0x1
popq %r14
movq %r14, %rsi
callq 0xb676
movq %rbp, %rdi
movq %r12, %rsi
callq 0xb5b6
movq 0x80(%rsp), %rdi
addq $0x10, %rdi
leaq 0x2e7f(%rip), %rsi      # 0xd008
callq 0x4610
movq 0x80(%rsp), %rax
movq %rax, 0x38(%rsp)
leaq 0x38(%rsp), %rdi
movq %r14, %rsi
callq 0xb676
movq 0x38(%rsp), %rdi
addq $0x10, %rdi
callq 0x9980
testb %al, %al
jne 0xa1d3
movq 0x38(%rsp), %rdi
addq $0x10, %rdi
leaq 0x2e3a(%rip), %rsi      # 0xd004
callq 0xb473
testb %al, %al
je 0xa1e3
movq 0x80(%rsp), %rsi
movq %rbp, %rdi
callq 0xb5b6
leaq 0x10(%rbx), %rsi
leaq 0x10(%rsp), %rdi
callq 0x41b0
movq %rbp, %rdi
movq %r15, %rsi
callq 0xb5c4
cmpq %rax, %rbx
je 0xa2e2
movq %rbx, %r12
jmp 0xa29f
leaq 0x60(%rsp), %rdi
callq 0x9c9f
testb %al, %al
jne 0xa23b
leaq 0x60(%rsp), %rdi
callq 0x9c2a
testb %al, %al
jne 0xa23b
leaq 0x60(%rsp), %rdi
callq 0x9af9
testb %al, %al
je 0xa2e6
movq %r15, %rsi
movq 0x8(%rsp), %r13
movq %r13, %rdi
callq 0xb5c4
movq %rax, %rbx
movq 0x30(%rsp), %rbp
movq %r13, %rdi
movq %rbp, %rsi
callq 0xb5b6
leaq 0x80(%rsp), %r13
movq %r13, %rdi
leaq 0x2d9a(%rip), %rsi      # 0xd00a
leaq 0x60(%rsp), %rdx
callq 0xb4bc
movq %r14, %rdi
movq %r13, %rsi
callq 0x43b0
movq %r13, %rdi
callq 0x4150
leaq 0x10(%rsp), %rdi
movq %r14, %rsi
callq 0x41b0
cmpq %rbx, %rbp
je 0xa2db
movb $0x1, %bpl
leaq 0x40(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x41b0
movq %r12, %rbx
leaq 0x60(%rsp), %rdi
callq 0x4150
leaq 0x10(%rsp), %rdi
callq 0x4150
testb %bpl, %bpl
movq 0x8(%rsp), %rbp
jne 0x9fd4
jmp 0xa35f
xorl %ebp, %ebp
movq %r12, %rbx
jmp 0xa2b4
xorl %ebp, %ebp
jmp 0xa2b4
leaq 0x60(%rsp), %rdi
leaq 0x2d12(%rip), %rsi      # 0xd004
callq 0xb473
testb %al, %al
je 0xa29f
movq %r14, %rdi
leaq 0x35f0(%rip), %rsi      # 0xd8f5
callq 0x4610
leaq 0x10(%rsp), %rdi
movq %r14, %rsi
callq 0x41b0
movq 0x30(%rsp), %rbx
leaq 0x80(%rsp), %r14
movq %r14, %rdi
leaq 0x2cde(%rip), %rsi      # 0xd00c
leaq 0x38(%rsp), %rdx
callq 0x5138
movq 0x8(%rsp), %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0xb928
movq %r14, %rdi
callq 0x4150
jmp 0xa29f
leaq 0x10(%rsp), %rdi
callq 0x4150
leaq 0x34ee(%rip), %rsi      # 0xd854
leaq 0x40(%rsp), %rdi
callq 0x4610
leaq 0x10(%rsp), %r14
leaq 0x2c88(%rip), %r15      # 0xd004
leaq 0x40(%rsp), %r13
leaq 0x60(%rsp), %rbp
leaq 0x80(%rsp), %r12
movq 0x8(%rsp), %rbx
movq (%rbx), %rbx
cmpq 0x8(%rsp), %rbx
je 0xa43b
leaq 0x10(%rbx), %rsi
movq %r14, %rdi
callq 0x4440
movq %r14, %rdi
movq %r15, %rsi
callq 0xb473
testb %al, %al
je 0xa423
movq %r13, %rdi
leaq 0x2c44(%rip), %rsi      # 0xd00a
callq 0xb473
testb %al, %al
je 0xa423
movq %rbp, %rdi
leaq 0x351d(%rip), %rsi      # 0xd8f6
movq %r12, %rdx
callq 0x5138
movq 0x8(%rsp), %rdi
movq %rbx, %rsi
movq %rbp, %rdx
callq 0xb928
movq %rbp, %rdi
callq 0x4150
movq %rbp, %rdi
leaq 0x2c09(%rip), %rsi      # 0xd00c
movq %r12, %rdx
callq 0x5138
movq 0x8(%rsp), %rdi
movq %rbx, %rsi
movq %rbp, %rdx
callq 0xb928
movq %rbp, %rdi
callq 0x4150
movq %r13, %rdi
movq %r14, %rsi
callq 0x41b0
movq %r14, %rdi
callq 0x4150
jmp 0xa393
leaq 0x40(%rsp), %rdi
callq 0x4150
leaq 0xa0(%rsp), %rdi
callq 0x4150
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2b99(%rip), %rsi      # 0xd004
leaq 0x40(%rsp), %rdi
callq 0xb473
testb %al, %al
jne 0xa487
leaq 0x40(%rsp), %rdi
callq 0x9af9
testb %al, %al
je 0xa4ed
leaq 0x3468(%rip), %rdx      # 0xd8f6
leaq 0x10(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0xb57e
movq (%rbp), %rdi
addq $0x10, %rdi
leaq 0x10(%rsp), %rbx
movq %rbx, %rsi
callq 0x43b0
movq %rbx, %rdi
callq 0x4150
leaq 0x2b48(%rip), %rsi      # 0xd00c
leaq 0x10(%rsp), %rdi
leaq 0x60(%rsp), %rdx
callq 0x5138
leaq 0x10(%rsp), %rdx
movq %rbp, %rdi
movq %r14, %rsi
callq 0xb928
leaq 0x10(%rsp), %rdi
jmp 0x9fa8
leaq 0x2b16(%rip), %rsi      # 0xd00a
leaq 0x40(%rsp), %rdi
callq 0xb473
testb %al, %al
je 0x9fad
leaq 0x2afd(%rip), %rsi      # 0xd00a
leaq 0xa0(%rsp), %rdi
callq 0xb473
testb %al, %al
je 0x9fad
leaq 0x10(%rsp), %rbx
movq %r14, (%rbx)
pushq $-0x1
popq %rsi
movq %rbx, %rdi
callq 0xb676
movq %rbp, %rdi
movq %r14, %rsi
callq 0xb5b6
movq (%rbx), %rsi
movq %rbp, %rdi
callq 0xb5b6
jmp 0x9fad
jmp 0xa5a4
jmp 0xa59f
jmp 0xa59f
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0x4150
jmp 0xa593
jmp 0xa590
jmp 0xa59f
jmp 0xa5ba
jmp 0xa59f
jmp 0xa590
jmp 0xa590
jmp 0xa590
jmp 0xa59f
jmp 0xa5ba
jmp 0xa590
jmp 0xa590
jmp 0xa590
jmp 0xa590
jmp 0xa590
jmp 0xa5a4
jmp 0xa590
jmp 0xa5a4
jmp 0xa5a4
jmp 0xa59f
jmp 0xa59f
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x4150
jmp 0xa5a7
movq %rax, %rbx
jmp 0xa5b1
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x4150
leaq 0x40(%rsp), %rdi
jmp 0xa5d6
jmp 0xa5ba
movq %rax, %rbx
jmp 0xa5db
movq %rax, %rbx
jmp 0xa5d1
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x4150
leaq 0x10(%rsp), %rdi
callq 0x4150
leaq 0xa0(%rsp), %rdi
callq 0x4150
movq %rbx, %rdi
callq 0x4590