diff --git a/src/compile.c b/src/compile.c index 05cc7bc..2109148 100644 --- a/src/compile.c +++ b/src/compile.c @@ -2630,19 +2630,21 @@ CORD compile(env_t *env, ast_t *ast) type_t *lhs_t = get_type(env, cmp.lhs); type_t *rhs_t = get_type(env, cmp.rhs); type_t *operand_t; - CORD lhs, rhs; - if (can_compile_to_type(env, cmp.rhs, lhs_t)) { - lhs = compile(env, cmp.lhs); - rhs = compile_to_type(env, cmp.rhs, lhs_t); + if (cmp.lhs->tag == Int && is_numeric_type(rhs_t)) { + operand_t = rhs_t; + } else if (cmp.rhs->tag == Int && is_numeric_type(lhs_t)) { + operand_t = lhs_t; + } else if (can_compile_to_type(env, cmp.rhs, lhs_t)) { operand_t = lhs_t; } else if (can_compile_to_type(env, cmp.lhs, rhs_t)) { - rhs = compile(env, cmp.rhs); - lhs = compile_to_type(env, cmp.lhs, rhs_t); operand_t = rhs_t; } else { code_err(ast, "I can't do comparisons between ", type_to_str(lhs_t), " and ", type_to_str(rhs_t)); } + CORD lhs = compile_to_type(env, cmp.lhs, operand_t); + CORD rhs = compile_to_type(env, cmp.rhs, operand_t); + if (ast->tag == Compare) return CORD_all("generic_compare(stack(", lhs, "), stack(", rhs, "), ", compile_type_info(operand_t), ")"); diff --git a/src/typecheck.c b/src/typecheck.c index 85f159c..1bef98c 100644 --- a/src/typecheck.c +++ b/src/typecheck.c @@ -1149,22 +1149,14 @@ type_t *get_type(env_t *env, ast_t *ast) } code_err(ast, "I couldn't figure out how to do `xor` between ", type_to_str(lhs_t), " and ", type_to_str(rhs_t)); } - case Compare: { - binary_operands_t binop = BINARY_OPERANDS(ast); - type_t *lhs_t = get_type(env, binop.lhs); - type_t *rhs_t = get_type(env, binop.rhs); - - if (can_promote(rhs_t, lhs_t) || can_promote(lhs_t, rhs_t)) - return Type(IntType, .bits=TYPE_IBITS32); - - code_err(ast, "I don't know how to compare ", type_to_str(lhs_t), " and ", type_to_str(rhs_t)); - } + case Compare: case Equals: case NotEquals: case LessThan: case LessThanOrEquals: case GreaterThan: case GreaterThanOrEquals: { binary_operands_t binop = BINARY_OPERANDS(ast); type_t *lhs_t = get_type(env, binop.lhs); type_t *rhs_t = get_type(env, binop.rhs); + if (can_promote(rhs_t, lhs_t) || can_promote(lhs_t, rhs_t)) - return Type(BoolType); + return ast->tag == Compare ? Type(IntType, .bits=TYPE_IBITS32) : Type(BoolType); code_err(ast, "I don't know how to compare ", type_to_str(lhs_t), " and ", type_to_str(rhs_t)); }