aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-04-05 02:03:08 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-04-05 02:03:08 -0400
commit81316e0d9704834a0a648cf84401b968933b7581 (patch)
treed6c23c32a896abd93826f357c318631156df526e
parente2ddd23b55bd51bd382ebc9b8d3094632472bf67 (diff)
Fix comparison with integer literals
-rw-r--r--src/compile.c14
-rw-r--r--src/typecheck.c14
2 files changed, 11 insertions, 17 deletions
diff --git a/src/compile.c b/src/compile.c
index 05cc7bcd..21091489 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 85f159c9..1bef98c8 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));
}