// File: /workspace/github_cpp_makefile_star2_O3/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 0xc4fd(%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 0xb9a2
testq %rax, %rax
je 0xb667
leaq 0x15061(%rip), %rsi     # 0x20590
leaq 0x1533a(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
movq %rax, %r14
jmp 0xb66a
testq %rax, %rax
je 0xb6be
leaq 0x15038(%rip), %rsi     # 0x20590
leaq 0x15311(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
movq %rax, %r14
jmp 0xb6c1
testq %rax, %rax
je 0xb74e
leaq 0x1500f(%rip), %rsi     # 0x20590
leaq 0x152e8(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
movq %rax, %r14
jmp 0xb751
testq %rax, %rax
je 0xb7a2
leaq 0x14fe6(%rip), %rsi     # 0x20590
leaq 0x152bf(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
movq %rax, %r14
jmp 0xb7a5
testq %rax, %rax
je 0xb7f6
leaq 0x14fbd(%rip), %rsi     # 0x20590
leaq 0x15296(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
movq %rax, %r14
jmp 0xb7f9
testq %rax, %rax
je 0xb847
leaq 0x14f94(%rip), %rsi     # 0x20590
leaq 0x1526d(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
movq %rax, %r14
jmp 0xb84a
testq %rax, %rax
je 0xb8cc
leaq 0x14f6b(%rip), %rsi     # 0x20590
leaq 0x15244(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
movq %rax, %r14
jmp 0xb8cf
testq %rax, %rax
je 0xb923
leaq 0x14f42(%rip), %rsi     # 0x20590
leaq 0x1521b(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
movq %rax, %r14
jmp 0xb926
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xb9a2
leaq 0x14f08(%rip), %rsi     # 0x20590
leaq 0x151e1(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
testq %r14, %r14
je 0xb9a2
testq %rax, %rax
je 0xb9a2
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x8(%r14), %xmm0
jmp 0xb713
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xb9a2
leaq 0x14eb1(%rip), %rsi     # 0x20590
leaq 0x1518a(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
testq %r14, %r14
je 0xb9a2
testq %rax, %rax
je 0xb9a2
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 0x15156(%rip), %rax     # 0x20898
movq %rax, (%rbx)
setae 0x8(%rbx)
jmp 0xb9a2
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xb9a2
leaq 0x14e21(%rip), %rsi     # 0x20590
leaq 0x150fa(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
testq %r14, %r14
je 0xb9a2
testq %rax, %rax
je 0xb9a2
movsd 0x8(%r14), %xmm0
mulsd 0x8(%rax), %xmm0
jmp 0xb896
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xb9a2
leaq 0x14dcd(%rip), %rsi     # 0x20590
leaq 0x150a6(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
testq %r14, %r14
je 0xb9a2
testq %rax, %rax
je 0xb9a2
movsd 0x8(%r14), %xmm0
divsd 0x8(%rax), %xmm0
jmp 0xb896
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xb9a2
leaq 0x14d79(%rip), %rsi     # 0x20590
leaq 0x15052(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
testq %r14, %r14
je 0xb9a2
testq %rax, %rax
je 0xb9a2
movsd 0x8(%r14), %xmm0
addsd 0x8(%rax), %xmm0
jmp 0xb896
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xb9a2
leaq 0x14d28(%rip), %rsi     # 0x20590
leaq 0x15001(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
testq %r14, %r14
je 0xb9a2
testq %rax, %rax
je 0xb9a2
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 0x14f97(%rip), %rax     # 0x20850
movq %rax, (%rbx)
movsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x8(%rbx)
jmp 0xb9a2
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xb9a2
leaq 0x14ca3(%rip), %rsi     # 0x20590
leaq 0x14f7c(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
testq %r14, %r14
je 0xb9a2
testq %rax, %rax
je 0xb9a2
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x8(%r14), %xmm0
jmp 0xb96c
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xb9a2
leaq 0x14c50(%rip), %rsi     # 0x20590
leaq 0x14f29(%rip), %rdx     # 0x20870
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53f0
testq %r14, %r14
je 0xb9a2
testq %rax, %rax
je 0xb9a2
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 0x14efd(%rip), %rax     # 0x20898
movq %rax, (%rbx)
seta 0x8(%rbx)
movq %rbx, %rax
addq $0x18, %rsp
popq %rbx
popq %r14
retq
nop