// File: Bartor[P]kompilator/middle/abstract_assembler/AbstractAssembler.cpp
// Function: AbstractAssembler::getVariablesFromDeclarations(bool)
void AbstractAssembler::getVariablesFromDeclarations(bool verbose) {
    scopedVariables = new ScopedVariables(
            1 // next address...
            + accumulatorNumber // ...offset by accumulators...
            + program.constants.constants.size() * 2 // ...constants times two for additional special constants (1024 = 2^10, so we may need 10 as well)
            + program.declarations.declarations.size() * 2 // ...and possible constants (array starting addresses + array starting indexes)
    );

    for (const auto &declaration : program.declarations.declarations) {
        if (auto numDecl = dynamic_cast<IdentifierDeclaration *>(declaration)) {
            NumberVariable *var = new NumberVariable(numDecl->name, *new ResolvableAddress());
            scopedVariables->pushVariableScope(var);
            if (verbose) std::cout << var->toString() << std::endl;
        } else if (auto arrDecl = dynamic_cast<ArrayDeclaration *>(declaration)) {
            NumberArrayVariable *var = new NumberArrayVariable(arrDecl->name, *new ResolvableAddress(), arrDecl->start, arrDecl->end);
            scopedVariables->pushVariableScope(var);
            if (verbose) std::cout << var->toString() << std::endl;

            // this is an array start address; it must be included in generated constants to use with indirect
            // variable addressing mode (e.g. a[b])
            // constants are to be generated in the next step, based on program constants
            // this isn't the best solutions and should be changed one day
            program.constants.constants.push_back(var->getAddress().getAddress());
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x150, %rsp            # imm = 0x150
movb %sil, %al
movq %rdi, -0x8(%rbp)
andb $0x1, %al
movb %al, -0x9(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xc0(%rbp)
movl $0x20, %edi
callq 0x6260
movq %rax, %rcx
movq -0xc0(%rbp), %rax
movq %rcx, -0xb8(%rbp)
movq %rcx, -0xd0(%rbp)
movq (%rax), %rcx
movq %rcx, -0xc8(%rbp)
movq 0x20(%rax), %rax
movq 0x10(%rax), %rdi
callq 0xa430
movq -0xc8(%rbp), %rcx
movq %rax, %rdx
movq -0xc0(%rbp), %rax
leaq (%rcx,%rdx,2), %rcx
movq %rcx, -0xb0(%rbp)
movq 0x20(%rax), %rax
movq (%rax), %rdi
addq $0x8, %rdi
callq 0x9c70
movq -0xb8(%rbp), %rdi
movq %rax, %rcx
movq -0xb0(%rbp), %rax
leaq 0x1(%rax,%rcx,2), %rsi
callq 0x1fa10
jmp 0x11d34
movq -0xc0(%rbp), %rax
movq -0xd0(%rbp), %rcx
movq %rcx, 0x28(%rax)
movq 0x20(%rax), %rax
movq (%rax), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x9b20
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rdi
callq 0x9970
movq %rax, -0x38(%rbp)
leaq -0x30(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0xf620
testb $0x1, %al
jne 0x11d85
jmp 0x12148
leaq -0x30(%rbp), %rdi
callq 0x9fa0
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xd8(%rbp)
cmpq $0x0, %rax
je 0x11def
movq -0xd8(%rbp), %rdi
leaq 0x2e1bc(%rip), %rsi     # 0x3ff70
leaq 0x2e7cd(%rip), %rdx     # 0x40588
xorl %eax, %eax
movl %eax, %ecx
callq 0x62f0
movq %rax, -0xe0(%rbp)
jmp 0x11dfa
movq -0xd0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movl $0x20, %esi
callq 0x6270
jmp 0x12151
xorl %eax, %eax
movq %rax, -0xe0(%rbp)
jmp 0x11dfa
movq -0xe0(%rbp), %rax
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0x11f4f
movl $0x30, %edi
callq 0x6260
movq %rax, -0xf8(%rbp)
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0xf0(%rbp)
movl $0x10, %edi
callq 0x6260
movq %rax, -0xe8(%rbp)
jmp 0x11e43
movq -0xe8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1fa40
jmp 0x11e55
movq -0xe8(%rbp), %rdx
movq -0xf0(%rbp), %rsi
movq -0xf8(%rbp), %rdi
xorl %ecx, %ecx
callq 0x1fa70
jmp 0x11e73
movq -0xc0(%rbp), %rax
movq -0xf8(%rbp), %rcx
movq %rcx, -0x50(%rbp)
movq 0x28(%rax), %rdi
movq -0x50(%rbp), %rsi
callq 0x244b0
testb $0x1, -0x9(%rbp)
je 0x11f4a
movq -0x50(%rbp), %rsi
movq (%rsi), %rax
movq (%rax), %rax
leaq -0x70(%rbp), %rdi
movq %rdi, -0x108(%rbp)
callq *%rax
movq -0x108(%rbp), %rsi
movq 0x2f107(%rip), %rdi     # 0x40fc8
callq 0x6240
movq %rax, -0x100(%rbp)
jmp 0x11ecf
movq -0x100(%rbp), %rdi
movq 0x2f0b3(%rip), %rsi     # 0x40f90
callq 0x6280
jmp 0x11ee4
leaq -0x70(%rbp), %rdi
callq 0x6598
jmp 0x11f4a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x11f1a
movq -0xe8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movl $0x10, %esi
callq 0x6270
movq -0xf8(%rbp), %rdi
movl $0x30, %esi
callq 0x6270
jmp 0x12151
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x6598
jmp 0x12151
jmp 0x12138
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x110(%rbp)
cmpq $0x0, %rax
je 0x11f8a
movq -0x110(%rbp), %rdi
leaq 0x2dfff(%rip), %rsi     # 0x3ff70
leaq 0x2e658(%rip), %rdx     # 0x405d0
xorl %eax, %eax
movl %eax, %ecx
callq 0x62f0
movq %rax, -0x118(%rbp)
jmp 0x11f95
xorl %eax, %eax
movq %rax, -0x118(%rbp)
jmp 0x11f95
movq -0x118(%rbp), %rax
movq %rax, -0x78(%rbp)
cmpq $0x0, -0x78(%rbp)
je 0x12136
movl $0x48, %edi
callq 0x6260
movq %rax, -0x130(%rbp)
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x128(%rbp)
movl $0x10, %edi
callq 0x6260
movq %rax, -0x120(%rbp)
jmp 0x11fde
movq -0x120(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1fa40
jmp 0x11ff0
movq -0x120(%rbp), %rdx
movq -0x128(%rbp), %rsi
movq -0x130(%rbp), %rdi
movq -0x78(%rbp), %rax
movq 0x10(%rax), %rcx
movq 0x18(%rax), %r8
xorl %r9d, %r9d
callq 0x1fad0
jmp 0x1201b
movq -0xc0(%rbp), %rax
movq -0x130(%rbp), %rcx
movq %rcx, -0x80(%rbp)
movq 0x28(%rax), %rdi
movq -0x80(%rbp), %rsi
callq 0x244b0
testb $0x1, -0x9(%rbp)
je 0x120f5
movq -0x80(%rbp), %rsi
movq (%rsi), %rax
movq (%rax), %rax
leaq -0xa0(%rbp), %rdi
movq %rdi, -0x140(%rbp)
callq *%rax
movq -0x140(%rbp), %rsi
movq 0x2ef5c(%rip), %rdi     # 0x40fc8
callq 0x6240
movq %rax, -0x138(%rbp)
jmp 0x1207a
movq -0x138(%rbp), %rdi
movq 0x2ef08(%rip), %rsi     # 0x40f90
callq 0x6280
jmp 0x1208f
leaq -0xa0(%rbp), %rdi
callq 0x6598
jmp 0x120f5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x120c8
movq -0x120(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movl $0x10, %esi
callq 0x6270
movq -0x130(%rbp), %rdi
movl $0x48, %esi
callq 0x6270
jmp 0x12151
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x6598
jmp 0x12151
movq -0xc0(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x10(%rax), %rax
movq %rax, -0x148(%rbp)
movq -0x80(%rbp), %rdi
callq 0x25230
movq %rax, %rdi
callq 0x24490
movq -0x148(%rbp), %rdi
movq %rax, -0xa8(%rbp)
leaq -0xa8(%rbp), %rsi
callq 0x1fd50
jmp 0x12138
jmp 0x1213a
leaq -0x30(%rbp), %rdi
callq 0xf660
jmp 0x11d6f
addq $0x150, %rsp            # imm = 0x150
popq %rbp
retq
movq -0x18(%rbp), %rdi
callq 0x64d0
nopw (%rax,%rax)