// File: /workspace/github_cpp_makefile_star2_O1/iamlouk[P]asbi/src/ast-optimize.cc
// Function: ast::InfixOperator::optimize()
Node* InfixOperator::optimize() {
	switch (type) {
	case InfixOperator::Add:{
		auto a = dynamic_cast<Number*>(lhs = lhs->optimize());
		auto b = dynamic_cast<Number*>(rhs = rhs->optimize());
		if (a != nullptr && b != nullptr) {
			auto res = a->value + b->value;
			delete this;
			return new ast::Number(res);
		}
		return this;
	}
	case InfixOperator::Sub:{
		auto a = dynamic_cast<Number*>(lhs = lhs->optimize());
		auto b = dynamic_cast<Number*>(rhs = rhs->optimize());
		if (a != nullptr && b != nullptr) {
			auto res = a->value - b->value;
			delete this;
			return new ast::Number(res);
		}
		return this;
	}
	case InfixOperator::Mul:{
		auto a = dynamic_cast<Number*>(lhs = lhs->optimize());
		auto b = dynamic_cast<Number*>(rhs = rhs->optimize());
		if (a != nullptr && b != nullptr) {
			auto res = a->value * b->value;
			delete this;
			return new ast::Number(res);
		}
		return this;
	}
	case InfixOperator::Div:{
		auto a = dynamic_cast<Number*>(lhs = lhs->optimize());
		auto b = dynamic_cast<Number*>(rhs = rhs->optimize());
		if (a != nullptr && b != nullptr) {
			auto res = a->value / b->value;
			delete this;
			return new ast::Number(res);
		}
		return this;
	}
	case InfixOperator::Or:{
		/*auto a = dynamic_cast<Bool*>(lhs = lhs->optimize());
		auto b = dynamic_cast<Bool*>(rhs = rhs->optimize());
		if (a != nullptr && b != nullptr) {
			auto res = a->value || b->value;
			delete this;
			return new ast::Bool(res);
		}*/
		lhs = lhs->optimize();
		rhs = rhs->optimize();
		return this;
	}
	case InfixOperator::And:{
		/*auto a = dynamic_cast<Bool*>(lhs = lhs->optimize());
		auto b = dynamic_cast<Bool*>(rhs = rhs->optimize());
		if (a != nullptr && b != nullptr) {
			auto res = a->value && b->value;
			delete this;
			return new ast::Bool(res);
		}*/
		lhs = lhs->optimize();
		rhs = rhs->optimize();
		return this;
	}
	case InfixOperator::Equals:{
		lhs = lhs->optimize();
		rhs = rhs->optimize();
		return this;
	}
	case InfixOperator::EqualsNot:{
		lhs = lhs->optimize();
		rhs = rhs->optimize();
		return this;
	}
	case InfixOperator::Bigger:{
		auto a = dynamic_cast<Number*>(lhs = lhs->optimize());
		auto b = dynamic_cast<Number*>(rhs = rhs->optimize());
		if (a != nullptr && b != nullptr) {
			auto res = a->value > b->value;
			delete this;
			return new ast::Bool(res);
		}
		return this;
	}
	case InfixOperator::BiggerOrEqual:{
		auto a = dynamic_cast<Number*>(lhs = lhs->optimize());
		auto b = dynamic_cast<Number*>(rhs = rhs->optimize());
		if (a != nullptr && b != nullptr) {
			auto res = a->value >= b->value;
			delete this;
			return new ast::Bool(res);
		}
		return this;
	}
	case InfixOperator::Smaller:{
		auto a = dynamic_cast<Number*>(lhs = lhs->optimize());
		auto b = dynamic_cast<Number*>(rhs = rhs->optimize());
		if (a != nullptr && b != nullptr) {
			auto res = a->value < b->value;
			delete this;
			return new ast::Bool(res);
		}
		return this;
	}
	case InfixOperator::SmallerOrEqual:{
		auto a = dynamic_cast<Number*>(lhs = lhs->optimize());
		auto b = dynamic_cast<Number*>(rhs = rhs->optimize());
		if (a != nullptr && b != nullptr) {
			auto res = a->value <= b->value;
			delete this;
			return new ast::Bool(res);
		}
		return this;
	}
	}
}

// Assembly:
pushq %r14
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
movl 0x8(%rdi), %r14d
movq 0x10(%rdi), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x10(%rbx)
leaq 0xc3dd(%rip), %rcx      # 0x17a00
movslq (%rcx,%r14,4), %rdx
addq %rcx, %rdx
jmpq *%rdx
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
jmp 0xbac6
testq %rax, %rax
je 0xb787
leaq 0x14f41(%rip), %rsi     # 0x20590
leaq 0x1521a(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
movq %rax, %r14
jmp 0xb78a
testq %rax, %rax
je 0xb7de
leaq 0x14f18(%rip), %rsi     # 0x20590
leaq 0x151f1(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
movq %rax, %r14
jmp 0xb7e1
testq %rax, %rax
je 0xb86e
leaq 0x14eef(%rip), %rsi     # 0x20590
leaq 0x151c8(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
movq %rax, %r14
jmp 0xb871
testq %rax, %rax
je 0xb8c2
leaq 0x14ec6(%rip), %rsi     # 0x20590
leaq 0x1519f(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
movq %rax, %r14
jmp 0xb8c5
testq %rax, %rax
je 0xb916
leaq 0x14e9d(%rip), %rsi     # 0x20590
leaq 0x15176(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
movq %rax, %r14
jmp 0xb919
testq %rax, %rax
je 0xb946
leaq 0x14e74(%rip), %rsi     # 0x20590
leaq 0x1514d(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
movq %rax, %r14
jmp 0xb949
testq %rax, %rax
je 0xb9ec
leaq 0x14e4b(%rip), %rsi     # 0x20590
leaq 0x15124(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
movq %rax, %r14
jmp 0xb9ef
testq %rax, %rax
je 0xba43
leaq 0x14e22(%rip), %rsi     # 0x20590
leaq 0x150fb(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
movq %rax, %r14
jmp 0xba46
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xb7b7
leaq 0x14dec(%rip), %rsi     # 0x20590
leaq 0x150c5(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
jmp 0xb7b9
xorl %eax, %eax
testq %r14, %r14
je 0xbac6
testq %rax, %rax
je 0xbac6
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x8(%r14), %xmm0
jmp 0xb833
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xb80e
leaq 0x14d95(%rip), %rsi     # 0x20590
leaq 0x1506e(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
jmp 0xb810
xorl %eax, %eax
testq %r14, %r14
je 0xbac6
testq %rax, %rax
je 0xbac6
movsd 0x8(%r14), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x8(%rax)
movl $0x10, %edi
callq 0x5380
movq %rax, %rbx
movsd 0x8(%rsp), %xmm0
ucomisd 0x10(%rsp), %xmm0
leaq 0x15036(%rip), %rax     # 0x20898
movq %rax, (%rbx)
setae 0x8(%rbx)
jmp 0xbac6
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xb89e
leaq 0x14d05(%rip), %rsi     # 0x20590
leaq 0x14fde(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
jmp 0xb8a0
xorl %eax, %eax
testq %r14, %r14
je 0xbac6
testq %rax, %rax
je 0xbac6
movsd 0x8(%r14), %xmm0
mulsd 0x8(%rax), %xmm0
jmp 0xb9b6
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xb8f2
leaq 0x14cb1(%rip), %rsi     # 0x20590
leaq 0x14f8a(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
jmp 0xb8f4
xorl %eax, %eax
testq %r14, %r14
je 0xbac6
testq %rax, %rax
je 0xbac6
movsd 0x8(%r14), %xmm0
divsd 0x8(%rax), %xmm0
jmp 0xb9b6
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xb976
leaq 0x14c5d(%rip), %rsi     # 0x20590
leaq 0x14f36(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
jmp 0xb978
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xb997
leaq 0x14c2d(%rip), %rsi     # 0x20590
leaq 0x14f06(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
jmp 0xb999
xorl %eax, %eax
testq %r14, %r14
je 0xbac6
testq %rax, %rax
je 0xbac6
movsd 0x8(%r14), %xmm0
addsd 0x8(%rax), %xmm0
jmp 0xb9b6
xorl %eax, %eax
testq %r14, %r14
je 0xbac6
testq %rax, %rax
je 0xbac6
movsd 0x8(%r14), %xmm0
subsd 0x8(%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x8(%rax)
movl $0x10, %edi
callq 0x5380
movq %rax, %rbx
leaq 0x14e77(%rip), %rax     # 0x20850
movq %rax, (%rbx)
movsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x8(%rbx)
jmp 0xbac6
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xba1c
leaq 0x14b87(%rip), %rsi     # 0x20590
leaq 0x14e60(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
jmp 0xba1e
xorl %eax, %eax
testq %r14, %r14
je 0xbac6
testq %rax, %rax
je 0xbac6
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x8(%r14), %xmm0
jmp 0xba90
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xba73
leaq 0x14b30(%rip), %rsi     # 0x20590
leaq 0x14e09(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
jmp 0xba75
xorl %eax, %eax
testq %r14, %r14
je 0xbac6
testq %rax, %rax
je 0xbac6
movsd 0x8(%r14), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x8(%rax)
movl $0x10, %edi
callq 0x5380
movq %rax, %rbx
movsd 0x8(%rsp), %xmm0
ucomisd 0x10(%rsp), %xmm0
leaq 0x14dd9(%rip), %rax     # 0x20898
movq %rax, (%rbx)
seta 0x8(%rbx)
movq %rbx, %rax
addq $0x18, %rsp
popq %rbx
popq %r14
retq
nop