// File: /workspace/github_cpp_makefile_star2_O3/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, %r14
movq %r8, %r12
movl %ecx, %ebp
movl %edx, %r13d
movq %rsi, 0x8(%rsp)
movq %rdi, 0x20(%rsp)
movslq %ecx, %rax
leaq 0x1ac75(%rip), %rbx     # 0x256e0
imulq $0xb0, %rax, %r15
movq 0x28(%rbx), %rdi
addq %r15, %rdi
callq 0x110a8
testl %eax, %eax
je 0xaade
movq %r14, 0x18(%rsp)
movl %r13d, %r14d
movq 0x28(%rbx), %rax
movq 0x28(%rax,%r15), %rbx
btl $0x12, %ebx
setae %al
cmpq $0x2, %r12
setl %r13b
setge %cl
orb %al, %cl
jne 0xab4d
movq 0x20(%rsp), %r13
movq %r13, %rdi
callq 0x10e06
leaq 0x1ac1f(%rip), %rbx     # 0x256e0
movq %rbx, %rdi
movl %eax, %esi
callq 0x1106e
cmpl $0x19, %eax
jne 0xab31
movq 0x28(%rbx), %rax
movq 0x28(%rax,%r15), %rbx
jmp 0xab84
leaq 0x1abfb(%rip), %rbx     # 0x256e0
movq %rbx, %rdi
movl %ebp, %esi
callq 0x1106e
cmpq $0x3, %r12
jl 0xab0d
cmpl $0x2e, %eax
jne 0xab0d
movq 0x28(%rbx), %rax
imulq $0xb0, 0x10(%r14), %rcx
testb $0x20, 0x29(%rax,%rcx)
jne 0xab3d
leaq 0x1abcc(%rip), %rdi     # 0x256e0
movl %ebp, %esi
callq 0x124c6
leaq 0x10c4f(%rip), %rdi     # 0x1b771
movq %rax, %rsi
xorl %eax, %eax
callq 0x102f4
jmp 0xac4a
leaq 0x10c65(%rip), %rdi     # 0x1b79d
jmp 0xac43
movq %r14, 0x18(%rsp)
movl %r13d, %r14d
movq 0x28(%rax,%r15), %rbx
xorl %r13d, %r13d
movl %ebp, %edi
callq 0x96f7
testb %r13b, %r13b
je 0xab64
testl %eax, %eax
je 0xab64
movq 0x20(%rsp), %r13
jmp 0xab84
testb $0x2, %bl
sete %al
xorb $0x1, %r13b
orb %al, %r13b
movq 0x20(%rsp), %r13
jne 0xab84
leaq 0x10c41(%rip), %rdi     # 0x1b7c0
jmp 0xac43
testb $0x20, %bl
jne 0xac3c
movq %r13, %rdi
callq 0x10e44
leaq 0x1ab44(%rip), %rdi     # 0x256e0
movq %rax, 0x28(%rsp)
movl %eax, %esi
callq 0x1106e
cmpl $0x22, %eax
jne 0xac60
movl $0x0, 0x1aaf9(%rip)     # 0x256b4
movl %r12d, %edi
movq 0x18(%rsp), %rsi
movq 0x8(%rsp), %r13
movq %r13, %rdx
xorl %ecx, %ecx
movl $0x1, %r8d
xorl %r9d, %r9d
callq 0xa009
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
testl %eax, %eax
jne 0xac4f
movslq 0x28(%rsp), %rax
leaq 0x1aaf0(%rip), %rcx     # 0x256e0
movq 0x28(%rcx), %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 0x7455
testl %eax, %eax
jne 0xac4f
movl %ebp, %edi
callq 0x96f7
testl %eax, %eax
je 0xae8c
leaq 0x1aab2(%rip), %rax     # 0x256e0
movq 0x28(%rax), %rax
movl 0x38(%rax,%r15), %ecx
jmp 0xae91
leaq 0x10ba1(%rip), %rdi     # 0x1b7e4
xorl %eax, %eax
callq 0x102f4
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
movq %r13, %rdi
movq 0x8(%rsp), %rsi
xorl %edx, %edx
callq 0x5897
movb $0x1, %bl
testl %eax, %eax
js 0xac4a
movb %bl, 0x7(%rsp)
leaq 0x1aa5b(%rip), %rbx     # 0x256e0
movq %rbx, %rdi
movq 0x28(%rsp), %r13
movl %r13d, %esi
callq 0x1106e
cmpl $0x1a, %eax
jne 0xad94
movslq %r13d, %rax
movq 0x28(%rbx), %r13
imulq $0xb0, %rax, %rax
movl 0x38(%r13,%rax), %ebx
movl %ebx, 0x14(%rsp)
movl %ebp, %edi
callq 0x96f7
testl %eax, %eax
movq 0x8(%rsp), %rbp
je 0xad05
movq 0x38(%r13,%r15), %rcx
cmpq $0x1, %rcx
je 0xad05
addl $-0xb, %ebx
cmpl $0x2, %ebx
jae 0xae80
movq %rbp, %rdi
movl $0x6, %esi
movl $0x4, %edx
callq 0x1348e
movq %rbp, %rdi
movl $0x9, %esi
movl $0x3, %edx
movl $0x4, %ecx
callq 0x1348e
movq %rbp, %rdi
movl $0x3, %esi
callq 0x134f6
movl 0x8d4c(%rbp), %ebx
movl %r12d, %edi
movq 0x18(%rsp), %rsi
movq %rbp, %rdx
xorl %ecx, %ecx
xorl %r8d, %r8d
xorl %r9d, %r9d
callq 0xa009
testl %eax, %eax
jne 0xac4a
movl 0x8d4c(%rbp), %esi
movl %ebx, %edi
movl $0x1, %edx
callq 0x75b3
testl %eax, %eax
jne 0xac4a
movl 0x8d4c(%rbp), %edx
leaq 0x14(%rsp), %rdi
movl %ebx, %esi
callq 0x7455
testl %eax, %eax
jne 0xac4a
movq %rbp, %rdi
movl $0x4, %esi
callq 0x13524
movl 0x14(%rsp), %esi
movq %rbp, %rdi
movl $0x3, %edx
movl $0x4, %ecx
callq 0x1348e
movq 0x28(%rsp), %r13
leaq 0x1a945(%rip), %rdi     # 0x256e0
movl %r13d, %esi
callq 0x1106e
cmpl $0x19, %eax
movq 0x18(%rsp), %r13
movq 0x8(%rsp), %rbp
jne 0xae0d
leaq -0x1(%r12), %r15
movl -0x8(%r13,%r12,8), %esi
leaq 0x1a91d(%rip), %rbx     # 0x256e0
movq %rbx, %rdi
callq 0x1106e
cmpl $0x8, %eax
jne 0xade9
movl %r15d, %edi
movq %r13, %rsi
callq 0x7f6f
testl %eax, %eax
jle 0xaee9
movl %eax, %r15d
decl %r15d
leaq 0x8d4c(%rbp), %rsi
movslq %r15d, %rax
movq 0x28(%rbx), %rcx
imulq $0xb0, (%r13,%rax,8), %rax
movswl 0x30(%rcx,%rax), %edx
movq %rbp, %rdi
callq 0x7e72
cmpb $0x0, 0x7(%rsp)
je 0xae3a
movl %r12d, %edi
movq %r13, %rsi
movq %rbp, %rdx
movl $0x1, %ecx
xorl %r8d, %r8d
xorl %r9d, %r9d
callq 0xa009
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
testl %eax, %eax
jne 0xac4f
movq 0x20(%rsp), %rdi
callq 0x10e44
leaq 0x1a895(%rip), %rdi     # 0x256e0
movl %eax, %esi
callq 0x1106e
testb %r14b, %r14b
je 0xae68
cmpl $0x6, %eax
je 0xae6d
leaq 0x109eb(%rip), %rdi     # 0x1b84e
jmp 0xac43
cmpl $0x28, %eax
jne 0xae74
xorl %ebx, %ebx
jmp 0xac4f
leaq 0x109e0(%rip), %rdi     # 0x1b85b
jmp 0xac43
leaq 0x10991(%rip), %rdi     # 0x1b818
jmp 0xac43
movl $0x1, %ecx
movl 0x34(%rsp), %esi
movq 0x8(%rsp), %rdi
movl $0x3, %edx
callq 0x1348e
cmpl $0x0, 0x1a809(%rip)     # 0x256b4
setne %bl
jne 0xac7a
movl 0x1a7f6(%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 0x8(%rsp), %rdi
movl $0x3, %edx
callq 0x1346e
jmp 0xac7a
leaq 0x1094a(%rip), %rdi     # 0x1b83a
jmp 0xac43