def compare_strings(self, lhs: Value, rhs: Value, op: str, line: int) -> Value: """Compare two strings""" compare_result = self.call_c(unicode_compare, [lhs, rhs], line) error_constant = self.add(LoadInt(-1, line, c_int_rprimitive)) compare_error_check = self.add( ComparisonOp(compare_result, error_constant, ComparisonOp.EQ, line)) exception_check, propagate, final_compare = BasicBlock(), BasicBlock( ), BasicBlock() branch = Branch(compare_error_check, exception_check, final_compare, Branch.BOOL_EXPR) branch.negated = False self.add(branch) self.activate_block(exception_check) check_error_result = self.call_c(err_occurred_op, [], line) null = self.add(LoadInt(0, line, pointer_rprimitive)) compare_error_check = self.add( ComparisonOp(check_error_result, null, ComparisonOp.NEQ, line)) branch = Branch(compare_error_check, propagate, final_compare, Branch.BOOL_EXPR) branch.negated = False self.add(branch) self.activate_block(propagate) self.call_c(keep_propagating_op, [], line) self.goto(final_compare) self.activate_block(final_compare) op_type = ComparisonOp.EQ if op == '==' else ComparisonOp.NEQ return self.add( ComparisonOp(compare_result, self.add(LoadInt(0, line, c_int_rprimitive)), op_type, line))
def test_comparison_op(self) -> None: # signed self.assert_emit( ComparisonOp(self.s1, self.s2, ComparisonOp.SLT, 1), """cpy_r_r0 = (Py_ssize_t)cpy_r_s1 < (Py_ssize_t)cpy_r_s2;""") self.assert_emit( ComparisonOp(self.i32, self.i32_1, ComparisonOp.SLT, 1), """cpy_r_r0 = cpy_r_i32 < cpy_r_i32_1;""") self.assert_emit( ComparisonOp(self.i64, self.i64_1, ComparisonOp.SLT, 1), """cpy_r_r0 = cpy_r_i64 < cpy_r_i64_1;""") # unsigned self.assert_emit(ComparisonOp(self.s1, self.s2, ComparisonOp.ULT, 1), """cpy_r_r0 = cpy_r_s1 < cpy_r_s2;""") self.assert_emit( ComparisonOp(self.i32, self.i32_1, ComparisonOp.ULT, 1), """cpy_r_r0 = (uint32_t)cpy_r_i32 < (uint32_t)cpy_r_i32_1;""") self.assert_emit( ComparisonOp(self.i64, self.i64_1, ComparisonOp.ULT, 1), """cpy_r_r0 = (uint64_t)cpy_r_i64 < (uint64_t)cpy_r_i64_1;""") # object type self.assert_emit(ComparisonOp(self.o, self.o2, ComparisonOp.EQ, 1), """cpy_r_r0 = cpy_r_o == cpy_r_o2;""") self.assert_emit(ComparisonOp(self.o, self.o2, ComparisonOp.NEQ, 1), """cpy_r_r0 = cpy_r_o != cpy_r_o2;""")
def translate_is_op(self, lreg: Value, rreg: Value, expr_op: str, line: int) -> Value: """Create equality comparison operation between object identities Args: expr_op: either 'is' or 'is not' """ op = ComparisonOp.EQ if expr_op == 'is' else ComparisonOp.NEQ lhs = self.coerce(lreg, object_rprimitive, line) rhs = self.coerce(rreg, object_rprimitive, line) return self.add(ComparisonOp(lhs, rhs, op, line))
def comparison_op(self, lhs: Value, rhs: Value, op: int, line: int) -> Value: return self.add(ComparisonOp(lhs, rhs, op, line))