// File: /workspace/github_cpp_makefile_star2_O3/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, %r12
movq %rdx, %r14
movq %rsi, %r15
movl %edi, %r13d
movl $0xffffffff, (%rcx)     # imm = 0xFFFFFFFF
movslq %edi, %rbx
leaq 0x1dd7e(%rip), %rax     # 0x256e0
imulq $0xb0, %rbx, %rdi
addq 0x28(%rax), %rdi
callq 0x110a8
testl %eax, %eax
jne 0x798e
leaq 0x1dd63(%rip), %rdi     # 0x256e0
movl %r13d, %esi
callq 0x1106e
cmpl $0x2e, %eax
jne 0x7d50
movq %rbx, (%r14)
movq %r15, %rdi
callq 0x10e06
cmpq $-0x1, %rax
je 0x7d3a
movq %r13, 0x10(%rsp)
movq %r12, 0x20(%rsp)
movl $0x0, 0xc(%rsp)
movl $0x1, %ebx
movq %rbx, %r12
movq %r15, %rdi
callq 0x10e06
leaq 0x1dd14(%rip), %rdi     # 0x256e0
movl %eax, %esi
callq 0x1106e
movl %eax, %ebp
cmpl $0x9, %eax
je 0x79e3
cmpl $0x7, %ebp
jne 0x7d78
movq %r15, %rdi
callq 0x10e44
movq %rax, (%r14,%r12,8)
movq %r15, %rdi
callq 0x10e06
movq %rax, 0x8(%r14,%r12,8)
cmpq $-0x1, %rax
je 0x7d6c
cmpq $0x5e, %r12
jge 0x7d44
leaq 0x1(%r12), %r13
leaq (%r14,%r12,8), %rcx
addq $0x8, %rcx
movq %rcx, 0x18(%rsp)
cmpl $0x7, %ebp
je 0x7bc9
movq %r13, %rbx
cmpl $0x9, %ebp
jne 0x79ba
leaq 0x1dca6(%rip), %rbx     # 0x256e0
movq %rbx, %rdi
movq 0x10(%rsp), %rbp
movl %ebp, %esi
callq 0x1106e
movq 0x28(%rbx), %rsi
movslq %ebp, %rcx
cmpl $0x2e, %eax
je 0x7a6e
imulq $0xb0, %rcx, %rdx
movswl 0x30(%rsi,%rdx), %edx
movq %rdx, 0x10(%rsp)
testl %edx, %edx
jle 0x7def
imulq $0xb0, %rcx, %rcx
movq 0x28(%rsi,%rcx), %rdx
movl %edx, %esi
shrb %sil
cmpl $0x0, 0xc(%rsp)
sete %cl
andb %sil, %cl
cmpb $0x1, %cl
je 0x7d89
movl %eax, %ebp
shrl $0xb, %edx
andl $0x1, %edx
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %rbx
movq %rbx, %rsi
callq 0x5dd2
movq $-0x1, %rcx
testl %eax, %eax
jne 0x7e0d
movq (%rbx), %rcx
leaq 0x1dc1a(%rip), %rax     # 0x256e0
movq 0x28(%rax), %rax
movq %rcx, 0x10(%rsp)
imulq $0xb0, %rcx, %rcx
movq 0x28(%rax,%rcx), %rax
testb %al, %al
jns 0x7ddd
cmpl $0x2e, %ebp
setne %cl
shrl $0xd, %eax
andl $0x1, %eax
orb %cl, %al
je 0x7de6
leaq 0x2(%r12), %rbx
movq %r15, %rdi
callq 0x10e44
movq 0x18(%rsp), %rax
movl (%rax), %esi
leaq 0x1dbce(%rip), %rdi     # 0x256e0
callq 0x1106e
movl $0x0, 0xc(%rsp)
cmpl $0x4, %eax
jne 0x79ba
movq 0x20(%rsp), %rax
movl %r13d, (%rax)
movq %r15, %rdi
callq 0x10e44
movq %rax, 0x10(%r14,%r12,8)
leaq 0x1db9c(%rip), %rdi     # 0x256e0
movl %eax, %esi
callq 0x1106e
cmpl $0x5, %eax
jne 0x7df8
addq $0x3, %r12
movl $0x1, %ebp
movq %r12, %rbx
leaq 0x1db79(%rip), %r12     # 0x256e0
movq %r15, %rdi
callq 0x626b
testl %eax, %eax
jne 0x7e06
movq %r15, %rdi
callq 0x10e44
movq %rax, (%r14,%rbx,8)
cmpq $0x63, %rbx
jge 0x7d44
movq %r12, %rdi
movl %eax, %esi
callq 0x1106e
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmpl $0x6, %eax
je 0x7bb5
movl (%r14,%rbx,8), %esi
movq %r12, %rdi
callq 0x1106e
xorl %ecx, %ecx
cmpl $0x5, %eax
sete %cl
incq %rbx
addl %ecx, %ebp
jg 0x7b67
movl $0x0, 0xc(%rsp)
jmp 0x79ba
leaq 0x1db10(%rip), %rbx     # 0x256e0
movq %rbx, %rdi
movl %eax, %esi
callq 0x1106e
movq 0x18(%rsp), %rbp
movq (%rbp), %rsi
cmpl $0x17, %eax
jl 0x7c13
movq %rbx, %rdi
callq 0x1106e
cmpl $0x2e, %eax
jne 0x7d80
movq (%rbp), %rsi
movq 0x28(%rbx), %rax
imulq $0xb0, %rsi, %rcx
testb $0x4, 0x29(%rax,%rcx)
je 0x7d80
movq %rbx, %rdi
callq 0x1106e
cmpl $0x8, %eax
je 0x7d92
movq -0x8(%r14,%r12,8), %rdx
movq 0x28(%rbx), %rax
imulq $0xb0, %rdx, %rcx
testb $0x2, 0x28(%rax,%rcx)
je 0x7d9b
movq %rbx, %r12
leaq 0x1db57(%rip), %rax     # 0x257a0
movl (%rax), %ebx
movq (%rbp), %rsi
xorl %ebp, %ebp
movq %r12, %rdi
callq 0x1106e
cmpl $0x17, %eax
jl 0x7c9c
movl (%r14,%r13,8), %esi
movq %r12, %rdi
callq 0x1106e
cmpl $0x2a, %eax
je 0x7c9c
movl (%r14,%r13,8), %esi
movq %r12, %rdi
callq 0x1106e
cmpl $0x2e, %eax
jne 0x7d2a
movq 0x28(%r12), %rax
imulq $0xb0, (%r14,%r13,8), %rcx
testb $0x4, 0x29(%rax,%rcx)
je 0x7d2a
movl -0x8(%r14,%r13,8), %esi
movq %r12, %rdi
callq 0x1106e
cmpl $0x2e, %eax
jne 0x7cbf
movl (%r14,%r13,8), %esi
movq %r12, %rdi
callq 0x1106e
cmpl $0x9, %eax
jne 0x7d2a
movq %r15, %rdi
callq 0x10e44
cmpq $-0x1, %rax
je 0x7d57
movl (%r14,%r13,8), %esi
movq %r12, %rdi
callq 0x1106e
cmpl $0x8, %eax
jne 0x7ce8
testl %ebp, %ebp
jle 0x7d27
decl %ebp
movl (%r14,%r13,8), %esi
movq %r12, %rdi
callq 0x1106e
cmpq $0x62, %r13
jge 0x7d44
leaq 0x1(%r13), %r12
xorl %ecx, %ecx
cmpl $0x7, %eax
sete %cl
addl %ecx, %ebp
movq %r15, %rdi
callq 0x10e06
movq %rax, %rsi
movq %rax, 0x8(%r14,%r13,8)
movq %r12, %r13
leaq 0x1d9be(%rip), %r12     # 0x256e0
jmp 0x7c51
incq %r13
movl $0x1, 0xc(%rsp)
movq %r13, %rbx
jmp 0x79ba
movl $0x1, %ecx
jmp 0x7e0d
leaq 0x1335b(%rip), %rdi     # 0x1b0a6
jmp 0x7dff
xorl %ecx, %ecx
jmp 0x7e0d
leaq 0x1da42(%rip), %rax     # 0x257a0
movl %ebx, (%rax)
leaq 0x13479(%rip), %rdi     # 0x1b1e0
jmp 0x7dff
leaq 0x132f6(%rip), %rdi     # 0x1b069
jmp 0x7dff
movq %r12, %rcx
jmp 0x7e0d
leaq 0x13416(%rip), %rdi     # 0x1b19d
jmp 0x7dff
leaq 0x1338d(%rip), %rdi     # 0x1b11d
jmp 0x7dff
leaq 0x1341a(%rip), %rdi     # 0x1b1b3
jmp 0x7dff
leaq 0x1d93e(%rip), %rsi     # 0x256e0
leaq 0x28(%rsp), %rbx
movq %rbx, %rdi
callq 0x11e2c
movq (%rbx), %rsi
leaq 0x13414(%rip), %rdi     # 0x1b1cd
xorl %eax, %eax
callq 0x102f4
leaq 0x38(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x7e06
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3320
jmp 0x7e06
leaq 0x13346(%rip), %rdi     # 0x1b12a
jmp 0x7dff
leaq 0x13361(%rip), %rdi     # 0x1b14e
jmp 0x7dff
leaq 0x13300(%rip), %rdi     # 0x1b0f6
jmp 0x7dff
leaq 0x13391(%rip), %rdi     # 0x1b190
xorl %eax, %eax
callq 0x102f4
movq $-0x1, %rcx
movq %rcx, %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x38(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x7e3d
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3320
movq %rbx, %rdi
callq 0x3560