// File: /workspace/github_cpp_makefile_star2_O2/rofl0r[P]ascc/cs_parser.cpp
// Function: evaluate_assignment(ccInternalList*, ccCompiledScript*, bool, int, long, long*, bool)
int evaluate_assignment(ccInternalList *targ, ccCompiledScript *scrip, bool expectCloseBracket, int cursym, long lilen, long *vnlist, bool insideBracketedDeclaration) {
    if (!sym.entries[cursym].is_loadable_variable()) {
        // allow through static properties
        if ((sym.get_type(cursym) == SYM_VARTYPE) && (lilen > 2) &&
            (sym.entries[vnlist[2]].flags & SFLG_STATIC))
        { }
        else {
            cc_error("variable required on left of assignment %s ", sym.get_name(cursym));
            return -1;
        }
    }
    bool isAccessingDynamicArray = false;

    if (((sym.entries[cursym].flags & SFLG_DYNAMICARRAY) != 0) && (lilen < 2))
    {
        if (sym.get_type(targ->peeknext()) != SYM_ASSIGN)
        {
            cc_error("invalid use of operator with array");
            return -1;
        }
        isAccessingDynamicArray = true;
    }
    else if (isRawPointer(cursym) && (lilen < 2)) { }
    else if (((sym.entries[cursym].flags & SFLG_ARRAY) != 0) && (lilen < 2))
    {
        cc_error("cannot assign value to entire array");
        return -1;
    }
    if (sym.entries[cursym].flags & SFLG_ISSTRING) {
        cc_error ("cannot assign to string; use Str* functions instead");
        return -1;
    }
    int MARIntactAssumption = 0;
    int asstype = targ->getnext();
    if (sym.get_type(asstype) == SYM_SASSIGN) {

        // ++ or --
        readonly_cannot_cause_error = 0;

        if (read_variable_into_ax(lilen,&vnlist[0],scrip, 1))
            return -1;

        int cpuOp = sym.entries[asstype].ssize;

        if (check_operator_valid_for_type(&cpuOp, scrip->ax_val_type, 0))
            return -1;

        int addend = 1;
        if (isRawPointer(cursym)) addend = sym.entries[cursym].ssize;

        scrip->write_cmd2(cpuOp, SREG_AX, addend);

        if (!readonly_cannot_cause_error) {
            MARIntactAssumption = 1;
            // since the MAR won't have changed, we can directly write
            // the value back to it without re-calculating the offset
            scrip->write_cmd1(get_readcmd_for_size(readcmd_lastcalledwith,1),SREG_AX);
        }
    }
    // not ++ or --, so we need to evaluate the RHS
    else if (evaluate_expression(targ,scrip,0,insideBracketedDeclaration) < 0)
        return -1;

    if (sym.get_type(asstype) == SYM_MASSIGN) {
        // it's a += or -=, so read in and adjust the result
        int cpuOp = sym.entries[asstype].ssize;

        if(isRawPointer(cursym) && sym.entries[cursym].ssize != 1) {
            if (!(cpuOp == SCMD_SUBREG || cpuOp == SCMD_ADDREG)) {
                cc_error("invalid operation for raw pointer");
                return -1;
            }
            // got to multiply the addend by pointed-to size
            scrip->write_cmd2(SCMD_LITTOREG, SREG_BX, sym.entries[cursym].ssize);
            scrip->write_cmd2(SCMD_MULREG, SREG_AX, SREG_BX);
        }

        // ax contains the addend
        scrip->push_reg(SREG_AX);
        int varTypeRHS = scrip->ax_val_type;

        if (read_variable_into_ax(lilen,&vnlist[0],scrip))
            return -1;
        if (check_type_mismatch(varTypeRHS, scrip->ax_val_type, 1))
            return -1;

        if (check_operator_valid_for_type(&cpuOp, varTypeRHS, scrip->ax_val_type))
            return -1;

        scrip->pop_reg(SREG_BX);
        scrip->write_cmd2(cpuOp, SREG_AX, SREG_BX);
    }

    if (sym.get_type(asstype) == SYM_ASSIGN) {
        // Convert normal literal string into String object
        int finalPartOfLHS = lilen - 1;
        if (sym.get_type(vnlist[lilen - 1]) == SYM_CLOSEBRACKET) {
            // deal with  a[1] = b
            finalPartOfLHS = findOpeningBracketOffs(lilen - 1, vnlist) - 1;
            if (finalPartOfLHS < 0) {
                cc_error("No [ for ] to match");
                return -1;
            }
        }
        PerformStringConversionInAX(scrip, &scrip->ax_val_type, sym.entries[vnlist[finalPartOfLHS]].vartype);
    }

    if (MARIntactAssumption) ;
    // so copy the result (currently in AX) into the variable
    else if (write_ax_to_variable(lilen,&vnlist[0],scrip))
        return -1;

    if(expectCloseBracket) {
        if (sym.get_type(targ->getnext()) != SYM_CLOSEPARENTHESIS) {
            cc_error("Expected ')'");
            return -1;
        }
    }
    else
        if (sym.get_type(targ->getnext()) != SYM_SEMICOLON) {
            cc_error("Expected ';'");
            return -1;
        }

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %r9, 0x28(%rsp)
movq %r8, %r12
movl %ecx, %ebp
movl %edx, 0x30(%rsp)
movq %rsi, 0x10(%rsp)
movq %rdi, %r14
movslq %ecx, %rax
leaq 0x1b73e(%rip), %r15     # 0x256f0
imulq $0xb0, %rax, %r13
movq 0x28(%r15), %rdi
addq %r13, %rdi
callq 0xfe92
testl %eax, %eax
je 0xa017
movq 0x28(%r15), %rax
movq 0x28(%rax,%r13), %r15
cmpq $0x1, %r12
jg 0xa06f
movl %r15d, %eax
andl $0x40000, %eax          # imm = 0x40000
je 0xa06f
movq %r14, %rdi
callq 0xfc58
leaq 0x1b6f7(%rip), %r15     # 0x256f0
movq %r15, %rdi
movl %eax, %esi
callq 0xfe60
cmpl $0x19, %eax
jne 0xa1b0
movq 0x28(%r15), %rax
movq 0x28(%rax,%r13), %r15
jmp 0xa088
leaq 0x1b6d2(%rip), %r15     # 0x256f0
movq %r15, %rdi
movl %ebp, %esi
callq 0xfe60
cmpq $0x3, %r12
jl 0xa04b
cmpl $0x2e, %eax
jne 0xa04b
movq 0x28(%r15), %rax
movq 0x28(%rsp), %rcx
imulq $0xb0, 0x10(%rcx), %rcx
testb $0x20, 0x29(%rax,%rcx)
jne 0x9fcd
leaq 0x1b69e(%rip), %rdi     # 0x256f0
movl %ebp, %esi
callq 0x10b48
leaq 0xf6f1(%rip), %rdi      # 0x19751
movq %rax, %rsi
xorl %eax, %eax
callq 0xf258
jmp 0xa1be
movl %ebp, %edi
callq 0x8d7d
cmpq $0x1, %r12
jg 0xa191
testl %eax, %eax
je 0xa191
testb $0x20, %r15b
jne 0xa188
movq %r14, %rdi
callq 0xfc84
movq %rax, %r15
leaq 0x1b64c(%rip), %rdi     # 0x256f0
movl %r15d, %esi
callq 0xfe60
cmpl $0x22, %eax
jne 0xa1d0
movq %r15, 0x20(%rsp)
andl $0x0, 0x1b603(%rip)     # 0x256c4
pushq $0x1
popq %rbx
movl %r12d, %edi
movq 0x28(%rsp), %rsi
movq 0x10(%rsp), %r15
movq %r15, %rdx
movl %ebx, %ecx
xorl %r8d, %r8d
callq 0x9f69
testl %eax, %eax
jne 0xa1be
movslq 0x20(%rsp), %rax
leaq 0x1b5fe(%rip), %rcx     # 0x256f0
movq 0x28(%rcx), %rcx
imulq $0xb0, %rax, %rax
movl 0x38(%rcx,%rax), %eax
leaq 0x34(%rsp), %rdi
movl %eax, (%rdi)
movl 0x8d4c(%r15), %esi
xorl %edx, %edx
callq 0x6e39
testl %eax, %eax
jne 0xa1be
movl %ebp, %edi
callq 0x8d7d
testl %eax, %eax
je 0xa139
leaq 0x1b5c0(%rip), %rax     # 0x256f0
movq 0x28(%rax), %rax
movl 0x38(%rax,%r13), %ebx
movl 0x34(%rsp), %esi
pushq $0x3
popq %rdx
movq 0x10(%rsp), %rdi
movl %ebx, %ecx
callq 0x11e6a
cmpl $0x0, 0x1b571(%rip)     # 0x256c4
setne %cl
movq 0x20(%rsp), %r15
jne 0xa1ea
movl 0x1b559(%rip), %edi     # 0x256c0
pushq $0x1
popq %rsi
movb %cl, 0xf(%rsp)
callq 0x79d7
pushq $0x3
popq %rdx
movq 0x10(%rsp), %rdi
movl %eax, %esi
callq 0x11e4a
movb 0xf(%rsp), %cl
jmp 0xa1ea
leaq 0xf635(%rip), %rdi      # 0x197c4
jmp 0xa1b7
cmpq $0x1, %r12
jg 0xa088
movl %r15d, %eax
andl $0x2, %eax
je 0xa088
leaq 0xf5f2(%rip), %rdi      # 0x197a0
jmp 0xa1b7
leaq 0xf5c6(%rip), %rdi      # 0x1977d
xorl %eax, %eax
callq 0xf258
pushq $-0x1
popq %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movzbl 0x70(%rsp), %ecx
movq %r14, %rdi
movq 0x10(%rsp), %rsi
xorl %edx, %edx
callq 0x55a5
movb $0x1, %cl
testl %eax, %eax
js 0xa1be
movb %cl, 0xf(%rsp)
leaq 0x1b4fb(%rip), %rbx     # 0x256f0
movq %rbx, %rdi
movl %r15d, %esi
callq 0xfe60
cmpl $0x1a, %eax
jne 0xa2f7
movq %r15, 0x20(%rsp)
movslq %r15d, %rax
movq 0x28(%rbx), %r15
imulq $0xb0, %rax, %rax
movl 0x38(%r15,%rax), %ebx
movl %ebx, 0x1c(%rsp)
movl %ebp, %edi
callq 0x8d7d
testl %eax, %eax
je 0xa26c
movq 0x38(%r15,%r13), %rcx
cmpq $0x1, %rcx
je 0xa26c
addl $-0xb, %ebx
cmpl $0x2, %ebx
jae 0xa3cf
pushq $0x6
popq %rsi
pushq $0x4
popq %rbp
movq 0x10(%rsp), %r15
movq %r15, %rdi
movl %ebp, %edx
callq 0x11e6a
pushq $0x9
popq %rsi
pushq $0x3
popq %rdx
movq %r15, %rdi
movl %ebp, %ecx
callq 0x11e6a
pushq $0x3
popq %rsi
movq 0x10(%rsp), %r15
movq %r15, %rdi
callq 0x11ed2
movl 0x8d4c(%r15), %ebp
movl %r12d, %edi
movq 0x28(%rsp), %rsi
movq %r15, %rdx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x9f69
testl %eax, %eax
jne 0xa1be
movl 0x8d4c(%r15), %esi
pushq $0x1
popq %rdx
movl %ebp, %edi
callq 0x6faa
testl %eax, %eax
jne 0xa1be
movl 0x8d4c(%r15), %edx
leaq 0x1c(%rsp), %rdi
movl %ebp, %esi
callq 0x6e39
testl %eax, %eax
jne 0xa1be
pushq $0x4
popq %rbp
movq %r15, %rdi
movl %ebp, %esi
callq 0x11eea
movl 0x1c(%rsp), %esi
pushq $0x3
popq %rdx
movq %r15, %rdi
movl %ebp, %ecx
callq 0x11e6a
movq 0x20(%rsp), %r15
leaq 0x1b3f2(%rip), %rdi     # 0x256f0
movl %r15d, %esi
callq 0xfe60
cmpl $0x19, %eax
movq 0x28(%rsp), %rbx
movq 0x10(%rsp), %r13
jne 0xa36c
leaq -0x1(%r12), %rbp
movl -0x8(%rbx,%r12,8), %esi
leaq 0x1b3ca(%rip), %r15     # 0x256f0
movq %r15, %rdi
callq 0xfe60
cmpl $0x8, %eax
jne 0xa349
movl %ebp, %edi
movq %rbx, %rsi
callq 0x7856
testl %eax, %eax
jle 0xa3db
movl %eax, %ebp
decl %ebp
leaq 0x8d4c(%r13), %rsi
movslq %ebp, %rax
movq 0x28(%r15), %rcx
imulq $0xb0, (%rbx,%rax,8), %rax
movswl 0x30(%rcx,%rax), %edx
movq %r13, %rdi
callq 0x7755
cmpb $0x0, 0xf(%rsp)
je 0xa389
movl %r12d, %edi
movq %rbx, %rsi
movq %r13, %rdx
callq 0x9f76
testl %eax, %eax
jne 0xa1be
movq %r14, %rdi
callq 0xfc84
leaq 0x1b358(%rip), %rdi     # 0x256f0
movl %eax, %esi
callq 0xfe60
cmpb $0x0, 0x30(%rsp)
je 0xa3b7
cmpl $0x6, %eax
je 0xa3bc
leaq 0xf47c(%rip), %rdi      # 0x1982e
jmp 0xa1b7
cmpl $0x28, %eax
jne 0xa3c3
xorl %eax, %eax
jmp 0xa1c1
leaq 0xf471(%rip), %rdi      # 0x1983b
jmp 0xa1b7
leaq 0xf422(%rip), %rdi      # 0x197f8
jmp 0xa1b7
leaq 0xf438(%rip), %rdi      # 0x1981a
jmp 0xa1b7