// File: /workspace/github_cpp_makefile_star2_O2/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, %r15
movq %rdi, %rbx
movslq 0x18(%rdi), %rax
movq (%rdi), %rcx
movq (%rcx,%rax,8), %r13
movl $0x80, %edi
callq 0x3230
movq %rax, %r14
movl $0x4, (%rax)
addq $0x18, %rax
movq %rax, 0x8(%r14)
andq $0x0, 0x10(%r14)
movb $0x0, 0x18(%r14)
leaq 0x38(%r14), %r12
xorps %xmm0, %xmm0
movups %xmm0, 0x38(%r14)
movups %xmm0, 0x48(%r14)
movups %xmm0, 0x58(%r14)
movups %xmm0, 0x68(%r14)
andq $0x0, 0x78(%r14)
movl 0x4(%r13), %eax
movl %eax, 0x30(%r14)
leaq 0x10(%rsp), %rsi
movq %r15, (%rsi)
leaq 0x20(%rsp), %r13
pushq $0x1
popq %rdx
leaq 0xf(%rsp), %rcx
movq %r13, %rdi
callq 0xf808
movq %r12, %rdi
movq %r13, %rsi
callq 0x10148
movq %r13, %rdi
callq 0x42f2
leaq 0x50(%r14), %r12
testl %ebp, %ebp
je 0xe1b2
pushq $0x2
jmp 0xe1b4
pushq $0x1
popq %rsi
movq %rbx, %rdi
callq 0xda9c
leaq 0x10(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x20(%rsp), %r13
pushq $0x1
popq %rdx
leaq 0xf(%rsp), %rcx
movq %r13, %rdi
callq 0xf808
movq %r12, %rdi
movq %r13, %rsi
callq 0x10148
movq %r13, %rdi
callq 0x42f2
cmpl $0x4, (%r15)
jne 0xe313
movl 0x30(%r14), %edi
callq 0xde22
movl %eax, %ebp
movl 0x30(%r15), %edi
callq 0xde22
cmpl %eax, %ebp
jbe 0xe313
pushq $0x2
popq %rbp
movl $0x80, %edi
callq 0x3230
movq %rax, %r13
pushq $0x4
popq %rax
movl %eax, (%r13)
leaq 0x18(%r13), %rax
movq %rax, 0x8(%r13)
andq $0x0, 0x10(%r13)
xorl %eax, %eax
movb %al, 0x18(%r13)
leaq 0x38(%r13), %rax
movq %rax, 0x18(%rsp)
xorps %xmm0, %xmm0
movups %xmm0, 0x38(%r13)
movups %xmm0, 0x48(%r13)
movups %xmm0, 0x58(%r13)
movups %xmm0, 0x68(%r13)
andq $0x0, 0x78(%r13)
movl %ebp, 0x30(%r13)
movl $0x80, %edi
callq 0x3230
movq %rax, %rbp
pushq $0x4
popq %rax
movl %eax, (%rbp)
leaq 0x18(%rbp), %rax
movq %rax, 0x8(%rbp)
andq $0x0, 0x10(%rbp)
xorl %eax, %eax
movb %al, 0x18(%rbp)
leaq 0x38(%rbp), %rdi
xorps %xmm0, %xmm0
movups %xmm0, 0x38(%rbp)
movups %xmm0, 0x48(%rbp)
andq $0x0, 0x78(%rbp)
movups %xmm0, 0x58(%rbp)
movups %xmm0, 0x68(%rbp)
pushq $0x2
popq %rax
movl %eax, 0x30(%rbp)
leaq 0x50(%r15), %rsi
callq 0x9d64
leaq 0x50(%rbp), %rdi
movq %r12, %rsi
callq 0x9d64
leaq 0x38(%r15), %rsi
movq 0x18(%rsp), %rdi
callq 0x9d64
leaq 0x10(%rsp), %rsi
movq %rbp, (%rsi)
leaq 0x20(%rsp), %r12
pushq $0x1
popq %rdx
leaq 0xf(%rsp), %rcx
movq %r12, %rdi
callq 0xf808
leaq 0x50(%r13), %rdi
movq %r12, %rsi
callq 0x10148
movq %r12, %rdi
callq 0x42f2
movl 0x30(%r15), %eax
movl %eax, 0x30(%r13)
movl 0x30(%r14), %eax
movl %eax, 0x30(%rbp)
movq %r13, %r14
movq %rbx, %rdi
movq %r14, %rsi
xorl %edx, %edx
callq 0xce8c
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop