// File: /workspace/github_cpp_makefile_star2_O1/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, 0x8(%rsp)
movq %r8, %r12
movl %ecx, %ebp
movl %edx, 0x30(%rsp)
movq %rsi, (%rsp)
movq %rdi, 0x20(%rsp)
movslq %ecx, %rax
leaq 0x1a9bc(%rip), %r13     # 0x256e0
imulq $0xb0, %rax, %r15
movq 0x28(%r13), %rdi
addq %r15, %rdi
callq 0x111e4
testl %eax, %eax
je 0xad87
movq 0x28(%r13), %rax
movq 0x28(%rax,%r15), %rbx
btl $0x12, %ebx
setae %al
cmpq $0x2, %r12
setge %cl
orb %al, %cl
jne 0xaddf
movq 0x20(%rsp), %rdi
callq 0x10f22
leaq 0x1a975(%rip), %rdi     # 0x256e0
movl %eax, %esi
callq 0x111aa
cmpl $0x19, %eax
je 0xae0d
leaq 0x10a1b(%rip), %rdi     # 0x1b79d
jmp 0xaebe
leaq 0x1a952(%rip), %rbx     # 0x256e0
movq %rbx, %rdi
movl %ebp, %esi
callq 0x111aa
cmpq $0x3, %r12
jl 0xadbb
cmpl $0x2e, %eax
jne 0xadbb
movq 0x28(%rbx), %rax
movq 0x8(%rsp), %rcx
imulq $0xb0, 0x10(%rcx), %rcx
testb $0x20, 0x29(%rax,%rcx)
jne 0xad3b
leaq 0x1a91e(%rip), %rdi     # 0x256e0
movl %ebp, %esi
callq 0x1263e
leaq 0x109a1(%rip), %rdi     # 0x1b771
movq %rax, %rsi
xorl %eax, %eax
callq 0x10418
jmp 0xaec5
movl %ebp, %edi
callq 0x985c
cmpq $0x1, %r12
jg 0xadf0
testl %eax, %eax
jne 0xae0d
cmpq $0x2, %r12
setge %al
testb $0x2, %bl
sete %cl
orb %al, %cl
jne 0xae0d
leaq 0x109b8(%rip), %rdi     # 0x1b7c0
jmp 0xaebe
movq 0x28(%r13), %rax
testb $0x20, 0x28(%rax,%r15)
jne 0xaeb7
movq 0x20(%rsp), %rbx
movq %rbx, %rdi
callq 0x10f88
leaq 0x1a8af(%rip), %r14     # 0x256e0
movq %r14, %rdi
movq %rax, 0x18(%rsp)
movl %eax, %esi
callq 0x111aa
cmpl $0x22, %eax
jne 0xaedb
movl $0x0, 0x1a861(%rip)     # 0x256b4
movl %r12d, %edi
movq 0x8(%rsp), %rsi
movq (%rsp), %r13
movq %r13, %rdx
xorl %ecx, %ecx
movl $0x1, %r8d
xorl %r9d, %r9d
callq 0xa1a7
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
testl %eax, %eax
jne 0xaeca
movslq 0x18(%rsp), %rax
movq 0x28(%r14), %rcx
imulq $0xb0, %rax, %rax
movl 0x38(%rcx,%rax), %eax
leaq 0x34(%rsp), %rdi
movl %eax, (%rdi)
movl 0x8d4c(%r13), %esi
xorl %edx, %edx
callq 0x7550
movl %eax, %r13d
testl %eax, %eax
je 0xb0c7
xorl %r14d, %r14d
jmp 0xb191
leaq 0x10926(%rip), %rdi     # 0x1b7e4
xorl %eax, %eax
callq 0x10418
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movl %ebx, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movzbl 0x70(%rsp), %ecx
xorl %r14d, %r14d
movq %rbx, %rdi
movq (%rsp), %rsi
xorl %edx, %edx
callq 0x592e
testl %eax, %eax
js 0xaec5
leaq 0x1a7e4(%rip), %rbx     # 0x256e0
movq %rbx, %rdi
movq 0x18(%rsp), %r13
movl %r13d, %esi
callq 0x111aa
cmpl $0x1a, %eax
jne 0xb01b
movl %r14d, 0x2c(%rsp)
movslq %r13d, %rax
movq 0x28(%rbx), %r13
imulq $0xb0, %rax, %rax
movl 0x38(%r13,%rax), %ebx
movl %ebx, 0x14(%rsp)
movl %ebp, %edi
callq 0x985c
testl %eax, %eax
je 0xaf80
movq 0x38(%r13,%r15), %rcx
cmpq $0x1, %rcx
je 0xaf80
addl $-0xb, %ebx
cmpl $0x2, %ebx
jae 0xb130
movq (%rsp), %rbx
movq %rbx, %rdi
movl $0x6, %esi
movl $0x4, %edx
callq 0x1361c
movq %rbx, %rdi
movl $0x9, %esi
movl $0x3, %edx
movl $0x4, %ecx
callq 0x1361c
movq (%rsp), %r15
movq %r15, %rdi
movl $0x3, %esi
callq 0x13684
movl 0x8d4c(%r15), %ebx
movl %r12d, %edi
movq 0x8(%rsp), %rsi
movq %r15, %rdx
xorl %ecx, %ecx
xorl %r8d, %r8d
xorl %r9d, %r9d
callq 0xa1a7
testl %eax, %eax
jne 0xaec5
movl 0x8d4c(%r15), %esi
movl %ebx, %edi
movl $0x1, %edx
callq 0x76b5
testl %eax, %eax
jne 0xaec5
movl 0x8d4c(%r15), %edx
leaq 0x14(%rsp), %rdi
movl %ebx, %esi
callq 0x7550
testl %eax, %eax
jne 0xaec5
movq %r15, %rdi
movl $0x4, %esi
callq 0x136b2
movl 0x14(%rsp), %esi
movq %r15, %rdi
movl $0x3, %edx
movl $0x4, %ecx
callq 0x1361c
movl 0x2c(%rsp), %r14d
movq 0x18(%rsp), %r13
leaq 0x1a6be(%rip), %rdi     # 0x256e0
movl %r13d, %esi
callq 0x111aa
cmpl $0x19, %eax
jne 0xb092
movl %r14d, %r15d
leaq -0x1(%r12), %rbp
movq 0x8(%rsp), %r14
movl -0x8(%r14,%r12,8), %esi
leaq 0x1a698(%rip), %rbx     # 0x256e0
movq %rbx, %rdi
callq 0x111aa
cmpl $0x8, %eax
jne 0xb06b
movl %ebp, %edi
movq %r14, %rsi
callq 0x80c5
testl %eax, %eax
jle 0xb19f
movl %eax, %ebp
decl %ebp
movq (%rsp), %rdi
leaq 0x8d4c(%rdi), %rsi
movslq %ebp, %rax
movq 0x28(%rbx), %rcx
imulq $0xb0, (%r14,%rax,8), %rax
movswl 0x30(%rcx,%rax), %edx
callq 0x7fab
movl %r15d, %r14d
testl %r14d, %r14d
je 0xb0f6
movq 0x20(%rsp), %rdi
callq 0x10f88
leaq 0x1a638(%rip), %rdi     # 0x256e0
movl %eax, %esi
callq 0x111aa
cmpb $0x0, 0x30(%rsp)
je 0xb0ea
cmpl $0x6, %eax
je 0xb0ef
leaq 0x1078c(%rip), %rdi     # 0x1b84e
jmp 0xaebe
movl %ebp, %edi
callq 0x985c
testl %eax, %eax
movl $0x0, %r14d
je 0xb13c
leaq 0x1a601(%rip), %rax     # 0x256e0
movq 0x28(%rax), %rax
movl 0x38(%rax,%r15), %ecx
jmp 0xb141
cmpl $0x28, %eax
jne 0xb124
xorl %ebx, %ebx
jmp 0xaeca
movl %r12d, %edi
movq 0x8(%rsp), %rsi
movq (%rsp), %rdx
movl $0x1, %ecx
xorl %r8d, %r8d
xorl %r9d, %r9d
callq 0xa1a7
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
testl %eax, %eax
jne 0xaeca
jmp 0xb097
leaq 0x10730(%rip), %rdi     # 0x1b85b
jmp 0xaebe
leaq 0x106e1(%rip), %rdi     # 0x1b818
jmp 0xaebe
movl $0x1, %ecx
movl 0x34(%rsp), %esi
movq (%rsp), %rdi
movl $0x3, %edx
callq 0x1361c
cmpl $0x0, 0x1a55a(%rip)     # 0x256b4
jne 0xb191
movl 0x1a54e(%rip), %eax     # 0x256b0
cmpl $0x2, %eax
movl $0x1b, %ecx
movl $0x8, %edx
cmovel %ecx, %edx
cmpl $0x1, %eax
movl $0x1a, %esi
cmovnel %edx, %esi
movq (%rsp), %rdi
movl $0x3, %edx
callq 0x135fc
movl $0x1, %r14d
testl %r13d, %r13d
jne 0xaeca
jmp 0xaef5
leaq 0x10694(%rip), %rdi     # 0x1b83a
jmp 0xaebe