// File: rofl0r[P]ascc/cs_parser.cpp
// Function: parseArrayIndexOffsets(ccCompiledScript*, VariableSymlist*, bool, bool*)
int parseArrayIndexOffsets(ccCompiledScript *scrip, VariableSymlist *thisClause, bool writingOperation, bool *isArrayOffset) {

  if ((thisClause->len > 1) &&
      (sym.get_type(thisClause->syml[1]) == SYM_OPENBRACKET)) {
    // An array
    // find where the brackets end
    int arrIndexEnd = findClosingBracketOffs(1, thisClause->syml, thisClause->len);
    if (arrIndexEnd != thisClause->len - 1) {
      cc_error("Error parsing path; unexpected token after array index");
      return -1;
    }

    bool propertyIndexer = false;
    bool checkBounds = true, multiplySize = true;

    if ((sym.entries[thisClause->syml[0]].flags & SFLG_PROPERTY) ||
        (sym.entries[thisClause->syml[0]].flags & SFLG_POINTER)) {
      // an array property, or array of pointers; in this case,
      // don't touch CX but just calculate the index value into DX
      propertyIndexer = true;
      multiplySize = false;
      // don't check bounds, the property getter will do that
      if (sym.entries[thisClause->syml[0]].flags & SFLG_PROPERTY)
        checkBounds = false;
    }
    // a char pointer has no known boundaries
    else if(isRawPointer(thisClause->syml[0]))
      checkBounds = false;

    // the value to write is in AX; preserve it
    if (writingOperation)
      scrip->push_reg(SREG_AX);

    // save the current offset in CX if there is one,
    // because parse_sub_expr might destroy it
    if (*isArrayOffset)
      scrip->push_reg(SREG_CX);

    // get the byte offset of the array index into AX
    if (get_array_index_into_ax(scrip, thisClause->syml, 1, arrIndexEnd, checkBounds, multiplySize))
      return -1;

    // if there is a current offset saved in CX, restore it
    // then add the result to CX (which is counting the overall offset)
    if (*isArrayOffset) {
      scrip->pop_reg(SREG_CX);

      if (propertyIndexer)
        scrip->write_cmd2(SCMD_REGTOREG, SREG_AX, SREG_DX);
      else
        scrip->write_cmd2(SCMD_ADDREG, SREG_CX, SREG_AX);
    }
    else if (propertyIndexer)
      scrip->write_cmd2(SCMD_REGTOREG, SREG_AX, SREG_DX);
    else
      scrip->write_cmd2(SCMD_REGTOREG, SREG_AX, SREG_CX);

    if (!propertyIndexer)
      *isArrayOffset = true;

    if (writingOperation)
      scrip->pop_reg(SREG_AX);

    // the array offset has now been added to CX (normal array)
    // or put into DX (property)
  }

  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movb %dl, %al
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
andb $0x1, %al
movb %al, -0x19(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x18(%rbp), %rax
cmpl $0x1, (%rax)
jle 0xdb77
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rax
movl %eax, %esi
leaq 0x34f13(%rip), %rdi     # 0x42870
callq 0x1e1e0
cmpl $0x7, %eax
jne 0xdb77
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x18(%rbp), %rax
movl (%rax), %edx
movl $0x1, %edi
callq 0xb6a0
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movq -0x18(%rbp), %rcx
movl (%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
je 0xd9b0
leaq 0x2481d(%rip), %rdi     # 0x321ba
movb $0x0, %al
callq 0x1bac0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xdb7e
movb $0x0, -0x2d(%rbp)
movb $0x1, -0x2e(%rbp)
movb $0x1, -0x2f(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rsi
leaq 0x34ea2(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x200, %rax            # imm = 0x200
cmpq $0x0, %rax
jne 0xda12
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rsi
leaq 0x34e77(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x100, %rax            # imm = 0x100
cmpq $0x0, %rax
je 0xda4b
movb $0x1, -0x2d(%rbp)
movb $0x0, -0x2f(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rsi
leaq 0x34e44(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x200, %rax            # imm = 0x200
cmpq $0x0, %rax
je 0xda49
movb $0x0, -0x2e(%rbp)
jmp 0xda68
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rax
movl %eax, %edi
callq 0xdb90
cmpl $0x0, %eax
je 0xda66
movb $0x0, -0x2e(%rbp)
jmp 0xda68
testb $0x1, -0x19(%rbp)
je 0xda7c
movq -0x10(%rbp), %rdi
movl $0x3, %esi
callq 0x252f0
movq -0x28(%rbp), %rax
testb $0x1, (%rax)
je 0xda93
movq -0x10(%rbp), %rdi
movl $0x5, %esi
callq 0x252f0
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
movl -0x2c(%rbp), %ecx
movb -0x2e(%rbp), %r8b
movb -0x2f(%rbp), %al
movl $0x1, %edx
andb $0x1, %r8b
andb $0x1, %al
movzbl %r8b, %r8d
movzbl %al, %r9d
callq 0xb9e0
cmpl $0x0, %eax
je 0xdad2
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xdb7e
movq -0x28(%rbp), %rax
testb $0x1, (%rax)
je 0xdb20
movq -0x10(%rbp), %rdi
movl $0x5, %esi
callq 0x25330
testb $0x1, -0x2d(%rbp)
je 0xdb06
movq -0x10(%rbp), %rdi
movl $0x3, %edx
movl $0x7, %ecx
movl %edx, %esi
callq 0x25240
jmp 0xdb1e
movq -0x10(%rbp), %rdi
movl $0xb, %esi
movl $0x5, %edx
movl $0x3, %ecx
callq 0x25240
jmp 0xdb54
testb $0x1, -0x2d(%rbp)
je 0xdb3d
movq -0x10(%rbp), %rdi
movl $0x3, %edx
movl $0x7, %ecx
movl %edx, %esi
callq 0x25240
jmp 0xdb52
movq -0x10(%rbp), %rdi
movl $0x3, %edx
movl $0x5, %ecx
movl %edx, %esi
callq 0x25240
jmp 0xdb54
testb $0x1, -0x2d(%rbp)
jne 0xdb61
movq -0x28(%rbp), %rax
movb $0x1, (%rax)
testb $0x1, -0x19(%rbp)
je 0xdb75
movq -0x10(%rbp), %rdi
movl $0x3, %esi
callq 0x25330
jmp 0xdb77
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x30, %rsp
popq %rbp
retq
nopw (%rax,%rax)