// File: /workspace/github_cpp_makefile_star2_O2/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 0xa365(%rip), %rcx      # 0x14a10
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 0xab44
testq %rax, %rax
je 0xa80f
leaq 0x14eb1(%rip), %rsi     # 0x1f588
leaq 0x1518a(%rip), %rdx     # 0x1f868
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53e0
movq %rax, %r14
jmp 0xa812
testq %rax, %rax
je 0xa866
leaq 0x14e88(%rip), %rsi     # 0x1f588
leaq 0x15161(%rip), %rdx     # 0x1f868
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53e0
movq %rax, %r14
jmp 0xa869
testq %rax, %rax
je 0xa8f4
leaq 0x14e5f(%rip), %rsi     # 0x1f588
leaq 0x15138(%rip), %rdx     # 0x1f868
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53e0
movq %rax, %r14
jmp 0xa8f7
testq %rax, %rax
je 0xa948
leaq 0x14e36(%rip), %rsi     # 0x1f588
leaq 0x1510f(%rip), %rdx     # 0x1f868
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53e0
movq %rax, %r14
jmp 0xa94b
testq %rax, %rax
je 0xa99c
leaq 0x14e0d(%rip), %rsi     # 0x1f588
leaq 0x150e6(%rip), %rdx     # 0x1f868
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53e0
movq %rax, %r14
jmp 0xa99f
testq %rax, %rax
je 0xa9ed
leaq 0x14de4(%rip), %rsi     # 0x1f588
leaq 0x150bd(%rip), %rdx     # 0x1f868
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53e0
movq %rax, %r14
jmp 0xa9f0
testq %rax, %rax
je 0xaa70
leaq 0x14dbb(%rip), %rsi     # 0x1f588
leaq 0x15094(%rip), %rdx     # 0x1f868
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53e0
movq %rax, %r14
jmp 0xaa73
testq %rax, %rax
je 0xaac7
leaq 0x14d92(%rip), %rsi     # 0x1f588
leaq 0x1506b(%rip), %rdx     # 0x1f868
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53e0
movq %rax, %r14
jmp 0xaaca
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xab44
leaq 0x14d58(%rip), %rsi     # 0x1f588
leaq 0x15031(%rip), %rdx     # 0x1f868
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53e0
testq %r14, %r14
je 0xab44
testq %rax, %rax
je 0xab44
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x8(%r14), %xmm0
jmp 0xa8bb
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xab44
leaq 0x14d01(%rip), %rsi     # 0x1f588
leaq 0x14fda(%rip), %rdx     # 0x1f868
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53e0
testq %r14, %r14
je 0xab44
testq %rax, %rax
je 0xab44
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)
pushq $0x10
popq %rdi
callq 0x5390
movq %rax, %rbx
movsd 0x8(%rsp), %xmm0
ucomisd 0x10(%rsp), %xmm0
leaq 0x14fa8(%rip), %rax     # 0x1f890
movq %rax, (%rbx)
setae 0x8(%rbx)
jmp 0xab44
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xab44
leaq 0x14c73(%rip), %rsi     # 0x1f588
leaq 0x14f4c(%rip), %rdx     # 0x1f868
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53e0
testq %r14, %r14
je 0xab44
testq %rax, %rax
je 0xab44
movsd 0x8(%r14), %xmm0
mulsd 0x8(%rax), %xmm0
jmp 0xaa3c
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xab44
leaq 0x14c1f(%rip), %rsi     # 0x1f588
leaq 0x14ef8(%rip), %rdx     # 0x1f868
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53e0
testq %r14, %r14
je 0xab44
testq %rax, %rax
je 0xab44
movsd 0x8(%r14), %xmm0
divsd 0x8(%rax), %xmm0
jmp 0xaa3c
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xab44
leaq 0x14bcb(%rip), %rsi     # 0x1f588
leaq 0x14ea4(%rip), %rdx     # 0x1f868
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53e0
testq %r14, %r14
je 0xab44
testq %rax, %rax
je 0xab44
movsd 0x8(%r14), %xmm0
addsd 0x8(%rax), %xmm0
jmp 0xaa3c
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xab44
leaq 0x14b7a(%rip), %rsi     # 0x1f588
leaq 0x14e53(%rip), %rdx     # 0x1f868
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53e0
testq %r14, %r14
je 0xab44
testq %rax, %rax
je 0xab44
movsd 0x8(%r14), %xmm0
subsd 0x8(%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x8(%rax)
pushq $0x10
popq %rdi
callq 0x5390
movq %rax, %rbx
leaq 0x14deb(%rip), %rax     # 0x1f848
movq %rax, (%rbx)
movsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x8(%rbx)
jmp 0xab44
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xab44
leaq 0x14af7(%rip), %rsi     # 0x1f588
leaq 0x14dd0(%rip), %rdx     # 0x1f868
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53e0
testq %r14, %r14
je 0xab44
testq %rax, %rax
je 0xab44
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x8(%r14), %xmm0
jmp 0xab10
xorl %r14d, %r14d
movq 0x18(%rbx), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0xab44
leaq 0x14aa4(%rip), %rsi     # 0x1f588
leaq 0x14d7d(%rip), %rdx     # 0x1f868
movq %rax, %rdi
xorl %ecx, %ecx
callq 0x53e0
testq %r14, %r14
je 0xab44
testq %rax, %rax
je 0xab44
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)
pushq $0x10
popq %rdi
callq 0x5390
movq %rax, %rbx
movsd 0x8(%rsp), %xmm0
ucomisd 0x10(%rsp), %xmm0
leaq 0x14d53(%rip), %rax     # 0x1f890
movq %rax, (%rbx)
seta 0x8(%rbx)
movq %rbx, %rax
addq $0x18, %rsp
popq %rbx
popq %r14
retq
nop