// File: kram[P]kram/./src/vm/vm.cpp
// Function: VM::math(Instruction*)
Value* VM::math(Instruction* ins) {
	Value* left = this->run(ins->left[0]);
	Value* right = this->run(ins->right[0]);

	if (left->type != right->type) {
		std::cout << "math() expects equal types, got " << left->print(true) << " and " << right->print(true) << "\n";
		exit(0);
	}
	
	switch (left->type) {
		case Type::NUMBER:
			return this->math_number(ins, left, right);
			break;
		case Type::STRING:
			return this->math_string(ins, left, right);
			break;

		// Silence the compiler
		default: break;
	}

	std::cout << "math() Does not know how to handle " << left->print() << "\n";
	exit(0);

	return this->get_value_null();
}

// Assembly:
subq $0xe8, %rsp
movq %rdi, 0xd8(%rsp)
movq %rsi, 0xd0(%rsp)
movq 0xd8(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0xd0(%rsp), %rdi
addq $0x38, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13710
movq 0x48(%rsp), %rdi
movq (%rax), %rsi
callq 0x10220
movq %rax, 0xc8(%rsp)
movq 0xd0(%rsp), %rdi
addq $0x50, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13710
movq 0x48(%rsp), %rdi
movq (%rax), %rsi
callq 0x10220
movq %rax, 0xc0(%rsp)
movq 0xc8(%rsp), %rax
movl 0x8(%rax), %eax
movq 0xc0(%rsp), %rcx
cmpl 0x8(%rcx), %eax
je 0x108af
movq 0x2982d(%rip), %rdi     # 0x39fd8
leaq 0x1ad64(%rip), %rsi     # 0x2b516
callq 0x32d0
movq %rax, 0x30(%rsp)
movq 0xc8(%rsp), %rsi
leaq 0xa0(%rsp), %rdi
movq %rdi, 0x38(%rsp)
movl $0x1, %edx
callq 0x1e430
movq 0x30(%rsp), %rdi
movq 0x38(%rsp), %rsi
callq 0x32a0
movq %rax, 0x40(%rsp)
jmp 0x107f1
movq 0x40(%rsp), %rdi
leaq 0x1ad3a(%rip), %rsi     # 0x2b537
callq 0x32d0
movq %rax, 0x28(%rsp)
jmp 0x10809
movq 0xc0(%rsp), %rsi
leaq 0x70(%rsp), %rdi
movl $0x1, %edx
callq 0x1e430
jmp 0x10822
movq 0x28(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x32a0
movq %rax, 0x20(%rsp)
jmp 0x10838
movq 0x20(%rsp), %rdi
leaq 0x1b01d(%rip), %rsi     # 0x2b861
callq 0x32d0
jmp 0x1084b
leaq 0x70(%rsp), %rdi
callq 0x31f0
leaq 0xa0(%rsp), %rdi
callq 0x31f0
xorl %edi, %edi
callq 0x3330
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x98(%rsp)
movl %eax, 0x94(%rsp)
jmp 0x1089d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x98(%rsp)
movl %eax, 0x94(%rsp)
leaq 0x70(%rsp), %rdi
callq 0x31f0
leaq 0xa0(%rsp), %rdi
callq 0x31f0
jmp 0x109c9
movq 0xc8(%rsp), %rax
movl 0x8(%rax), %eax
movl %eax, 0x1c(%rsp)
subl $0x1, %eax
je 0x108ff
jmp 0x108c5
movl 0x1c(%rsp), %eax
subl $0x2, %eax
jne 0x1092e
jmp 0x108d0
movq 0x48(%rsp), %rdi
movq 0xd0(%rsp), %rsi
movq 0xc8(%rsp), %rdx
movq 0xc0(%rsp), %rcx
callq 0x109e0
movq %rax, 0xe0(%rsp)
jmp 0x109b9
movq 0x48(%rsp), %rdi
movq 0xd0(%rsp), %rsi
movq 0xc8(%rsp), %rdx
movq 0xc0(%rsp), %rcx
callq 0x10c10
movq %rax, 0xe0(%rsp)
jmp 0x109b9
jmp 0x10930
movq 0x296a1(%rip), %rdi     # 0x39fd8
leaq 0x1abff(%rip), %rsi     # 0x2b53d
callq 0x32d0
movq %rax, (%rsp)
movq 0xc8(%rsp), %rsi
leaq 0x50(%rsp), %rdi
movq %rdi, 0x8(%rsp)
xorl %edx, %edx
callq 0x1e430
movq (%rsp), %rdi
movq 0x8(%rsp), %rsi
callq 0x32a0
movq %rax, 0x10(%rsp)
jmp 0x10975
movq 0x10(%rsp), %rdi
leaq 0x1aee0(%rip), %rsi     # 0x2b861
callq 0x32d0
jmp 0x10988
leaq 0x50(%rsp), %rdi
callq 0x31f0
xorl %edi, %edi
callq 0x3330
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x98(%rsp)
movl %eax, 0x94(%rsp)
leaq 0x50(%rsp), %rdi
callq 0x31f0
jmp 0x109c9
movq 0xe0(%rsp), %rax
addq $0xe8, %rsp
retq
movq 0x98(%rsp), %rdi
callq 0x3490
nopw %cs:(%rax,%rax)