// File: 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
movq %rsp, %rbp
subq $0xa0, %rsp
movl %edi, -0xc(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x28(%rbp), %rax
movl $0xffffffff, (%rax)     # imm = 0xFFFFFFFF
movl $0x0, -0x2c(%rbp)
movslq -0xc(%rbp), %rsi
leaq 0x37b8a(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq %rax, %rdi
callq 0x1e260
cmpl $0x0, %eax
jne 0xad28
movl -0xc(%rbp), %esi
leaq 0x37b6a(%rip), %rdi     # 0x42870
callq 0x1e1e0
cmpl $0x2e, %eax
jne 0xad19
movl $0x1, -0x2c(%rbp)
jmp 0xad26
movq $0x0, -0x8(%rbp)
jmp 0xb522
jmp 0xad28
movq -0x18(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x30(%rbp)
movq $0x1, -0x38(%rbp)
movslq -0xc(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x18(%rbp), %rdi
callq 0x1dd60
cmpq $-0x1, %rax
jne 0xad61
movq -0x38(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xb522
movl $0x0, -0x3c(%rbp)
movq -0x18(%rbp), %rdi
callq 0x1dd60
movl %eax, %esi
leaq 0x37af6(%rip), %rdi     # 0x42870
callq 0x1e1e0
movl %eax, -0x40(%rbp)
movb $0x1, %al
cmpl $0x9, -0x40(%rbp)
movb %al, -0x85(%rbp)
je 0xad9d
cmpl $0x7, -0x40(%rbp)
sete %al
movb %al, -0x85(%rbp)
movb -0x85(%rbp), %al
testb $0x1, %al
jne 0xadac
jmp 0xb51a
movq -0x18(%rbp), %rdi
callq 0x1de00
movq %rax, %rdx
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rdi
callq 0x1dd60
movq %rax, %rdx
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
cmpq $-0x1, (%rax,%rcx,8)
jne 0xae12
leaq 0x271ff(%rip), %rdi     # 0x31ffd
movb $0x0, %al
callq 0x1bac0
movq $-0x1, -0x8(%rbp)
jmp 0xb522
cmpq $0x5f, -0x38(%rbp)
jl 0xae34
leaq 0x2721a(%rip), %rdi     # 0x3203a
movb $0x0, %al
callq 0x1bac0
movq $-0x1, -0x8(%rbp)
jmp 0xb522
cmpl $0x9, -0x40(%rbp)
jne 0xb178
movl -0xc(%rbp), %esi
leaq 0x37a28(%rip), %rdi     # 0x42870
callq 0x1e1e0
cmpl $0x2e, %eax
jne 0xae61
movl $0x1, -0x2c(%rbp)
movl -0xc(%rbp), %eax
movl %eax, -0x44(%rbp)
jmp 0xaea6
movl $0x0, -0x2c(%rbp)
movslq -0xc(%rbp), %rsi
leaq 0x379fd(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movswl 0x30(%rax), %eax
movl %eax, -0x44(%rbp)
cmpl $0x1, -0x44(%rbp)
jge 0xaea4
leaq 0x271fa(%rip), %rdi     # 0x3208a
movb $0x0, %al
callq 0x1bac0
movq $-0x1, -0x8(%rbp)
jmp 0xb522
jmp 0xaea6
movslq -0xc(%rbp), %rsi
leaq 0x379bf(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x2, %rax
cmpq $0x0, %rax
je 0xaee9
cmpl $0x0, -0x3c(%rbp)
jne 0xaee9
leaq 0x271dc(%rip), %rdi     # 0x320b1
movb $0x0, %al
callq 0x1bac0
movq $-0x1, -0x8(%rbp)
jmp 0xb522
movl $0x0, -0x3c(%rbp)
movl $0x0, -0x48(%rbp)
movslq -0xc(%rbp), %rsi
leaq 0x3796e(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x800, %rax            # imm = 0x800
cmpq $0x0, %rax
je 0xaf22
movl $0x1, -0x48(%rbp)
movl -0x44(%rbp), %edi
movq -0x20(%rbp), %rsi
movq -0x38(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
movl -0x48(%rbp), %edx
callq 0x8420
cmpl $0x0, %eax
je 0xaf4e
movq $-0x1, -0x8(%rbp)
jmp 0xb522
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
leaq 0x3790f(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x80, %rax
cmpq $0x0, %rax
jne 0xaf95
leaq 0x2713d(%rip), %rdi     # 0x320be
movb $0x0, %al
callq 0x1bac0
movq $-0x1, -0x8(%rbp)
jmp 0xb522
cmpl $0x0, -0x2c(%rbp)
je 0xafe2
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
leaq 0x378c2(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x2000, %rax           # imm = 0x2000
cmpq $0x0, %rax
jne 0xafe2
leaq 0x27114(%rip), %rdi     # 0x320e2
movb $0x0, %al
callq 0x1bac0
movq $-0x1, -0x8(%rbp)
jmp 0xb522
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl %eax, -0xc(%rbp)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rdi
callq 0x1de00
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
subq $0x1, %rcx
movq (%rax,%rcx,8), %rax
movl %eax, %esi
leaq 0x37851(%rip), %rdi     # 0x42870
callq 0x1e1e0
cmpl $0x4, %eax
jne 0xb173
movq -0x38(%rbp), %rax
subq $0x1, %rax
movl %eax, %ecx
movq -0x28(%rbp), %rax
movl %ecx, (%rax)
movq -0x18(%rbp), %rdi
callq 0x1de00
movq %rax, %rdx
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, -0x38(%rbp)
movq %rdx, (%rax,%rcx,8)
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
subq $0x1, %rcx
movq (%rax,%rcx,8), %rax
movl %eax, %esi
leaq 0x377f7(%rip), %rdi     # 0x42870
callq 0x1e1e0
cmpl $0x5, %eax
je 0xb09e
leaq 0x2709a(%rip), %rdi     # 0x32124
movb $0x0, %al
callq 0x1bac0
movq $-0x1, -0x8(%rbp)
jmp 0xb522
movl $0x1, -0x4c(%rbp)
cmpl $0x0, -0x4c(%rbp)
jle 0xb171
movq -0x18(%rbp), %rdi
callq 0x8a60
cmpl $0x0, %eax
je 0xb0ca
movq $-0x1, -0x8(%rbp)
jmp 0xb522
movq -0x18(%rbp), %rdi
callq 0x1de00
movq %rax, %rdx
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
cmpq $0x63, -0x38(%rbp)
jl 0xb104
leaq 0x26f4a(%rip), %rdi     # 0x3203a
movb $0x0, %al
callq 0x1bac0
movq $-0x1, -0x8(%rbp)
jmp 0xb522
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
subq $0x1, %rcx
movq (%rax,%rcx,8), %rax
movl %eax, %esi
leaq 0x37747(%rip), %rdi     # 0x42870
callq 0x1e1e0
cmpl $0x6, %eax
jne 0xb13e
movl -0x4c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0xb16c
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
subq $0x1, %rcx
movq (%rax,%rcx,8), %rax
movl %eax, %esi
leaq 0x37719(%rip), %rdi     # 0x42870
callq 0x1e1e0
cmpl $0x5, %eax
jne 0xb16a
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0xb16c
jmp 0xb0a5
jmp 0xb173
jmp 0xb4fb
cmpl $0x7, -0x40(%rbp)
jne 0xb4f9
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl %eax, %esi
leaq 0x376d9(%rip), %rdi     # 0x42870
callq 0x1e1e0
cmpl $0x17, %eax
jl 0xb207
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl %eax, %esi
leaq 0x376ba(%rip), %rdi     # 0x42870
callq 0x1e1e0
cmpl $0x2e, %eax
jne 0xb1ec
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
leaq 0x3769d(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x400, %rax            # imm = 0x400
cmpq $0x0, %rax
jne 0xb207
leaq 0x26f3e(%rip), %rdi     # 0x32131
movb $0x0, %al
callq 0x1bac0
movq $-0x1, -0x8(%rbp)
jmp 0xb522
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl %eax, %esi
leaq 0x37654(%rip), %rdi     # 0x42870
callq 0x1e1e0
cmpl $0x8, %eax
jne 0xb241
leaq 0x26f1a(%rip), %rdi     # 0x32147
movb $0x0, %al
callq 0x1bac0
movq $-0x1, -0x8(%rbp)
jmp 0xb522
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
subq $0x2, %rcx
movq (%rax,%rcx,8), %rsi
leaq 0x37618(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x2, %rax
cmpq $0x0, %rax
jne 0xb2e1
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movl -0x10(%rax,%rcx,8), %edx
leaq 0x375ee(%rip), %rsi     # 0x42870
leaq -0x70(%rbp), %rdi
movq %rdi, -0x90(%rbp)
callq 0x1f080
movq -0x90(%rbp), %rdi
callq 0x41b0
movq %rax, %rsi
leaq 0x26eb9(%rip), %rdi     # 0x32161
xorl %eax, %eax
callq 0x1bac0
jmp 0xb2b1
leaq -0x70(%rbp), %rdi
callq 0x4270
movq $-0x1, -0x8(%rbp)
jmp 0xb522
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x4270
jmp 0xb52f
movl $0x0, -0x80(%rbp)
leaq 0x37641(%rip), %rax     # 0x42930
movl (%rax), %eax
movl %eax, -0x84(%rbp)
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl %eax, %esi
leaq 0x37564(%rip), %rdi     # 0x42870
callq 0x1e1e0
movl %eax, %ecx
movb $0x1, %al
cmpl $0x17, %ecx
movb %al, -0x91(%rbp)
jl 0xb3b5
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl %eax, %esi
leaq 0x37537(%rip), %rdi     # 0x42870
callq 0x1e1e0
movl %eax, %ecx
movb $0x1, %al
cmpl $0x2a, %ecx
movb %al, -0x91(%rbp)
je 0xb3b5
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl %eax, %esi
leaq 0x3750e(%rip), %rdi     # 0x42870
callq 0x1e1e0
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x2e, %ecx
movb %al, -0x92(%rbp)
jne 0xb3a9
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
leaq 0x374e7(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x400, %rax            # imm = 0x400
cmpq $0x0, %rax
setne %al
movb %al, -0x92(%rbp)
movb -0x92(%rbp), %al
movb %al, -0x91(%rbp)
movb -0x91(%rbp), %al
testb $0x1, %al
jne 0xb3c4
jmp 0xb4f2
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
subq $0x1, %rcx
movq (%rax,%rcx,8), %rax
movl %eax, %esi
leaq 0x37493(%rip), %rdi     # 0x42870
callq 0x1e1e0
cmpl $0x2e, %eax
jne 0xb40b
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl %eax, %esi
leaq 0x37474(%rip), %rdi     # 0x42870
callq 0x1e1e0
cmpl $0x9, %eax
je 0xb40b
jmp 0xb4f2
movq -0x18(%rbp), %rdi
callq 0x1de00
cmpq $-0x1, %rax
jne 0xb444
movl -0x84(%rbp), %ecx
leaq 0x37509(%rip), %rax     # 0x42930
movl %ecx, (%rax)
leaq 0x26d44(%rip), %rdi     # 0x32174
movb $0x0, %al
callq 0x1bac0
movq $-0x1, -0x8(%rbp)
jmp 0xb522
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl %eax, %esi
leaq 0x37417(%rip), %rdi     # 0x42870
callq 0x1e1e0
cmpl $0x8, %eax
jne 0xb482
movl -0x80(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x80(%rbp)
cmpl $0x0, -0x80(%rbp)
jge 0xb480
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0xb4f2
jmp 0xb482
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl %eax, %esi
leaq 0x373d9(%rip), %rdi     # 0x42870
callq 0x1e1e0
cmpl $0x7, %eax
jne 0xb4aa
movl -0x80(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x80(%rbp)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
cmpq $0x63, -0x38(%rbp)
jl 0xb4d5
leaq 0x26b76(%rip), %rdi     # 0x3203a
movb $0x0, %al
callq 0x1bac0
movq $-0x1, -0x8(%rbp)
jmp 0xb522
movq -0x18(%rbp), %rdi
callq 0x1dd60
movq %rax, %rdx
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
jmp 0xb2f7
movl $0x1, -0x3c(%rbp)
jmp 0xb4fb
movq -0x18(%rbp), %rdi
callq 0x1dd60
movl %eax, %esi
leaq 0x37363(%rip), %rdi     # 0x42870
callq 0x1e1e0
movl %eax, -0x40(%rbp)
jmp 0xad82
movq -0x38(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xa0, %rsp
popq %rbp
retq
movq -0x78(%rbp), %rdi
callq 0x4670
nopl (%rax,%rax)