// File: /workspace/github_cpp_makefile_star2_O1/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 $0x48, %rsp
movq %rcx, %r13
movq %rdx, %r14
movq %rsi, %r15
movl %edi, %ebp
movl $0xffffffff, (%rcx)     # imm = 0xFFFFFFFF
movslq %edi, %rbx
leaq 0x1dc8c(%rip), %r12     # 0x256e0
imulq $0xb0, %rbx, %rdi
addq 0x28(%r12), %rdi
callq 0x111e4
testl %eax, %eax
jne 0x7a80
leaq 0x1dc70(%rip), %rdi     # 0x256e0
movl %ebp, %esi
callq 0x111aa
cmpl $0x2e, %eax
jne 0x7eee
movq %rbx, (%r14)
movq %r15, %rdi
callq 0x10f22
cmpq $-0x1, %rax
je 0x7ec7
movl %ebp, 0x10(%rsp)
movq %r13, 0x20(%rsp)
movl $0x0, 0xc(%rsp)
movl $0x1, %ebp
leaq (,%rbp,8), %r13
movq %r15, %rdi
callq 0x10f22
movq %r12, %rdi
movl %eax, %esi
callq 0x111aa
movl %eax, %ebx
cmpl $0x9, %eax
je 0x7ad5
cmpl $0x7, %ebx
jne 0x7ef2
movq %r15, %rdi
callq 0x10f88
movq %rax, (%r14,%rbp,8)
movq %r15, %rdi
callq 0x10f22
movq %rax, 0x8(%r14,%rbp,8)
cmpq $-0x1, %rax
je 0x7ece
cmpq $0x5e, %rbp
jge 0x7ed7
incq %rbp
cmpl $0x7, %ebx
je 0x7b7d
addq $0x8, %r13
cmpl $0x9, %ebx
jne 0x7ab3
movq %r12, %rdi
movl 0x10(%rsp), %ebx
movl %ebx, %esi
callq 0x111aa
movslq %ebx, %rsi
cmpl $0x2e, %eax
je 0x7b42
movq 0x28(%r12), %rcx
imulq $0xb0, %rsi, %rdx
movswl 0x30(%rcx,%rdx), %ebx
testl %ebx, %ebx
jle 0x7d2e
movq 0x28(%r12), %rcx
imulq $0xb0, %rsi, %rdx
movq 0x28(%rcx,%rdx), %rdx
movl %edx, %esi
shrb %sil
cmpl $0x0, 0xc(%rsp)
sete %cl
testb %cl, %sil
je 0x7ccf
movl $0x0, 0xc(%rsp)
leaq 0x135a5(%rip), %rdi     # 0x1b11d
jmp 0x7da1
movq %r12, %rdi
movl %eax, %esi
callq 0x111aa
cmpl $0x17, %eax
jl 0x7bb9
movl (%r14,%rbp,8), %esi
movq %r12, %rdi
callq 0x111aa
cmpl $0x2e, %eax
jne 0x7f04
movq 0x28(%r12), %rax
imulq $0xb0, (%r14,%rbp,8), %rcx
testb $0x4, 0x29(%rax,%rcx)
je 0x7f04
movl (%r14,%rbp,8), %esi
movq %r12, %rdi
callq 0x111aa
cmpl $0x8, %eax
je 0x7f0d
movq -0x10(%r14,%rbp,8), %rdx
movq 0x28(%r12), %rax
imulq $0xb0, %rdx, %rcx
testb $0x2, 0x28(%rax,%rcx)
je 0x7f16
leaq 0x1dbaf(%rip), %rax     # 0x257a0
movl (%rax), %eax
movl %eax, 0x1c(%rsp)
xorl %r13d, %r13d
movl (%r14,%rbp,8), %esi
movq %r12, %rdi
callq 0x111aa
cmpl $0x17, %eax
jl 0x7c4b
movl (%r14,%rbp,8), %esi
movq %r12, %rdi
callq 0x111aa
cmpl $0x2a, %eax
je 0x7c4b
movl (%r14,%rbp,8), %esi
movq %r12, %rdi
callq 0x111aa
movb $0x1, %bl
cmpl $0x2e, %eax
jne 0x7d61
movq 0x28(%r12), %rax
imulq $0xb0, (%r14,%rbp,8), %rcx
testb $0x4, 0x29(%rax,%rcx)
je 0x7d61
movl -0x8(%r14,%rbp,8), %esi
movq %r12, %rdi
callq 0x111aa
cmpl $0x2e, %eax
jne 0x7c72
movl (%r14,%rbp,8), %esi
movq %r12, %rdi
callq 0x111aa
cmpl $0x9, %eax
jne 0x7d6e
movq %r15, %rdi
callq 0x10f88
cmpq $-0x1, %rax
je 0x7cfa
movl (%r14,%rbp,8), %esi
movq %r12, %rdi
callq 0x111aa
cmpl $0x8, %eax
jne 0x7c9d
testl %r13d, %r13d
jle 0x7d6b
decl %r13d
movl (%r14,%rbp,8), %esi
movq %r12, %rdi
callq 0x111aa
cmpq $0x62, %rbp
jge 0x7d19
xorl %ecx, %ecx
cmpl $0x7, %eax
sete %cl
addl %ecx, %r13d
movq %r15, %rdi
callq 0x10f22
movq %rax, 0x8(%r14,%rbp,8)
incq %rbp
jmp 0x7bfa
movl %eax, 0x1c(%rsp)
addq %r14, %r13
shrl $0xb, %edx
andl $0x1, %edx
movl %ebx, %edi
movq %r13, %rsi
callq 0x5e5c
xorl %r13d, %r13d
testl %eax, %eax
je 0x7d37
movl $0x0, 0xc(%rsp)
jmp 0x7dab
leaq 0x1da9f(%rip), %rax     # 0x257a0
movl 0x1c(%rsp), %ecx
movl %ecx, (%rax)
xorl %ebx, %ebx
leaq 0x134d0(%rip), %rdi     # 0x1b1e0
xorl %eax, %eax
callq 0x10418
jmp 0x7d78
xorl %ebx, %ebx
leaq 0x13384(%rip), %rdi     # 0x1b0a6
xorl %eax, %eax
callq 0x10418
incq %rbp
jmp 0x7d78
leaq 0x133c1(%rip), %rdi     # 0x1b0f6
jmp 0x7da1
movq (%r14,%rbp,8), %rbx
movq 0x28(%r12), %rax
imulq $0xb0, %rbx, %rcx
movq 0x28(%rax,%rcx), %rax
movl $0x0, 0xc(%rsp)
testb %al, %al
js 0x7d8c
leaq 0x133cb(%rip), %rdi     # 0x1b12a
jmp 0x7da1
movl $0x1, 0xc(%rsp)
jmp 0x7d78
incq %rbp
movl $0x1, 0xc(%rsp)
movb $0x1, %bl
movq $-0x1, %rax
testb %bl, %bl
jne 0x7aab
jmp 0x7ef5
cmpl $0x2e, 0x1c(%rsp)
jne 0x7dca
andl $0x2000, %eax           # imm = 0x2000
jne 0x7dca
leaq 0x133ad(%rip), %rdi     # 0x1b14e
xorl %r13d, %r13d
xorl %eax, %eax
callq 0x10418
movl 0x10(%rsp), %eax
movl %eax, %ebx
movq $-0x1, %rax
movl %ebx, 0x10(%rsp)
testb %r13b, %r13b
jne 0x7aab
jmp 0x7ef5
movq %r15, %rdi
callq 0x10f88
movl (%r14,%rbp,8), %esi
movq %r12, %rdi
callq 0x111aa
cmpl $0x4, %eax
jne 0x7e7f
movq 0x20(%rsp), %rax
movl %ebp, (%rax)
movq %r15, %rdi
callq 0x10f88
movq %rax, 0x8(%r14,%rbp,8)
addq $0x2, %rbp
movq %r12, %rdi
movl %eax, %esi
callq 0x111aa
cmpl $0x5, %eax
jne 0x7e92
movq %rbx, 0x10(%rsp)
movl $0x1, %ebx
movq %r15, %rdi
callq 0x62f5
testl %eax, %eax
sete %r13b
jne 0x7e6d
movq %r15, %rdi
callq 0x10f88
movq %rax, (%r14,%rbp,8)
cmpq $0x62, %rbp
jg 0x7eaa
movq %r12, %rdi
movl %eax, %esi
callq 0x111aa
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmpl $0x6, %eax
je 0x7e66
movl (%r14,%rbp,8), %esi
movq %r12, %rdi
callq 0x111aa
xorl %ecx, %ecx
cmpl $0x5, %eax
sete %cl
incq %rbp
addl %ecx, %ebx
jg 0x7e1c
movl $0x0, 0xc(%rsp)
movq 0x10(%rsp), %rbx
jmp 0x7db1
incq %rbp
movl $0x0, 0xc(%rsp)
movb $0x1, %r13b
jmp 0x7db1
movl $0x0, 0xc(%rsp)
leaq 0x132ef(%rip), %rdi     # 0x1b190
movl %ebx, 0x10(%rsp)
jmp 0x7da1
movl $0x0, 0xc(%rsp)
leaq 0x131ed(%rip), %rdi     # 0x1b0a6
movq 0x10(%rsp), %rax
movl %eax, 0x10(%rsp)
jmp 0x7da1
movl $0x1, %eax
jmp 0x7ef5
leaq 0x13194(%rip), %rdi     # 0x1b069
jmp 0x7ede
leaq 0x131c8(%rip), %rdi     # 0x1b0a6
xorl %eax, %eax
callq 0x10418
movq $-0x1, %rax
jmp 0x7ef5
xorl %eax, %eax
jmp 0x7ef5
movq %rbp, %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x13292(%rip), %rdi     # 0x1b19d
jmp 0x7ede
leaq 0x1329f(%rip), %rdi     # 0x1b1b3
jmp 0x7ede
leaq 0x1d7c3(%rip), %rsi     # 0x256e0
leaq 0x28(%rsp), %rbx
movq %rbx, %rdi
callq 0x11fa0
movq (%rbx), %rsi
leaq 0x13299(%rip), %rdi     # 0x1b1cd
xorl %eax, %eax
callq 0x10418
leaq 0x38(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x7ee5
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3320
jmp 0x7ee5
movq %rax, %rbx
leaq 0x38(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x7f76
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3320
movq %rbx, %rdi
callq 0x3560