// File: /workspace/github_cpp_makefile_star2_O1/Bartor[P]kompilator/middle/abstract_assembler/AbstractAssembler.cpp
// Function: AbstractAssembler::resolve(AbstractIdentifier&, bool)
Resolution *AbstractAssembler::resolve(AbstractIdentifier &identifier, bool checkInit = true) {
    Variable *var = scopedVariables->resolveVariable(identifier.name);
    if (checkInit && !var->initialized) {
        std::cout << "   [w] Variable " << var->name << " may not have been initialized" << std::endl;
        warning = true;
    }
    var->initialized = true; // assume it was initialized at this point

    if (auto numVar = dynamic_cast<NumberVariable *>(var)) {
        try {
            VariableIdentifier &varId = dynamic_cast<VariableIdentifier &>(identifier); // check if the identifier was actually a var id

            return new Resolution(
                    *new InstructionList(),
                    numVar->getAddress(),
                    VARIABLE,
                    false,
                    0, // zero temp vars used
                    !numVar->readOnly // if it's readOnly, it's not writable -- used for iterators
            );
        } catch (std::bad_cast _) {
            throw "Trying to access a number variable like an array";
        }
    } else if (auto arrayVar = dynamic_cast<NumberArrayVariable *>(var)) {
        try { // ACCESS VALUE - a[0]
            AccessIdentifier &accId = dynamic_cast<AccessIdentifier &>(identifier);

            if ((accId.index < arrayVar->start || accId.index > arrayVar->end) && !arrayVar->warned) {
                std::cout << "   [w] Trying to access " + arrayVar->toString() + " at index " + std::to_string(accId.index) << "; you won't be warned about this array anymore" << std::endl;
                warning = true;
                arrayVar->warned = true;
            }

            ResolvableAddress &address = *new ResolvableAddress(arrayVar->getAddress().getAddress()); // copy address
            address.setOffset(accId.index - arrayVar->start); // set proper offset

            return new Resolution(
                    *new InstructionList(),
                    address,
                    CONSTANT_ARRAY,
                    false
            );
        } catch (std::bad_cast _) {
            try { // VARIABLE ACCESS VALUE - a[b]
                VariableAccessIdentifier &varAccId = dynamic_cast<VariableAccessIdentifier &>(identifier);

                ResolvableAddress &startValueAddress = constants->getConstant(arrayVar->start)->getAddress(); // arr start
                Variable *variable = scopedVariables->resolveVariable(varAccId.accessName); // "b" variable
                if (!variable->initialized) {
                    std::cout << "   [w] Variable " << variable->name << " may not have been initialized" << std::endl;
                    warning = true;
                }
                variable->initialized = true; // assume it was initialized at this point

                ResolvableAddress &arrAddressAddress = constants->getConstant(arrayVar->getAddress().getAddress())->getAddress();

                InstructionList &instructionList = *new InstructionList();

                Load *load = new Load(variable->getAddress()); // load value of b
                Sub *sub = new Sub(startValueAddress); // subtract value of starting index
                Add *add = new Add(arrAddressAddress); // add value of array address

                instructionList.append(load)
                        .append(sub)
                        .append(add);

                return new Resolution(
                        instructionList,
                        *new ResolvableAddress(),
                        VARIABLE_ARRAY,
                        true
                );
            } catch (std::bad_cast __) {
                throw "Trying to use array identifier as variable";
            }
        }
    } else throw "Variable resolution error";
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movl %edx, %ebx
movq %rsi, %r14
movq %rdi, %r12
movq 0x28(%rdi), %rdi
movq 0x8(%rsi), %rsi
callq 0x17e9c
movq %rax, %r15
testl %ebx, %ebx
je 0x1015d
cmpb $0x0, 0x10(%r15)
jne 0x1015d
movq 0x17eda(%rip), %rbx     # 0x27fc8
leaq 0x103b1(%rip), %rsi     # 0x204a6
movl $0x10, %edx
movq %rbx, %rdi
callq 0x5250
movq 0x18(%r15), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq %rbx, %rdi
callq 0x5250
movq %rax, %rbx
leaq 0x10398(%rip), %rsi     # 0x204b7
movl $0x1e, %edx
movq %rax, %rdi
callq 0x5250
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x51d0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x5030
movq %rax, %rdi
callq 0x5140
leaq 0x18258(%rip), %rax     # 0x283b2
movb $0x1, (%rax)
movb $0x1, 0x10(%r15)
testq %r15, %r15
je 0x10184
leaq 0x174f2(%rip), %rsi     # 0x27660
leaq 0x17583(%rip), %rdx     # 0x276f8
movq %r15, %rdi
xorl %ecx, %ecx
callq 0x5240
movq %rax, %rbx
jmp 0x10186
xorl %ebx, %ebx
testq %rbx, %rbx
je 0x10202
leaq 0x16ed6(%rip), %rsi     # 0x27068
leaq 0x16f17(%rip), %rdx     # 0x270b0
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x5240
testq %rax, %rax
je 0x1061b
movl $0x28, %edi
callq 0x51f0
movq %rax, %r13
movl $0x20, %edi
callq 0x51f0
movq %rax, %r14
movq %rax, %rdi
callq 0x1ac28
movq %rbx, %rdi
callq 0x180e8
movb 0x28(%rbx), %cl
xorb $0x1, %cl
movb %cl, (%r13)
movb $0x0, 0x1(%r13)
movq $0x0, 0x8(%r13)
movq %r14, 0x10(%r13)
movq %rax, 0x18(%r13)
movl $0x1, 0x20(%r13)
jmp 0x10606
testq %r15, %r15
je 0x10221
leaq 0x17452(%rip), %rsi     # 0x27660
leaq 0x17523(%rip), %rdx     # 0x27738
movq %r15, %rdi
xorl %ecx, %ecx
callq 0x5240
jmp 0x10223
xorl %eax, %eax
movq %r12, -0x60(%rbp)
movq %rax, -0x38(%rbp)
testq %rax, %rax
je 0x10620
leaq 0x16e2d(%rip), %rsi     # 0x27068
leaq 0x16eb6(%rip), %rdx     # 0x270f8
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x5240
testq %rax, %rax
je 0x10645
movq %rax, %r12
movq 0x10(%rax), %rax
movq -0x38(%rbp), %rsi
cmpq 0x30(%rsi), %rax
jl 0x10270
cmpq 0x38(%rsi), %rax
jle 0x10587
cmpb $0x0, 0x40(%rsi)
jne 0x10587
movq (%rsi), %rax
leaq -0xe0(%rbp), %rdi
callq *(%rax)
leaq 0x1027a(%rip), %rcx     # 0x20507
leaq -0xe0(%rbp), %rdi
movl $0x18, %r8d
xorl %esi, %esi
xorl %edx, %edx
callq 0x5230
leaq -0xb0(%rbp), %rsi
movq %rsi, -0x10(%rsi)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x102d0
movq %rdx, -0xc0(%rbp)
movq (%rcx), %rdx
movq %rdx, -0xb0(%rbp)
jmp 0x102d6
movups (%rcx), %xmm0
movups %xmm0, (%rsi)
movq 0x8(%rax), %rdx
leaq -0xc0(%rbp), %rdi
movq %rdx, 0x8(%rdi)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq 0x10225(%rip), %rsi     # 0x20520
callq 0x5420
leaq -0x70(%rbp), %rsi
movq %rsi, -0x10(%rsi)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x10324
movq %rdx, -0x80(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x70(%rbp)
jmp 0x1032a
movups (%rcx), %xmm0
movups %xmm0, (%rsi)
movq 0x8(%rax), %rdx
movq %rdx, -0x78(%rbp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
movq 0x10(%r12), %r13
movq %r13, %rbx
negq %rbx
cmovsq %r13, %rbx
movl $0x1, %r15d
cmpq $0xa, %rbx
jb 0x103b0
movl $0x4, %r15d
movabsq $0x346dc5d63886594b, %rsi # imm = 0x346DC5D63886594B
movq %rbx, %rcx
cmpq $0x63, %rcx
jbe 0x103a7
cmpq $0x3e7, %rcx            # imm = 0x3E7
jbe 0x103ad
cmpq $0x2710, %rcx           # imm = 0x2710
jb 0x103b0
movq %rcx, %rax
mulq %rsi
shrq $0xb, %rdx
addl $0x4, %r15d
cmpq $0x1869f, %rcx          # imm = 0x1869F
movq %rdx, %rcx
ja 0x1036f
addl $-0x3, %r15d
jmp 0x103b0
addl $-0x2, %r15d
jmp 0x103b0
decl %r15d
shrq $0x3f, %r13
leal (%r15,%r13), %esi
leaq -0x90(%rbp), %rax
movq %rax, -0x10(%rax)
leaq -0xa0(%rbp), %rdi
movl $0x2d, %edx
callq 0x5260
addq -0xa0(%rbp), %r13
movq %r13, %rdi
movl %r15d, %esi
movq %rbx, %rdx
callq 0xeac3
movq -0x80(%rbp), %rcx
movq -0x78(%rbp), %r8
movq -0x98(%rbp), %rdx
leaq (%rdx,%r8), %rax
movl $0xf, %esi
leaq -0x70(%rbp), %r15
cmpq %r15, %rcx
je 0x1040e
movq -0x70(%rbp), %rsi
cmpq %rsi, %rax
leaq -0x90(%rbp), %r13
jbe 0x10434
movl $0xf, %esi
cmpq %r13, -0xa0(%rbp)
je 0x1042f
movq -0x90(%rbp), %rsi
cmpq %rsi, %rax
jbe 0x10446
movq -0xa0(%rbp), %rsi
leaq -0x80(%rbp), %rdi
callq 0x50a0
jmp 0x10456
leaq -0xa0(%rbp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x5230
leaq -0x48(%rbp), %rdx
movq %rdx, -0x10(%rdx)
movq (%rax), %rsi
leaq 0x10(%rax), %rcx
cmpq %rcx, %rsi
je 0x10477
movq %rsi, -0x58(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x48(%rbp)
jmp 0x1047d
movups (%rcx), %xmm0
movups %xmm0, (%rdx)
movq %rax, %rdx
addq $0x8, %rdx
movq 0x8(%rax), %rsi
movq %rsi, -0x50(%rbp)
movq %rcx, (%rax)
movq $0x0, (%rdx)
movb $0x0, (%rcx)
movq -0x58(%rbp), %rsi
movq -0x50(%rbp), %rdx
movq 0x17b20(%rip), %rdi     # 0x27fc8
callq 0x5250
movq %rax, %rbx
leaq 0x10074(%rip), %rsi     # 0x2052b
movl $0x2e, %edx
movq %rax, %rdi
callq 0x5250
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x51d0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x5030
movq %rax, %rdi
callq 0x5140
leaq -0x48(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x10504
movq -0x48(%rbp), %rsi
incq %rsi
callq 0x5200
movq -0xa0(%rbp), %rdi
cmpq %r13, %rdi
je 0x1051f
movq -0x90(%rbp), %rsi
incq %rsi
callq 0x5200
movq -0x80(%rbp), %rdi
cmpq %r15, %rdi
je 0x10534
movq -0x70(%rbp), %rsi
incq %rsi
callq 0x5200
movq -0xc0(%rbp), %rdi
leaq -0xb0(%rbp), %rax
cmpq %rax, %rdi
je 0x10556
movq -0xb0(%rbp), %rsi
incq %rsi
callq 0x5200
leaq -0xd0(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x10575
movq -0xd0(%rbp), %rsi
incq %rsi
callq 0x5200
leaq 0x17e36(%rip), %rax     # 0x283b2
movb $0x1, %cl
movb %cl, (%rax)
movq -0x38(%rbp), %rax
movb %cl, 0x40(%rax)
movl $0x10, %edi
callq 0x51f0
movq %rax, %rbx
movq -0x38(%rbp), %rdi
callq 0x180e8
movq %rax, %rdi
callq 0x17d30
movq $0x0, (%rbx)
movq %rax, 0x8(%rbx)
movq 0x10(%r12), %rsi
movq -0x38(%rbp), %rax
subq 0x30(%rax), %rsi
movq %rbx, %rdi
callq 0x17d26
movl $0x28, %edi
callq 0x51f0
movq %rax, %r13
movl $0x20, %edi
callq 0x51f0
movq %rax, %r15
movq %rax, %rdi
callq 0x1ac28
movw $0x1, (%r13)
movq $0x0, 0x8(%r13)
movq %r15, 0x10(%r13)
movq %rbx, 0x18(%r13)
movl $0x2, 0x20(%r13)
movq %r13, %rax
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x5410
movl $0x8, %edi
callq 0x5120
leaq 0xff54(%rip), %rcx      # 0x20585
movq %rcx, (%rax)
movq 0x17965(%rip), %rsi     # 0x27fa0
movq %rax, %rdi
xorl %edx, %edx
callq 0x53a0
callq 0x5410
movq %rdx, -0x30(%rbp)
movq %rax, %r12
jmp 0x106e6
movq %rdx, -0x30(%rbp)
movq %rax, %r12
jmp 0x10708
movq %rdx, -0x30(%rbp)
movq %rax, %r12
jmp 0x10721
movq %rdx, -0x30(%rbp)
movq %rax, %r12
jmp 0x10743
jmp 0x10775
movq %rdx, -0x30(%rbp)
movq %rax, %r12
movl $0x20, %esi
movq %r15, %rdi
callq 0x5200
jmp 0x1069c
movq %rdx, -0x30(%rbp)
movq %rax, %r12
movl $0x28, %esi
movq %r13, %rdi
jmp 0x1076e
jmp 0x10775
movq %rdx, %rbx
movq %rax, %r12
movl $0x20, %esi
movq %r14, %rdi
callq 0x5200
jmp 0x10a60
movq %rdx, -0x30(%rbp)
movq %rax, %r12
leaq -0x48(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x106e6
movq -0x48(%rbp), %rsi
incq %rsi
callq 0x5200
movq -0xa0(%rbp), %rdi
leaq -0x90(%rbp), %rax
cmpq %rax, %rdi
je 0x10708
movq -0x90(%rbp), %rsi
incq %rsi
callq 0x5200
movq -0x80(%rbp), %rdi
leaq -0x70(%rbp), %rax
cmpq %rax, %rdi
je 0x10721
movq -0x70(%rbp), %rsi
incq %rsi
callq 0x5200
movq -0xc0(%rbp), %rdi
leaq -0xb0(%rbp), %rax
cmpq %rax, %rdi
je 0x10743
movq -0xb0(%rbp), %rsi
incq %rsi
callq 0x5200
leaq -0xd0(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x1077c
movq -0xd0(%rbp), %rsi
incq %rsi
jmp 0x1076e
movq %rdx, -0x30(%rbp)
movq %rax, %r12
movl $0x10, %esi
movq %rbx, %rdi
callq 0x5200
jmp 0x1077c
movq %rdx, -0x30(%rbp)
movq %rax, %r12
cmpl $0x1, -0x30(%rbp)
jne 0x10acf
movq %r12, %rdi
callq 0x52b0
movq 0x17813(%rip), %rax     # 0x27fa8
addq $0x10, %rax
movq %rax, -0x30(%rbp)
movq %rax, -0x58(%rbp)
movq %r12, %rdi
callq 0x50f0
leaq 0x168b8(%rip), %rsi     # 0x27068
leaq 0x16989(%rip), %rdx     # 0x27140
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x5240
testq %rax, %rax
je 0x109a6
movq %rax, %rbx
movq -0x60(%rbp), %rax
movq 0x30(%rax), %rdi
movq -0x38(%rbp), %rax
movq 0x30(%rax), %rsi
callq 0x17c56
movq %rax, %rdi
callq 0x17612
movq %rax, %r14
movq -0x60(%rbp), %rax
movq 0x28(%rax), %rdi
movq 0x10(%rbx), %rsi
callq 0x17e9c
movq %rax, %r12
cmpb $0x0, 0x10(%rax)
jne 0x10860
movq 0x177ba(%rip), %rdi     # 0x27fc8
leaq 0xfc91(%rip), %rsi      # 0x204a6
movl $0x10, %edx
callq 0x5250
movq 0x18(%r12), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq 0x17796(%rip), %rdi     # 0x27fc8
callq 0x5250
movq %rax, %rbx
leaq 0xfc76(%rip), %rsi      # 0x204b7
movl $0x1e, %edx
movq %rax, %rdi
callq 0x5250
movq %rbx, %rdi
callq 0x5110
leaq 0x17b55(%rip), %rax     # 0x283b2
movb $0x1, (%rax)
movb $0x1, 0x10(%r12)
movq -0x60(%rbp), %rax
movq 0x30(%rax), %rbx
movq -0x38(%rbp), %rdi
callq 0x180e8
movq %rax, %rdi
callq 0x17d30
movq %rbx, %rdi
movq %rax, %rsi
callq 0x17c56
movq %rax, %rdi
callq 0x17612
movq %rax, %r15
movl $0x20, %edi
callq 0x51f0
movq %rax, %rbx
movq %rax, %rdi
callq 0x1ac28
movl $0x20, %edi
callq 0x51f0
movq %rax, %r13
movq %r12, %rdi
callq 0x180e8
movq $-0x1, 0x8(%r13)
movb $0x0, 0x10(%r13)
movq %rax, 0x18(%r13)
leaq 0x16fa1(%rip), %rax     # 0x27878
addq $0x10, %rax
movq %rax, (%r13)
movl $0x20, %edi
callq 0x51f0
movq %rax, %r12
movq $-0x1, 0x8(%rax)
movb $0x0, 0x10(%rax)
movq %r14, 0x18(%rax)
leaq 0x17105(%rip), %rax     # 0x27a08
addq $0x10, %rax
movq %rax, (%r12)
movl $0x20, %edi
callq 0x51f0
movq %rax, %r14
movq $-0x1, 0x8(%rax)
movb $0x0, 0x10(%rax)
movq %r15, 0x18(%rax)
leaq 0x17089(%rip), %rax     # 0x279b8
addq $0x10, %rax
movq %rax, (%r14)
movq %rbx, %rdi
movq %r13, %rsi
callq 0x1adbe
movq %rax, %rdi
movq %r12, %rsi
callq 0x1adbe
movq %rax, %rdi
movq %r14, %rsi
callq 0x1adbe
movl $0x28, %edi
callq 0x51f0
movq %rax, %r13
movl $0x10, %edi
callq 0x51f0
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movw $0x101, (%r13)          # imm = 0x101
movq $0x0, 0x8(%r13)
movq %rbx, 0x10(%r13)
movq %rax, 0x18(%r13)
movl $0x3, 0x20(%r13)
leaq -0x58(%rbp), %rdi
callq 0x53f0
callq 0x5350
jmp 0x10606
callq 0x5410
movq %rdx, %r14
movq %rax, %r12
movl $0x28, %esi
jmp 0x109c5
jmp 0x109eb
movq %rdx, %r14
movq %rax, %r12
movl $0x20, %esi
movq %r13, %rdi
jmp 0x109da
jmp 0x109eb
movq %rdx, %r14
movq %rax, %r12
movl $0x20, %esi
movq %rbx, %rdi
callq 0x5200
jmp 0x109f1
jmp 0x109eb
jmp 0x109eb
jmp 0x109eb
jmp 0x109eb
jmp 0x109eb
movq %rdx, %r14
movq %rax, %r12
cmpl $0x1, %r14d
jne 0x10a4a
movq %r12, %rdi
callq 0x52b0
movq -0x30(%rbp), %rax
movq %rax, -0x80(%rbp)
movq %r12, %rdi
callq 0x50f0
movl $0x8, %edi
callq 0x5120
leaq 0xfb3a(%rip), %rcx      # 0x2055a
movq %rcx, (%rax)
movq 0x17576(%rip), %rsi     # 0x27fa0
movq %rax, %rdi
xorl %edx, %edx
callq 0x53a0
jmp 0x10abe
movq %rax, %r12
leaq -0x80(%rbp), %rdi
callq 0x53f0
callq 0x5350
leaq -0x58(%rbp), %rdi
callq 0x53f0
callq 0x5350
jmp 0x10acf
movq %rdx, %rbx
movq %rax, %r12
movl $0x28, %esi
movq %r13, %rdi
callq 0x5200
jmp 0x10a75
movq %rdx, %rbx
movq %rax, %r12
cmpl $0x1, %ebx
jne 0x10acf
movq %r12, %rdi
callq 0x52b0
movq 0x1751f(%rip), %rax     # 0x27fa8
addq $0x10, %rax
movq %rax, -0x58(%rbp)
movq %r12, %rdi
callq 0x50f0
movl $0x8, %edi
callq 0x5120
leaq 0xfa2c(%rip), %rcx      # 0x204d6
movq %rcx, (%rax)
movq 0x174ec(%rip), %rsi     # 0x27fa0
movq %rax, %rdi
xorl %edx, %edx
callq 0x53a0
movq %rax, %r12
leaq -0x58(%rbp), %rdi
callq 0x53f0
callq 0x5350
movq %r12, %rdi
callq 0x53d0
movq %rax, %rdi
callq 0xec29
nop