// File: /workspace/github_cpp_makefile_star2_O3/kram[P]kram/./src/parser/parser.cpp
// Function: Parser::math(Instruction*, ON)
Instruction* Parser::math(Instruction* prev, ON on) {

	// Get the current token
	lexer::Token* current = this->get_token();

	// Create a new instruction
	Instruction* math = new Instruction(Ins::MATH);

	// Set the mathematical operator, eg + or -
	math->type = current->sub;

	math->left = std::vector<Instruction*> { prev };

	if (on == ON::DEFAULT) {
		math->right = std::vector<Instruction*> { this->symbol_next(ON::MATH_CONTINUATION) };
	} else {
		math->right = std::vector<Instruction*> { this->symbol_next(ON::MATH_NEG) };
	}

	// Verify that the ordering (infix_priority()) is correct
	if (prev->instruction == Ins::MATH) {

		// The ordering is wrong, and we need to correct this
		// [a, *, [b, +, c]] -> [[a, *, b], +, c]
		// This part is a little bit well, confusing and tight. But hey, it is a side-project after all.
		if (Parser::infix_priority(math->type) > Parser::infix_priority(prev->type)) {

			Instruction* res = new Instruction(Ins::MATH);
			Instruction* right = new Instruction(Ins::MATH);

			right->left = prev->right;
			right->right = math->right;

			res->left = prev->left;
			res->right = std::vector<Instruction*> { right };

			res->type = prev->type;
			right->type = math->type;

			return this->lookahead(res, ON::DEFAULT);
		}
	}

	return this->lookahead(math, ON::DEFAULT);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %rbx
movslq 0x18(%rdi), %rax
movq (%rdi), %rcx
movq (%rcx,%rax,8), %r12
movl $0x80, %edi
callq 0x3260
movq %rax, %r15
movl $0x4, (%rax)
addq $0x18, %rax
movq %rax, 0x8(%r15)
xorl %r13d, %r13d
movq %r13, 0x10(%r15)
movb $0x0, 0x18(%r15)
xorps %xmm0, %xmm0
movups %xmm0, 0x38(%r15)
movups %xmm0, 0x48(%r15)
movups %xmm0, 0x58(%r15)
movups %xmm0, 0x68(%r15)
movq %r13, 0x78(%r15)
movl 0x4(%r12), %eax
movl %eax, 0x30(%r15)
leaq 0x8(%rsp), %rsi
movq %r14, (%rsi)
leaq 0x10(%rsp), %r12
leaq 0x7(%rsp), %rcx
movl $0x1, %edx
movq %r12, %rdi
callq 0x112c8
movq 0x38(%r15), %rdi
movaps (%r12), %xmm0
movups %xmm0, 0x38(%r15)
movq 0x10(%r12), %rax
movq %rax, 0x48(%r15)
movq %r13, 0x10(%r12)
xorps %xmm0, %xmm0
movaps %xmm0, (%r12)
testq %rdi, %rdi
je 0xf8b6
callq 0x3230
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0xf8b6
callq 0x3230
movq %rbx, %rdi
testl %ebp, %ebp
je 0xf8c4
movl $0x2, %esi
jmp 0xf8c9
movl $0x1, %esi
callq 0xf070
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %r12
leaq 0x7(%rsp), %rcx
movl $0x1, %edx
movq %r12, %rdi
callq 0x112c8
movq 0x50(%r15), %rdi
movaps (%r12), %xmm0
movups %xmm0, 0x50(%r15)
movq 0x10(%r12), %rax
movq %rax, 0x60(%r15)
xorps %xmm0, %xmm0
movaps %xmm0, (%r12)
movq $0x0, 0x10(%r12)
testq %rdi, %rdi
je 0xf92e
callq 0x3230
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0xf92e
callq 0x3230
cmpl $0x4, (%r14)
jne 0xfa96
movl 0x30(%r15), %edi
callq 0xf4ac
movl %eax, %ebp
movl 0x30(%r14), %edi
callq 0xf4ac
cmpl %eax, %ebp
jbe 0xfa96
movl $0x80, %edi
callq 0x3260
movq %rax, %r12
movl $0x4, %eax
movl %eax, (%r12)
leaq 0x18(%r12), %rax
movq %rax, 0x8(%r12)
xorl %eax, %eax
movq %rax, 0x10(%r12)
movb %al, 0x18(%r12)
leaq 0x38(%r12), %rcx
movq %rcx, 0x30(%rsp)
xorps %xmm0, %xmm0
movups %xmm0, 0x38(%r12)
movups %xmm0, 0x48(%r12)
movups %xmm0, 0x58(%r12)
movups %xmm0, 0x68(%r12)
movq %rax, 0x78(%r12)
movl $0x2, %ebp
movl %ebp, 0x30(%r12)
movl $0x80, %edi
callq 0x3260
movq %rax, %r13
movl $0x4, %eax
movl %eax, (%r13)
leaq 0x18(%r13), %rax
movq %rax, 0x8(%r13)
xorl %eax, %eax
movq %rax, 0x10(%r13)
movb %al, 0x18(%r13)
leaq 0x38(%r13), %rdi
xorps %xmm0, %xmm0
movups %xmm0, 0x38(%r13)
movups %xmm0, 0x48(%r13)
movups %xmm0, 0x58(%r13)
movups %xmm0, 0x68(%r13)
movq %rax, 0x78(%r13)
movl %ebp, 0x30(%r13)
leaq 0x50(%r14), %rsi
callq 0xaf8c
movq %r15, %rsi
addq $0x50, %rsi
leaq 0x50(%r13), %rdi
callq 0xaf8c
leaq 0x38(%r14), %rsi
movq 0x30(%rsp), %rdi
callq 0xaf8c
leaq 0x8(%rsp), %rsi
movq %r13, (%rsi)
leaq 0x10(%rsp), %rbp
leaq 0x7(%rsp), %rcx
movl $0x1, %edx
movq %rbp, %rdi
callq 0x112c8
movq 0x50(%r12), %rdi
movaps (%rbp), %xmm0
movups %xmm0, 0x50(%r12)
movq 0x10(%rbp), %rax
movq %rax, 0x60(%r12)
xorl %eax, %eax
movq %rax, 0x10(%rbp)
xorps %xmm0, %xmm0
movaps %xmm0, (%rbp)
testq %rdi, %rdi
je 0xfa83
callq 0x3230
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0xfa83
callq 0x3230
movl 0x30(%r14), %eax
movl %eax, 0x30(%r12)
movl 0x30(%r15), %eax
movl %eax, 0x30(%r13)
jmp 0xfa99
movq %r15, %r12
movq %rbx, %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0xe220
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop