// File: Bartor[P]kompilator/middle/ast_optimizer/ASTOptimizer.cpp
// Function: ASTOptimizer::constantLoopUnroller(Node*)
Node *ASTOptimizer::constantLoopUnroller(Node *node) {
    if (auto forNode = dynamic_cast<For *>(node)) {
        try {
            auto startConstant = dynamic_cast<NumberValue &>(forNode->startValue);
            try {
                auto endConstant = dynamic_cast<NumberValue &>(forNode->endValue);

                CommandList *cmdList = new CommandList();

                if (forNode->reversed) {
                    for (long long i = startConstant.value; i >= endConstant.value; i--) {
                        Callback replacer = iteratorReplacer(forNode->variableName, i);
                        originalProgram->constants.constants.push_back(i);
                        cmdList->append(*static_cast<CommandList *>(forNode->commands.copy(replacer)));
                    }
                } else {
                    for (long long i = startConstant.value; i <= endConstant.value; i++) {
                        Callback replacer = iteratorReplacer(forNode->variableName, i);
                        originalProgram->constants.constants.push_back(i);
                        cmdList->append(*static_cast<CommandList *>(forNode->commands.copy(replacer)));
                    }
                }

                return cmdList;
            } catch (std::bad_cast _) {}
        } catch (std::bad_cast _) {}
    }
    return node;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x180, %rsp            # imm = 0x180
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x110(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x108(%rbp)
cmpq $0x0, %rax
je 0x26b26
movq -0x108(%rbp), %rdi
leaq 0x19453(%rip), %rsi     # 0x3ff60
leaq 0x1999c(%rip), %rdx     # 0x404b0
xorl %eax, %eax
movl %eax, %ecx
callq 0x62f0
movq %rax, -0x118(%rbp)
jmp 0x26b31
xorl %eax, %eax
movq %rax, -0x118(%rbp)
jmp 0x26b31
movq -0x118(%rbp), %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x26f89
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rdi
leaq 0x19522(%rip), %rsi     # 0x40078
leaq 0x19683(%rip), %rdx     # 0x401e0
xorl %eax, %eax
movl %eax, %ecx
callq 0x62f0
movq %rax, -0x120(%rbp)
cmpq $0x0, %rax
jne 0x26b7a
callq 0x6530
jmp 0x26b7a
movq -0x120(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0x28eb0
movq -0x20(%rbp), %rax
movq 0x30(%rax), %rdi
leaq 0x194df(%rip), %rsi     # 0x40078
leaq 0x19640(%rip), %rdx     # 0x401e0
xorl %eax, %eax
movl %eax, %ecx
callq 0x62f0
movq %rax, -0x128(%rbp)
cmpq $0x0, %rax
jne 0x26bbd
callq 0x6530
jmp 0x26bbd
movq -0x128(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0x28eb0
movl $0x20, %edi
callq 0x6260
movq %rax, -0x130(%rbp)
jmp 0x26be0
movq -0x130(%rbp), %rdi
callq 0x8420
jmp 0x26bee
movq -0x130(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x20(%rbp), %rax
testb $0x1, 0x40(%rax)
je 0x26d69
movq -0x28(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
cmpq -0x48(%rbp), %rax
jl 0x26d64
movq -0x110(%rbp), %rsi
movq -0x20(%rbp), %rdx
addq $0x8, %rdx
movq -0x60(%rbp), %rcx
leaq -0x80(%rbp), %rdi
callq 0x26fb0
jmp 0x26c3b
movq -0x110(%rbp), %rax
movq (%rax), %rax
movq 0x10(%rax), %rdi
leaq -0x60(%rbp), %rsi
callq 0x82e0
jmp 0x26c54
movq -0x58(%rbp), %rax
movq %rax, -0x140(%rbp)
movq -0x20(%rbp), %rax
movq 0x38(%rax), %rax
movq %rax, -0x138(%rbp)
leaq -0xa0(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x11590
jmp 0x26c80
movq -0x138(%rbp), %rdi
movq (%rdi), %rax
movq 0x8(%rax), %rax
leaq -0xa0(%rbp), %rsi
callq *%rax
movq %rax, -0x148(%rbp)
jmp 0x26ca0
movq -0x148(%rbp), %rsi
movq -0x140(%rbp), %rdi
callq 0x28f00
jmp 0x26cb5
leaq -0xa0(%rbp), %rdi
callq 0x11640
leaq -0x80(%rbp), %rdi
callq 0x11640
movq -0x60(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x60(%rbp)
jmp 0x26c0f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x26f3f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x26eb4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x26eab
movq -0x130(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
movl $0x20, %esi
callq 0x6270
jmp 0x26eab
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x26d56
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x11640
leaq -0x80(%rbp), %rdi
callq 0x11640
jmp 0x26eab
jmp 0x26e8e
movq -0x28(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rax
cmpq -0x48(%rbp), %rax
jg 0x26e8c
movq -0x110(%rbp), %rsi
movq -0x20(%rbp), %rdx
addq $0x8, %rdx
movq -0xa8(%rbp), %rcx
leaq -0xc8(%rbp), %rdi
callq 0x26fb0
jmp 0x26da9
movq -0x110(%rbp), %rax
movq (%rax), %rax
movq 0x10(%rax), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x82e0
jmp 0x26dc5
movq -0x58(%rbp), %rax
movq %rax, -0x158(%rbp)
movq -0x20(%rbp), %rax
movq 0x38(%rax), %rax
movq %rax, -0x150(%rbp)
leaq -0xe8(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0x11590
jmp 0x26df4
movq -0x150(%rbp), %rdi
movq (%rdi), %rax
movq 0x8(%rax), %rax
leaq -0xe8(%rbp), %rsi
callq *%rax
movq %rax, -0x160(%rbp)
jmp 0x26e14
movq -0x160(%rbp), %rsi
movq -0x158(%rbp), %rdi
callq 0x28f00
jmp 0x26e29
leaq -0xe8(%rbp), %rdi
callq 0x11640
leaq -0xc8(%rbp), %rdi
callq 0x11640
movq -0xa8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa8(%rbp)
jmp 0x26d74
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x26e7e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x11640
leaq -0xc8(%rbp), %rdi
callq 0x11640
jmp 0x26eab
jmp 0x26e8e
movq -0x58(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0xec(%rbp)
leaq -0x50(%rbp), %rdi
callq 0xfa50
jmp 0x26f11
leaq -0x50(%rbp), %rdi
callq 0xfa50
movl -0x3c(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x26f36
movq -0x38(%rbp), %rdi
movq %rdi, -0x170(%rbp)
callq 0x6360
movq %rax, %rsi
leaq -0xf8(%rbp), %rdi
movq %rdi, -0x168(%rbp)
callq 0x203d0
movq -0x170(%rbp), %rdi
callq 0x60f0
movq -0x168(%rbp), %rdi
callq 0x6500
callq 0x6450
jmp 0x26f05
jmp 0x26f07
movl $0x0, -0xec(%rbp)
leaq -0x30(%rbp), %rdi
callq 0xfa50
movl -0xec(%rbp), %eax
testl %eax, %eax
je 0x26f28
jmp 0x26f26
jmp 0x26f91
jmp 0x26f87
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x30(%rbp), %rdi
callq 0xfa50
movl -0x3c(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x26f9e
movq -0x38(%rbp), %rdi
movq %rdi, -0x178(%rbp)
callq 0x6360
movq %rax, %rsi
leaq -0x100(%rbp), %rdi
callq 0x203d0
movq -0x178(%rbp), %rdi
callq 0x60f0
leaq -0x100(%rbp), %rdi
callq 0x6500
callq 0x6450
jmp 0x26f89
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x180, %rsp            # imm = 0x180
popq %rbp
retq
movq -0x38(%rbp), %rdi
callq 0x64d0
nopw (%rax,%rax)