Skip to content

Commit

Permalink
Fix comparing two unsigned types (#488)
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli authored Dec 29, 2023
1 parent ac67ef9 commit 78e6756
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 4 deletions.
2 changes: 1 addition & 1 deletion self_hosted/create_llvm_ir.jou
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ class AstToIR:
assert False

if lhs_type->is_integer_type() and rhs_type->is_integer_type():
is_signed = lhs_type->kind == TypeKind::SignedInteger and rhs_type->kind == TypeKind::SignedInteger
is_signed = lhs_type->kind == TypeKind::SignedInteger or rhs_type->kind == TypeKind::SignedInteger
if op == AstExpressionKind::Add:
return LLVMBuildAdd(self->builder, lhs, rhs, "add")
if op == AstExpressionKind::Subtract:
Expand Down
6 changes: 3 additions & 3 deletions src/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,11 +392,11 @@ static void codegen_instruction(const struct State *st, const CfInstruction *ins
setdest(LLVMBuildFCmp(st->builder, LLVMRealOEQ, getop(0), getop(1), "num_eq"));
break;
case CF_NUM_LT:
if (is_integer_type(ins->operands[0]->type))
// TODO: unsigned less than
if (ins->operands[0]->type->kind == TYPE_UNSIGNED_INTEGER && ins->operands[1]->type->kind == TYPE_UNSIGNED_INTEGER)
setdest(LLVMBuildICmp(st->builder, LLVMIntULT, getop(0), getop(1), "num_lt"));
else if (is_integer_type(ins->operands[0]->type) && is_integer_type(ins->operands[1]->type))
setdest(LLVMBuildICmp(st->builder, LLVMIntSLT, getop(0), getop(1), "num_lt"));
else
// TODO: signed less than
setdest(LLVMBuildFCmp(st->builder, LLVMRealOLT, getop(0), getop(1), "num_lt"));
break;
}
Expand Down
20 changes: 20 additions & 0 deletions tests/should_succeed/compare_bytes.jou
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import "stdlib/io.jou"


# TODO: It's not possible to test things like "signed < unsigned" yet with types of the same size.
# For 8-bit there's only unsigned (byte), for 16-bit only signed (short), 32-bit only signed (int), 64-bit only signed (long).
def main() -> int:
a = 0 as byte
b = 100 as byte
c = 200 as byte

printf("%d %d %d\n", a < b, b < b, c < b) # Output: 1 0 0
printf("%d %d %d\n", a > b, b > b, c > b) # Output: 0 0 1

printf("%d %d %d\n", a <= b, b <= b, c <= b) # Output: 1 1 0
printf("%d %d %d\n", a >= b, b >= b, c >= b) # Output: 0 1 1

printf("%d %d %d\n", a == b, b == b, c == b) # Output: 0 1 0
printf("%d %d %d\n", a != b, b != b, c != b) # Output: 1 0 1

return 0

0 comments on commit 78e6756

Please sign in to comment.