// File: TsukiGva2[P]Blade-lang/blade.cpp
// Function: lc_eval(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
std::string lc_eval(std::string expr){
/* 
1. detect the innermost function [x]
2. call that function            [x]
3. return to 1                   [x]
*/

	std::cout << "got: " << expr << endl;
	FnPtr tempfun = err;
	std::string temp;
	std::string ufun;
	bool userfun = false;
    
	//       f a a
	// [ + [ - 9 9] 9 ]
	//   f   arg1  arg2	

	// so, it works like this
	//-         1 1 1     1 1 1
	//  [ [ [ [ ] ] ] [ [ ] ] ]
	//+ 1 1 1 1       1 1   
	//  you do + 1 for the opening parens
	//  and - 1 for the closing ones

	int acc = 0;
	std::map<int,int> depth_index;
	std::vector<int> depths;
	std::vector<std::string> args;

	bool instr = false;
	
	for (int i = 0; i < expr.size(); i++){
		if (expr[i] == '"') instr = !instr;

		if (expr[i] == '[' && !instr) {
			acc += 1;
			depths.push_back(acc);
		}

		else if (expr[i] == ']' && !instr) {
			acc -= 1;
			depths.push_back(acc);
		}

		if (depth_index.find(acc) == depth_index.end())
			depth_index[acc] = i;
	}

	if (instr) return "SYNTAX-ERROR: no matching double quote. err-unfinished-str";

	if (acc != 0){
		return "SYNTAX-ERROR: wrong number of brackets. err-unbalanced-brackets";
	}

	int maxd_index = depth_index[max_element(depths)];
	int replace_end = 0;

	for (int i = maxd_index+1; i < expr.size(); i++){
		if (expr[i] == ']' && !instr) {
			replace_end = i+1;
		}

		if (expr[i] == '"' && !instr){
			instr = true;
			continue;
		}

		if (!((expr[i] == ' ' && !instr && expr[i-1] != '"') || (expr[i] == '"' && instr) || (expr[i] == ']' && !instr))){ // XXX
			temp += expr[i];
		} else {
			if (!instr){
				std::remove(temp.begin(), temp.end(), ' ');
			}

			if (funcs_map.find(temp) != funcs_map.end() && !instr) tempfun = funcs_map[temp];
			else if (usfuns_map.find(temp) != usfuns_map.end() && !instr){
				ufun = temp;
				userfun = true;
			} else {
				if (vars.find(temp) != vars.end() && !instr) {
					args.push_back(vars[temp]);
				} else if (!temp.empty()){
					args.push_back(temp);
				}
			}

			instr = false;
			if (expr[i] == ']' && !instr) break;
			temp = "";
		}
	}
	std::string result;
	if (!userfun) result = tempfun(args);
	else {
		globl_args = args;
		result = lc_eval(usfuns_map[ufun]);
	}

	if (max_element(depths) < 2) return result;
	
	// else
	
	return lc_eval(replace_str(expr,maxd_index,replace_end,result));
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3b0, %rsp            # imm = 0x3B0
movq %rsi, -0x288(%rbp)
movq %rdi, -0x298(%rbp)
movq %rdi, %rax
movq %rax, -0x290(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq 0x13e2ae(%rip), %rdi    # 0x156960
leaq 0xe4b10(%rip), %rsi     # 0xfd1c9
callq 0xba870
movq -0x288(%rbp), %rsi
movq %rax, %rdi
callq 0xcd2e0
movq %rax, %rdi
leaq 0xa1a79(%rip), %rsi     # 0xba150
callq 0xb9360
leaq -0x1e3(%rip), %rax      # 0x18500
movq %rax, -0x18(%rbp)
leaq -0x38(%rbp), %rdi
callq 0xcaac0
leaq -0x58(%rbp), %rdi
callq 0xcaac0
movb $0x0, -0x59(%rbp)
movl $0x0, -0x60(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x1b740
leaq -0xa8(%rbp), %rdi
callq 0x1b760
leaq -0xc0(%rbp), %rdi
callq 0x1b5f0
movb $0x0, -0xc1(%rbp)
movl $0x0, -0xc8(%rbp)
movq -0x288(%rbp), %rdi
movslq -0xc8(%rbp), %rax
movq %rax, -0x2a0(%rbp)
callq 0xcadf0
movq %rax, %rcx
movq -0x2a0(%rbp), %rax
cmpq %rcx, %rax
jae 0x188f9
movq -0x288(%rbp), %rdi
movslq -0xc8(%rbp), %rsi
callq 0xcb110
movq %rax, -0x2a8(%rbp)
jmp 0x18782
movq -0x2a8(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x22, %eax
jne 0x187ba
movb -0xc1(%rbp), %al
xorb $-0x1, %al
andb $0x1, %al
movb %al, -0xc1(%rbp)
jmp 0x187ba
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xd0(%rbp)
movl %eax, -0xd4(%rbp)
jmp 0x19279
movq -0x288(%rbp), %rdi
movslq -0xc8(%rbp), %rsi
callq 0xcb110
movq %rax, -0x2b0(%rbp)
jmp 0x187d6
movq -0x2b0(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x5b, %eax
jne 0x1880a
testb $0x1, -0xc1(%rbp)
jne 0x1880a
movl -0x60(%rbp), %eax
incl %eax
movl %eax, -0x60(%rbp)
leaq -0xa8(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x1b780
jmp 0x18808
jmp 0x1885c
movq -0x288(%rbp), %rdi
movslq -0xc8(%rbp), %rsi
callq 0xcb110
movq %rax, -0x2b8(%rbp)
jmp 0x18826
movq -0x2b8(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x5d, %eax
jne 0x1885a
testb $0x1, -0xc1(%rbp)
jne 0x1885a
movl -0x60(%rbp), %eax
decl %eax
movl %eax, -0x60(%rbp)
leaq -0xa8(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x1b780
jmp 0x18858
jmp 0x1885a
jmp 0x1885c
leaq -0x90(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x1b820
movq %rax, -0x2c0(%rbp)
jmp 0x18875
movq -0x2c0(%rbp), %rax
movq %rax, -0xe0(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x1b850
movq %rax, -0xe8(%rbp)
leaq -0xe0(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x1b7f0
testb $0x1, %al
jne 0x188af
jmp 0x188e3
movl -0xc8(%rbp), %eax
movl %eax, -0x2cc(%rbp)
leaq -0x90(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x1b880
movq %rax, -0x2c8(%rbp)
jmp 0x188d4
movq -0x2c8(%rbp), %rax
movl -0x2cc(%rbp), %ecx
movl %ecx, (%rax)
jmp 0x188e5
movl -0xc8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc8(%rbp)
jmp 0x18739
testb $0x1, -0xc1(%rbp)
je 0x1896f
leaq -0xe9(%rbp), %rdi
movq %rdi, -0x2d8(%rbp)
callq 0x505b0
movq -0x298(%rbp), %rdi
movq -0x2d8(%rbp), %rdx
leaq 0xe48a5(%rip), %rsi     # 0xfd1cf
callq 0x1b480
jmp 0x18931
leaq -0xe9(%rbp), %rdi
callq 0x505d0
movl $0x1, -0xf0(%rbp)
jmp 0x19233
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xd0(%rbp)
movl %eax, -0xd4(%rbp)
leaq -0xe9(%rbp), %rdi
callq 0x505d0
jmp 0x19279
cmpl $0x0, -0x60(%rbp)
je 0x189e2
leaq -0xf1(%rbp), %rdi
movq %rdi, -0x2e0(%rbp)
callq 0x505b0
movq -0x298(%rbp), %rdi
movq -0x2e0(%rbp), %rdx
leaq 0xe486d(%rip), %rsi     # 0xfd20a
callq 0x1b480
jmp 0x189a4
leaq -0xf1(%rbp), %rdi
callq 0x505d0
movl $0x1, -0xf0(%rbp)
jmp 0x19233
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xd0(%rbp)
movl %eax, -0xd4(%rbp)
leaq -0xf1(%rbp), %rdi
callq 0x505d0
jmp 0x19279
leaq -0x118(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x1ba40
jmp 0x189f7
leaq -0x118(%rbp), %rdi
callq 0x18480
movl %eax, -0x2e4(%rbp)
jmp 0x18a0b
movl -0x2e4(%rbp), %eax
movl %eax, -0xfc(%rbp)
leaq -0x90(%rbp), %rdi
leaq -0xfc(%rbp), %rsi
callq 0x1b960
movq %rax, -0x2f0(%rbp)
jmp 0x18a33
movq -0x2f0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x2f4(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x1bb30
movl -0x2f4(%rbp), %eax
movl %eax, -0xf8(%rbp)
movl $0x0, -0x11c(%rbp)
movl -0xf8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x120(%rbp)
movq -0x288(%rbp), %rdi
movslq -0x120(%rbp), %rax
movq %rax, -0x300(%rbp)
callq 0xcadf0
movq %rax, %rcx
movq -0x300(%rbp), %rax
cmpq %rcx, %rax
jae 0x18f22
movq -0x288(%rbp), %rdi
movslq -0x120(%rbp), %rsi
callq 0xcb110
movq %rax, -0x308(%rbp)
jmp 0x18abc
movq -0x308(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x5d, %eax
jne 0x18b08
testb $0x1, -0xc1(%rbp)
jne 0x18b08
movl -0x120(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x11c(%rbp)
jmp 0x18b08
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xd0(%rbp)
movl %eax, -0xd4(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x1bb30
jmp 0x19279
movq -0x288(%rbp), %rdi
movslq -0x120(%rbp), %rsi
callq 0xcb110
movq %rax, -0x310(%rbp)
jmp 0x18b24
movq -0x310(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x22, %eax
jne 0x18b48
testb $0x1, -0xc1(%rbp)
jne 0x18b48
movb $0x1, -0xc1(%rbp)
jmp 0x18f0e
movq -0x288(%rbp), %rdi
movslq -0x120(%rbp), %rsi
callq 0xcb110
movq %rax, -0x318(%rbp)
jmp 0x18b64
movq -0x318(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x20, %eax
jne 0x18baf
testb $0x1, -0xc1(%rbp)
jne 0x18baf
movq -0x288(%rbp), %rdi
movl -0x120(%rbp), %eax
decl %eax
movslq %eax, %rsi
callq 0xcb110
movq %rax, -0x320(%rbp)
jmp 0x18b9c
movq -0x320(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x22, %eax
jne 0x18c4d
movq -0x288(%rbp), %rdi
movslq -0x120(%rbp), %rsi
callq 0xcb110
movq %rax, -0x328(%rbp)
jmp 0x18bcb
movq -0x328(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x22, %eax
jne 0x18be3
testb $0x1, -0xc1(%rbp)
jne 0x18c4d
movq -0x288(%rbp), %rdi
movslq -0x120(%rbp), %rsi
callq 0xcb110
movq %rax, -0x330(%rbp)
jmp 0x18bff
movq -0x330(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x5d, %eax
jne 0x18c17
testb $0x1, -0xc1(%rbp)
je 0x18c4d
movq -0x288(%rbp), %rdi
movslq -0x120(%rbp), %rsi
callq 0xcb110
movq %rax, -0x338(%rbp)
jmp 0x18c33
movq -0x338(%rbp), %rax
movsbl (%rax), %esi
leaq -0x38(%rbp), %rdi
callq 0xcb1e0
jmp 0x18c48
jmp 0x18f0c
testb $0x1, -0xc1(%rbp)
jne 0x18cb8
leaq -0x38(%rbp), %rdi
movq %rdi, -0x348(%rbp)
callq 0xcad00
movq -0x348(%rbp), %rdi
movq %rax, -0x128(%rbp)
callq 0xcad20
movq %rax, -0x130(%rbp)
movb $0x20, -0x131(%rbp)
movq -0x128(%rbp), %rdi
movq -0x130(%rbp), %rsi
leaq -0x131(%rbp), %rdx
callq 0x1bb90
movq %rax, -0x340(%rbp)
jmp 0x18caa
movq -0x340(%rbp), %rax
movq %rax, -0x140(%rbp)
leaq 0x13cc31(%rip), %rdi    # 0x1558f0
leaq -0x38(%rbp), %rsi
callq 0x1bc10
movq %rax, -0x350(%rbp)
jmp 0x18cd1
movq -0x350(%rbp), %rax
movq %rax, -0x148(%rbp)
leaq 0x13cc0a(%rip), %rdi    # 0x1558f0
callq 0x1bc40
movq %rax, -0x150(%rbp)
leaq -0x148(%rbp), %rdi
leaq -0x150(%rbp), %rsi
callq 0x1bbe0
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x351(%rbp)
jne 0x18d16
jmp 0x18d24
movb -0xc1(%rbp), %al
xorb $-0x1, %al
movb %al, -0x351(%rbp)
movb -0x351(%rbp), %al
testb $0x1, %al
jne 0x18d30
jmp 0x18d5c
leaq 0x13cbb9(%rip), %rdi    # 0x1558f0
leaq -0x38(%rbp), %rsi
callq 0x1bc70
movq %rax, -0x360(%rbp)
jmp 0x18d49
movq -0x360(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
jmp 0x18ebb
leaq 0x13cbbd(%rip), %rdi    # 0x155920
leaq -0x38(%rbp), %rsi
callq 0x1bd80
movq %rax, -0x368(%rbp)
jmp 0x18d75
movq -0x368(%rbp), %rax
movq %rax, -0x158(%rbp)
leaq 0x13cb96(%rip), %rdi    # 0x155920
callq 0x1bdb0
movq %rax, -0x160(%rbp)
leaq -0x158(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x1bd50
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x369(%rbp)
jne 0x18dba
jmp 0x18dc8
movb -0xc1(%rbp), %al
xorb $-0x1, %al
movb %al, -0x369(%rbp)
movb -0x369(%rbp), %al
testb $0x1, %al
jne 0x18dd4
jmp 0x18dec
leaq -0x58(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0xcac00
jmp 0x18de3
movb $0x1, -0x59(%rbp)
jmp 0x18eb9
leaq 0x13cb75(%rip), %rdi    # 0x155968
leaq -0x38(%rbp), %rsi
callq 0x1bd80
movq %rax, -0x378(%rbp)
jmp 0x18e05
movq -0x378(%rbp), %rax
movq %rax, -0x168(%rbp)
leaq 0x13cb4e(%rip), %rdi    # 0x155968
callq 0x1bdb0
movq %rax, -0x170(%rbp)
leaq -0x168(%rbp), %rdi
leaq -0x170(%rbp), %rsi
callq 0x1bd50
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x379(%rbp)
jne 0x18e4a
jmp 0x18e58
movb -0xc1(%rbp), %al
xorb $-0x1, %al
movb %al, -0x379(%rbp)
movb -0x379(%rbp), %al
testb $0x1, %al
jne 0x18e64
jmp 0x18e94
leaq 0x13cafd(%rip), %rdi    # 0x155968
leaq -0x38(%rbp), %rsi
callq 0x1be50
movq %rax, -0x388(%rbp)
jmp 0x18e7d
movq -0x388(%rbp), %rsi
leaq -0xc0(%rbp), %rdi
callq 0x1bde0
jmp 0x18e92
jmp 0x18eb7
leaq -0x38(%rbp), %rdi
callq 0xcb0f0
testb $0x1, %al
jne 0x18eb5
leaq -0xc0(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x1bde0
jmp 0x18eb3
jmp 0x18eb5
jmp 0x18eb7
jmp 0x18eb9
jmp 0x18ebb
movq -0x288(%rbp), %rdi
movb $0x0, -0xc1(%rbp)
movslq -0x120(%rbp), %rsi
callq 0xcb110
movq %rax, -0x390(%rbp)
jmp 0x18ede
movq -0x390(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x5d, %eax
jne 0x18ef8
testb $0x1, -0xc1(%rbp)
jne 0x18ef8
jmp 0x18f22
leaq 0xe4505(%rip), %rsi     # 0xfd404
leaq -0x38(%rbp), %rdi
callq 0xcbc20
jmp 0x18f0a
jmp 0x18f0c
jmp 0x18f0e
movl -0x120(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x120(%rbp)
jmp 0x18a73
leaq -0x190(%rbp), %rdi
callq 0xcaac0
testb $0x1, -0x59(%rbp)
jne 0x18fdb
movq -0x18(%rbp), %rax
movq %rax, -0x398(%rbp)
leaq -0x1c8(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x1bf30
jmp 0x18f58
movq -0x398(%rbp), %rax
leaq -0x1b0(%rbp), %rdi
leaq -0x1c8(%rbp), %rsi
callq *%rax
jmp 0x18f71
leaq -0x190(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
callq 0xcac20
leaq -0x1b0(%rbp), %rdi
callq 0xcabd0
leaq -0x1c8(%rbp), %rdi
callq 0x1b610
jmp 0x19083
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xd0(%rbp)
movl %eax, -0xd4(%rbp)
jmp 0x19225
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xd0(%rbp)
movl %eax, -0xd4(%rbp)
leaq -0x1c8(%rbp), %rdi
callq 0x1b610
jmp 0x19225
leaq 0x13c96e(%rip), %rdi    # 0x155950
leaq -0xc0(%rbp), %rsi
callq 0x1c020
jmp 0x18ff0
leaq 0x13c929(%rip), %rdi    # 0x155920
leaq -0x58(%rbp), %rsi
callq 0x1be50
movq %rax, -0x3a0(%rbp)
jmp 0x19009
movq -0x3a0(%rbp), %rsi
leaq -0x208(%rbp), %rdi
callq 0xcd060
jmp 0x1901e
leaq -0x1e8(%rbp), %rdi
leaq -0x208(%rbp), %rsi
callq 0x18680
jmp 0x19033
leaq -0x190(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0xcac20
leaq -0x1e8(%rbp), %rdi
callq 0xcabd0
leaq -0x208(%rbp), %rdi
callq 0xcabd0
jmp 0x19083
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xd0(%rbp)
movl %eax, -0xd4(%rbp)
leaq -0x208(%rbp), %rdi
callq 0xcabd0
jmp 0x19225
leaq -0x220(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x1ba40
jmp 0x19098
leaq -0x220(%rbp), %rdi
callq 0x18480
movl %eax, -0x3a4(%rbp)
jmp 0x190ac
leaq -0x220(%rbp), %rdi
callq 0x1bb30
movl -0x3a4(%rbp), %eax
cmpl $0x2, %eax
jge 0x19108
movq -0x298(%rbp), %rdi
leaq -0x190(%rbp), %rsi
callq 0xcab20
movl $0x1, -0xf0(%rbp)
jmp 0x19217
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xd0(%rbp)
movl %eax, -0xd4(%rbp)
leaq -0x220(%rbp), %rdi
callq 0x1bb30
jmp 0x19225
movq -0x288(%rbp), %rsi
leaq -0x260(%rbp), %rdi
callq 0xcd060
jmp 0x1911d
movl -0xf8(%rbp), %eax
movl %eax, -0x3ac(%rbp)
movl -0x11c(%rbp), %eax
movl %eax, -0x3a8(%rbp)
leaq -0x280(%rbp), %rdi
leaq -0x190(%rbp), %rsi
callq 0xcd060
jmp 0x1914a
movl -0x3a8(%rbp), %ecx
movl -0x3ac(%rbp), %edx
leaq -0x240(%rbp), %rdi
leaq -0x260(%rbp), %rsi
leaq -0x280(%rbp), %r8
callq 0x18570
jmp 0x19172
movq -0x298(%rbp), %rdi
leaq -0x240(%rbp), %rsi
callq 0x18680
jmp 0x19187
leaq -0x240(%rbp), %rdi
callq 0xcabd0
leaq -0x280(%rbp), %rdi
callq 0xcabd0
leaq -0x260(%rbp), %rdi
callq 0xcabd0
movl $0x1, -0xf0(%rbp)
jmp 0x19217
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xd0(%rbp)
movl %eax, -0xd4(%rbp)
jmp 0x19209
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xd0(%rbp)
movl %eax, -0xd4(%rbp)
jmp 0x191fd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xd0(%rbp)
movl %eax, -0xd4(%rbp)
leaq -0x240(%rbp), %rdi
callq 0xcabd0
leaq -0x280(%rbp), %rdi
callq 0xcabd0
leaq -0x260(%rbp), %rdi
callq 0xcabd0
jmp 0x19225
leaq -0x190(%rbp), %rdi
callq 0xcabd0
jmp 0x19233
leaq -0x190(%rbp), %rdi
callq 0xcabd0
jmp 0x19279
leaq -0xc0(%rbp), %rdi
callq 0x1b610
leaq -0xa8(%rbp), %rdi
callq 0x1bb30
leaq -0x90(%rbp), %rdi
callq 0x1c270
leaq -0x58(%rbp), %rdi
callq 0xcabd0
leaq -0x38(%rbp), %rdi
callq 0xcabd0
movq -0x290(%rbp), %rax
addq $0x3b0, %rsp            # imm = 0x3B0
popq %rbp
retq
leaq -0xc0(%rbp), %rdi
callq 0x1b610
leaq -0xa8(%rbp), %rdi
callq 0x1bb30
leaq -0x90(%rbp), %rdi
callq 0x1c270
leaq -0x58(%rbp), %rdi
callq 0xcabd0
leaq -0x38(%rbp), %rdi
callq 0xcabd0
movq -0xd0(%rbp), %rdi
callq 0xfa2a0
nopl (%rax,%rax)