// File: /workspace/github_cpp_makefile_star2_O2/rofl0r[P]ascc/cs_parser.cpp
// Function: extract_variable_name(int, ccInternalList*, long*, int*)
long extract_variable_name(int fsym, ccInternalList*targ,long*slist, int *funcAtOffs) {
  *funcAtOffs = -1;

  int mustBeStaticMember = 0;

  if (!sym.entries[fsym].is_loadable_variable()) {

    // allow struct type as first word, but then a static member must be used
    if (sym.get_type(fsym) == SYM_VARTYPE)
      mustBeStaticMember = 1;
    else
      return 0;
  }

  int oriOffs = targ->pos;
  long sslen=1;
  slist[0]=fsym;
  if (targ->peeknext() == SCODE_INVALID) return sslen;
  // it works like this:
  // MyStruct ms; MouseType m; int x;
  // ms.m.x
  // MyStruct::m
  // MouseType::x

  int justHadBrackets = 0;
  int nexttype = sym.get_type(targ->peeknext());
  while ((nexttype == SYM_DOT) || (nexttype == SYM_OPENBRACKET)) {
    // store the . or [
    slist[sslen] = targ->getnext();
    sslen++;
    // get the next one
    slist[sslen] = targ->peeknext();

    if (slist[sslen] == SCODE_INVALID) {
      // this happens if they do:
      // player.Walk(oKey.-4666);
      cc_error("dot operator must be followed by member function or property");
      return -1;
    }

    if (sslen >= TEMP_SYMLIST_LENGTH - 5)
    {
      cc_error("buffer exceeded: you probably have a missing closing bracket on a previous line");
      return -1;
    }

    if (nexttype == SYM_DOT) {
      int reallywant;
      if (sym.get_type(fsym) == SYM_VARTYPE) {
        // static member access, eg. "Math.Func()"
        mustBeStaticMember = 1;
        reallywant = fsym;
      }
      else {
        mustBeStaticMember = 0;
        reallywant = sym.entries[fsym].vartype;
        if (reallywant < 1) {
          cc_error("structure required on left side of '.'");
          return -1;
        }
      }

      if (((sym.entries[fsym].flags & SFLG_ARRAY) != 0) && (justHadBrackets == 0)) {
        cc_error("'[' expected");
        return -1;
      }
      justHadBrackets = 0;

      // allow protected member access with the "this" ptr only
      int allowProtectedMembers = 0;
      if (sym.entries[fsym].flags & SFLG_THISPTR) {
        allowProtectedMembers = 1;
      }
      // convert the member's sym to the structmember version
      if (find_member_sym(reallywant, &slist[sslen], allowProtectedMembers))
        return -1;
      if ((sym.entries[slist[sslen]].flags & SFLG_STRUCTMEMBER) == 0) {
        cc_error("structure member required after '.'");
        return -1;
      }
      if ((mustBeStaticMember) && ((sym.entries[slist[sslen]].flags & SFLG_STATIC) == 0)) {
        cc_error("must have an instance of the struct to access a non-static member");
        return -1;
      }
      fsym = slist[sslen];
      sslen++;
      targ->getnext();

      if (sym.get_type(slist[sslen - 1]) == SYM_FUNCTION) {
        *funcAtOffs = sslen - 1;

        slist[sslen++] = targ->getnext();

        if (sym.get_type(slist[sslen - 1]) != SYM_OPENPARENTHESIS) {
          cc_error("'(' expected");
          return -1;
        }

        // include the member function params in the returned value
        int bdepth = 1;
        while (bdepth > 0) {
          if (check_not_eof(*targ))
            return -1;
          slist[sslen] = targ->getnext();
          if (sslen >= TEMP_SYMLIST_LENGTH - 1)
          {
            cc_error("buffer exceeded: you probably have a missing closing bracket on a previous line");
            return -1;
          }
          sslen++;
          if (sym.get_type(slist[sslen - 1]) == SYM_CLOSEPARENTHESIS)
            bdepth--;
          else if (sym.get_type(slist[sslen - 1]) == SYM_OPENPARENTHESIS)
            bdepth++;
        }

      }
      // save this member for use in a sub-member
    }
    else if (nexttype == SYM_OPENBRACKET) {
      if ((sym.get_type(slist[sslen]) >= NOTEXPRESSION) &&
          ((sym.get_type(slist[sslen]) != SYM_VARTYPE) || ((sym.entries[slist[sslen]].flags & SFLG_STRUCTTYPE) == 0))) {
        cc_error("parse error after '['");
        return -1;
        }
      if (sym.get_type(slist[sslen]) == SYM_CLOSEBRACKET) {
        cc_error("array index not specified");
        return -1;
        }
      if ((sym.entries[slist[sslen-2]].flags & SFLG_ARRAY)==0) {
        cc_error("%s is not an array",sym.get_friendly_name(slist[sslen-2]).c_str());
        return -1;
        }
      int braclevel = 0, linenumWas = currentline;
      // extract the contents of the brackets
      // comma is allowed because you can have like array[func(a,b)]
      // vartype is allowed to permit access to static members, e.g. array[Game.GetColorFromRGB(0, 0, 0)]
      while ((sym.get_type(slist[sslen]) < NOTEXPRESSION) ||
             (sym.get_type(slist[sslen]) == SYM_COMMA) ||
             (sym.get_type(slist[sslen]) == SYM_VARTYPE) && (sym.entries[slist[sslen]].flags & SFLG_STRUCTTYPE)) {
        if (sym.get_type(slist[sslen - 1]) == SYM_VARTYPE && sym.get_type(slist[sslen]) != SYM_DOT)
          break;
        if (targ->getnext() == SCODE_INVALID) {
          currentline = linenumWas;
          cc_error("missing ']'");
          return -1;
        }
        if (sym.get_type(slist[sslen]) == SYM_CLOSEBRACKET) {
          braclevel--;
          if (braclevel < 0) {
            sslen++;
            break;
            }
          }
        if (sym.get_type(slist[sslen]) == SYM_OPENBRACKET)
          braclevel++;
        sslen++;
        if (sslen >= TEMP_SYMLIST_LENGTH - 1)
        {
          cc_error("buffer exceeded: you probably have a missing closing bracket on a previous line");
          return -1;
        }
        slist[sslen] = targ->peeknext();
      }
      justHadBrackets = 1;
    }
    nexttype = sym.get_type(targ->peeknext());
  }
  return sslen;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rcx, %r14
movq %rdx, %r15
movq %rsi, %r12
movl %edi, %ebp
orl $-0x1, (%rcx)
movslq %edi, %rbx
leaq 0x1e424(%rip), %r13     # 0x256f0
imulq $0xb0, %rbx, %rdi
addq 0x28(%r13), %rdi
callq 0xfe92
testl %eax, %eax
jne 0x72f7
leaq 0x1e409(%rip), %rdi     # 0x256f0
movl %ebp, %esi
callq 0xfe60
cmpl $0x2e, %eax
jne 0x765b
movq %rbx, (%r15)
movq %r12, %rdi
callq 0xfc58
cmpq $-0x1, %rax
je 0x764e
movq %rbp, 0x8(%rsp)
movq %r14, 0x10(%rsp)
pushq $0x1
popq %rbx
movb $0x1, %al
movl %eax, 0x4(%rsp)
movq %rbx, %rbp
leaq (,%rbp,8), %rbx
movq %r12, %rdi
callq 0xfc58
movq %r13, %rdi
movl %eax, %esi
callq 0xfe60
movl %eax, %r14d
cmpl $0x9, %eax
je 0x734e
cmpl $0x7, %r14d
jne 0x7670
movq %r12, %rdi
callq 0xfc84
movq %rax, (%r15,%rbp,8)
movq %r12, %rdi
callq 0xfc58
movq %rax, 0x8(%r15,%rbp,8)
cmpq $-0x1, %rax
je 0x765f
cmpq $0x5e, %rbp
jge 0x7652
incq %rbp
cmpl $0x7, %r14d
je 0x7393
addq $0x8, %rbx
cmpl $0x9, %r14d
jne 0x732a
jmp 0x74f6
movq %r13, %rdi
movl %eax, %esi
callq 0xfe60
movq (%r15,%rbp,8), %rsi
cmpl $0x17, %eax
jl 0x73d1
movq %r13, %rdi
callq 0xfe60
cmpl $0x2e, %eax
jne 0x76a1
movq (%r15,%rbp,8), %rsi
movq 0x28(%r13), %rax
imulq $0xb0, %rsi, %rcx
testb $0x4, 0x29(%rax,%rcx)
je 0x76a1
movq %r13, %rdi
callq 0xfe60
cmpl $0x8, %eax
je 0x76aa
movq -0x10(%r15,%rbp,8), %rdx
movq 0x28(%r13), %rax
imulq $0xb0, %rdx, %rcx
testb $0x2, 0x28(%rax,%rcx)
je 0x76b3
leaq 0x1e3ac(%rip), %rax     # 0x257b0
movl (%rax), %eax
movl %eax, 0x4(%rsp)
movq (%r15,%rbp,8), %rsi
xorl %r14d, %r14d
movq %r13, %rdi
callq 0xfe60
cmpl $0x17, %eax
jl 0x745b
movl (%r15,%rbp,8), %esi
movq %r13, %rdi
callq 0xfe60
cmpl $0x2a, %eax
je 0x745b
movl (%r15,%rbp,8), %esi
movq %r13, %rdi
callq 0xfe60
cmpl $0x2e, %eax
jne 0x74e9
movq 0x28(%r13), %rax
imulq $0xb0, (%r15,%rbp,8), %rcx
testb $0x4, 0x29(%rax,%rcx)
je 0x74e9
movl -0x8(%r15,%rbp,8), %esi
movq %r13, %rdi
callq 0xfe60
cmpl $0x2e, %eax
jne 0x747e
movl (%r15,%rbp,8), %esi
movq %r13, %rdi
callq 0xfe60
cmpl $0x9, %eax
jne 0x74e9
movq %r12, %rdi
callq 0xfc84
cmpq $-0x1, %rax
je 0x7682
movl (%r15,%rbp,8), %esi
movq %r13, %rdi
callq 0xfe60
cmpl $0x8, %eax
jne 0x74a9
testl %r14d, %r14d
jle 0x74e6
decl %r14d
movl (%r15,%rbp,8), %esi
movq %r13, %rdi
callq 0xfe60
cmpq $0x62, %rbp
jge 0x7652
leaq 0x1(%rbp), %rbx
xorl %ecx, %ecx
cmpl $0x7, %eax
sete %cl
addl %ecx, %r14d
movq %r12, %rdi
callq 0xfc58
movq %rax, %rsi
movq %rax, 0x8(%r15,%rbp,8)
movq %rbx, %rbp
jmp 0x7411
incq %rbp
movl $0x0, 0x4(%rsp)
jmp 0x7322
movq %r13, %rdi
movq 0x8(%rsp), %r14
movl %r14d, %esi
callq 0xfe60
movq 0x28(%r13), %rsi
movslq %r14d, %rcx
movl %eax, %r14d
cmpl $0x2e, %eax
je 0x752e
imulq $0xb0, %rcx, %rdx
movswl 0x30(%rsi,%rdx), %edx
movq %rdx, 0x8(%rsp)
testl %edx, %edx
jle 0x76ff
imulq $0xb0, %rcx, %rcx
movq 0x28(%rsi,%rcx), %rdx
testb $0x2, %dl
sete %al
movl 0x4(%rsp), %ecx
notb %cl
orb %al, %cl
testb $0x1, %cl
je 0x7698
addq %r15, %rbx
shrl $0xb, %edx
andl $0x1, %edx
movq 0x8(%rsp), %rdi
movq %rbx, %rsi
callq 0x59e1
testl %eax, %eax
jne 0x766d
movq (%r15,%rbp,8), %rcx
movq 0x28(%r13), %rax
movq %rcx, 0x8(%rsp)
imulq $0xb0, %rcx, %rcx
movq 0x28(%rax,%rcx), %rax
testb %al, %al
jns 0x76e7
cmpl $0x2e, %r14d
setne %cl
shrl $0xd, %eax
andl $0x1, %eax
orb %cl, %al
je 0x76f3
leaq 0x1(%rbp), %rbx
movq %r12, %rdi
callq 0xfc84
movl (%r15,%rbp,8), %esi
movq %r13, %rdi
callq 0xfe60
cmpl $0x4, %eax
jne 0x7319
movq 0x10(%rsp), %rax
movl %ebp, (%rax)
movq %r12, %rdi
callq 0xfc84
movq %rax, 0x8(%r15,%rbp,8)
movq %r13, %rdi
movl %eax, %esi
callq 0xfe60
cmpl $0x5, %eax
jne 0x770b
addq $0x2, %rbp
movq %rbp, %rbx
pushq $0x1
popq %rbp
pushq $-0x1
popq %r14
testl %ebp, %ebp
jle 0x7319
movq %r12, %rdi
callq 0x5d62
testl %eax, %eax
jne 0x766d
movq %r12, %rdi
callq 0xfc84
movq %rax, (%r15,%rbx,8)
cmpq $0x63, %rbx
jge 0x7652
movq %r13, %rdi
movl %eax, %esi
callq 0xfe60
movl %r14d, %ecx
cmpl $0x6, %eax
je 0x7647
movl (%r15,%rbx,8), %esi
movq %r13, %rdi
callq 0xfe60
xorl %ecx, %ecx
cmpl $0x5, %eax
sete %cl
addl %ecx, %ebp
incq %rbx
jmp 0x75fb
pushq $0x1
jmp 0x766f
leaq 0x11a2d(%rip), %rdi     # 0x19086
jmp 0x7666
xorl %ebp, %ebp
jmp 0x7670
leaq 0x119e3(%rip), %rdi     # 0x19049
xorl %eax, %eax
callq 0xf258
pushq $-0x1
popq %rbp
movq %rbp, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1e127(%rip), %rax     # 0x257b0
movl 0x4(%rsp), %ecx
movl %ecx, (%rax)
leaq 0x11b2a(%rip), %rdi     # 0x191c0
jmp 0x7666
leaq 0x11a5e(%rip), %rdi     # 0x190fd
jmp 0x7666
leaq 0x11ad5(%rip), %rdi     # 0x1917d
jmp 0x7666
leaq 0x11ae2(%rip), %rdi     # 0x19193
jmp 0x7666
leaq 0x1e036(%rip), %rsi     # 0x256f0
leaq 0x18(%rsp), %rbx
movq %rbx, %rdi
callq 0x10864
movq (%rbx), %rsi
leaq 0x11adc(%rip), %rdi     # 0x191ad
xorl %eax, %eax
callq 0xf258
pushq $-0x1
popq %rbp
leaq 0x18(%rsp), %rdi
callq 0x31a0
jmp 0x7670
leaq 0x11a1c(%rip), %rdi     # 0x1910a
jmp 0x7666
leaq 0x11a34(%rip), %rdi     # 0x1912e
jmp 0x7666
leaq 0x119d0(%rip), %rdi     # 0x190d6
jmp 0x7666
leaq 0x11a5e(%rip), %rdi     # 0x19170
jmp 0x7666
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0x31a0
movq %rbx, %rdi
callq 0x3560