// File: baziotis[P]minijava-cpp/typecheck.cpp
// Function: track_while_assignment_for_expr(Expression*, Array<WhileAssign, (MEM)4>)
bool track_while_assignment_for_expr(Expression *expr, FuncArr<WhileAssign> track_buf) {
    switch (expr->kind) {
    case EXPR::ID:
    {
        for (WhileAssign& wa : track_buf) {
            Local *local = wa.local;
            if (expr->id == local->id) {
                if (!wa.used) {
                    if (!wa.assigned) {
                        wa.used = 1;
                    } else {
                        wa.used = 2;
                    }
                }
                break;
            }
        }
    } break;
    case EXPR::ARR_ALLOC:
    case EXPR::ARR_LEN:
    case EXPR::NOT:
    {
        track_while_assignment_for_expr(expr->e1, track_buf);
    } break;
    case EXPR::AND:
    case EXPR::CMP:
    case EXPR::PLUS:
    case EXPR::MINUS:
    case EXPR::TIMES:
    case EXPR::ARR_LOOK:
    {
        BinaryExpression *be = (BinaryExpression *) expr;
        track_while_assignment_for_expr(be->e1, track_buf);
        track_while_assignment_for_expr(be->e2, track_buf);
    } break;
    case EXPR::MSG_SEND:
    {
        BinaryExpression *be = (BinaryExpression *) expr;
        track_while_assignment_for_expr(be->e1, track_buf);
        for (Expression *e : be->msd->expr_list) {
            track_while_assignment_for_expr(e, track_buf);
        }
    } break;
    default: break;
    }
    return false;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
leaq 0x10(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movl 0x4(%rax), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0xe0(%rbp)
subl $0xd, %eax
ja 0x135ab
movq -0xe0(%rbp), %rax
leaq 0x83f5(%rip), %rcx      # 0x1b6c8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0xe8(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
callq 0x169e0
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rdi
callq 0x16a00
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rax
cmpq -0x20(%rbp), %rax
je 0x13391
movq -0x18(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x30(%rbp), %rcx
cmpq (%rcx), %rax
jne 0x1337e
movq -0x28(%rbp), %rax
movb 0x8(%rax), %al
shrb $0x2, %al
andb $0x3, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x1337c
movq -0x28(%rbp), %rax
movb 0x8(%rax), %al
andb $0x3, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x1336a
movq -0x28(%rbp), %rax
movb 0x8(%rax), %cl
andb $-0xd, %cl
orb $0x4, %cl
movb %cl, 0x8(%rax)
jmp 0x1337a
movq -0x28(%rbp), %rax
movb 0x8(%rax), %cl
andb $-0xd, %cl
orb $0x8, %cl
movb %cl, 0x8(%rax)
jmp 0x1337c
jmp 0x13391
jmp 0x13380
movq -0x18(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x18(%rbp)
jmp 0x13301
jmp 0x135ad
movq -0xe8(%rbp), %rax
movq -0x8(%rbp), %rcx
movq 0x10(%rcx), %rdi
movq (%rax), %rcx
movq %rcx, -0x48(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x40(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x38(%rbp)
leaq -0x48(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rax
movq %rax, 0x10(%rsp)
callq 0x13290
jmp 0x135ad
movq -0xe8(%rbp), %rax
movq -0x8(%rbp), %rcx
movq %rcx, -0x50(%rbp)
movq -0x50(%rbp), %rcx
movq 0x10(%rcx), %rdi
movq (%rax), %rcx
movq %rcx, -0x68(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x60(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x58(%rbp)
leaq -0x68(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rax
movq %rax, 0x10(%rsp)
callq 0x13290
movq -0xe8(%rbp), %rax
movq -0x50(%rbp), %rcx
movq 0x18(%rcx), %rdi
movq (%rax), %rcx
movq %rcx, -0x80(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x78(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x70(%rbp)
leaq -0x80(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rax
movq %rax, 0x10(%rsp)
callq 0x13290
jmp 0x135ad
movq -0xe8(%rbp), %rax
movq -0x8(%rbp), %rcx
movq %rcx, -0x88(%rbp)
movq -0x88(%rbp), %rcx
movq 0x10(%rcx), %rdi
movq (%rax), %rcx
movq %rcx, -0xa0(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x98(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x90(%rbp)
leaq -0xa0(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rax
movq %rax, 0x10(%rsp)
callq 0x13290
movq -0x88(%rbp), %rax
movq 0x18(%rax), %rax
addq $0x8, %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rdi
callq 0x39b0
movq %rax, -0xb0(%rbp)
movq -0xa8(%rbp), %rdi
callq 0x39d0
movq %rax, -0xb8(%rbp)
movq -0xb0(%rbp), %rax
cmpq -0xb8(%rbp), %rax
je 0x135a9
movq -0xe8(%rbp), %rax
movq -0xb0(%rbp), %rcx
movq (%rcx), %rcx
movq %rcx, -0xc0(%rbp)
movq -0xc0(%rbp), %rdi
movq (%rax), %rcx
movq %rcx, -0xd8(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0xd0(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0xc8(%rbp)
leaq -0xd8(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rax
movq %rax, 0x10(%rsp)
callq 0x13290
movq -0xb0(%rbp), %rax
addq $0x8, %rax
movq %rax, -0xb0(%rbp)
jmp 0x1351e
jmp 0x135ad
jmp 0x135ad
xorl %eax, %eax
andb $0x1, %al
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
nopw (%rax,%rax)