// File: AshOlogn[P]ash-language-interpreter/src/typehandler.cpp
// Function: typecheckArithmeticExpression(ParseOperatorType, ParseDataType, ParseDataType)
bool typecheckArithmeticExpression(ParseOperatorType op, ParseDataType l, ParseDataType r) {
  
  switch(op) {
  
    case EXPONENT_OP: return isNumberParseDataType(l) && isNumberParseDataType(r);
    case DIVIDE_OP: return isNumberParseDataType(l) && isNumberParseDataType(r);
    case MULTIPLY_OP: return (isNumberParseDataType(l) && isNumberParseDataType(r)) ||
                             (isIntParseDataType(l) && r == STRING_T) ||
                             (l == STRING_T && isIntParseDataType(r)) ||
														 (isIntParseDataType(l) && r == ARRAY_T) ||
                             (l == ARRAY_T && isIntParseDataType(r));

    case MOD_OP: return isNumberParseDataType(l) && isNumberParseDataType(r);

    case ADD_OP: return l == STRING_T || r == STRING_T ||
												(l == ARRAY_T && r == ARRAY_T) ||
                        (isNumberParseDataType(l) && isNumberParseDataType(r));

    case SUBTRACT_OP: return isNumberParseDataType(l) && isNumberParseDataType(r);
    default: return false;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movl %edi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movl -0x8(%rbp), %eax
addl $-0xb, %eax
movl %eax, %ecx
movq %rcx, -0x18(%rbp)
subl $0x5, %eax
ja 0x2b8be
movq -0x18(%rbp), %rax
leaq 0x18d97(%rip), %rcx     # 0x444a8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl -0xc(%rbp), %edi
callq 0xb1c0
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x19(%rbp)
jne 0x2b730
jmp 0x2b73b
movl -0x10(%rbp), %edi
callq 0xb1c0
movb %al, -0x19(%rbp)
movb -0x19(%rbp), %al
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0x2b8c2
movl -0xc(%rbp), %edi
callq 0xb1c0
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x1a(%rbp)
jne 0x2b75e
jmp 0x2b769
movl -0x10(%rbp), %edi
callq 0xb1c0
movb %al, -0x1a(%rbp)
movb -0x1a(%rbp), %al
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0x2b8c2
movl -0xc(%rbp), %edi
callq 0xb1c0
testb $0x1, %al
jne 0x2b784
jmp 0x2b798
movl -0x10(%rbp), %edi
callq 0xb1c0
movb %al, %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x1b(%rbp)
jne 0x2b800
movl -0xc(%rbp), %edi
callq 0xb240
testb $0x1, %al
jne 0x2b7a6
jmp 0x2b7b1
movb $0x1, %al
cmpl $0xb, -0x10(%rbp)
movb %al, -0x1b(%rbp)
je 0x2b800
cmpl $0xb, -0xc(%rbp)
jne 0x2b7cb
movl -0x10(%rbp), %edi
callq 0xb240
movb %al, %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x1b(%rbp)
jne 0x2b800
movl -0xc(%rbp), %edi
callq 0xb240
testb $0x1, %al
jne 0x2b7d9
jmp 0x2b7e4
movb $0x1, %al
cmpl $0xc, -0x10(%rbp)
movb %al, -0x1b(%rbp)
je 0x2b800
xorl %eax, %eax
cmpl $0xc, -0xc(%rbp)
movb %al, -0x1c(%rbp)
jne 0x2b7fa
movl -0x10(%rbp), %edi
callq 0xb240
movb %al, -0x1c(%rbp)
movb -0x1c(%rbp), %al
movb %al, -0x1b(%rbp)
movb -0x1b(%rbp), %al
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0x2b8c2
movl -0xc(%rbp), %edi
callq 0xb1c0
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x1d(%rbp)
jne 0x2b823
jmp 0x2b82e
movl -0x10(%rbp), %edi
callq 0xb1c0
movb %al, -0x1d(%rbp)
movb -0x1d(%rbp), %al
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0x2b8c2
movb $0x1, %al
cmpl $0xb, -0xc(%rbp)
movb %al, -0x1e(%rbp)
je 0x2b889
movb $0x1, %al
cmpl $0xb, -0x10(%rbp)
movb %al, -0x1e(%rbp)
je 0x2b889
cmpl $0xc, -0xc(%rbp)
jne 0x2b862
movb $0x1, %al
cmpl $0xc, -0x10(%rbp)
movb %al, -0x1e(%rbp)
je 0x2b889
movl -0xc(%rbp), %edi
callq 0xb1c0
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x1f(%rbp)
jne 0x2b878
jmp 0x2b883
movl -0x10(%rbp), %edi
callq 0xb1c0
movb %al, -0x1f(%rbp)
movb -0x1f(%rbp), %al
movb %al, -0x1e(%rbp)
movb -0x1e(%rbp), %al
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0x2b8c2
movl -0xc(%rbp), %edi
callq 0xb1c0
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x20(%rbp)
jne 0x2b8a9
jmp 0x2b8b4
movl -0x10(%rbp), %edi
callq 0xb1c0
movb %al, -0x20(%rbp)
movb -0x20(%rbp), %al
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0x2b8c2
movb $0x0, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x20, %rsp
popq %rbp
retq
nopl (%rax)