Friendlier int parsing and promotion.

This commit is contained in:
Christoffer Lerno
2022-12-28 00:37:52 +01:00
parent f622b3bd4c
commit f6e798c283
4 changed files with 27 additions and 12 deletions

View File

@@ -5,7 +5,7 @@ struct SimpleRandom
long seed;
}
private const long SIMPLE_RANDOM_MULTIPLIER = 0x5DEECE66Di64;
private const long SIMPLE_RANDOM_MULTIPLIER = 0x5DEECE66D;
private const long SIMPLE_RANDOM_ADDEND = 0xB;
private const long SIMPLE_RANDOM_MASK = (1i64 << 48) - 1;

View File

@@ -1198,7 +1198,7 @@ Expr *parse_integer(ParseContext *c, Expr *left)
}
expr_int->const_expr.const_kind = CONST_INTEGER;
expr_int->const_expr.is_hex = hex_characters > 0;
Type *type = is_unsigned ? type_cuint : type_cint;
Type *type_base = NULL;
expr_int->const_expr.narrowable = !type_bits;
if (type_bits)
{
@@ -1241,16 +1241,31 @@ Expr *parse_integer(ParseContext *c, Expr *left)
if (type_bits && !is_power_of_two((uint64_t)type_bits)) type_bits = (int)next_highest_power_of_2((uint32_t)type_bits);
}
if (type_bits) expr_int->const_expr.is_hex = false;
if (!type_bits)
{
type_bits = (int)type_size(type) * 8;
}
if (type_bits)
{
type = is_unsigned ? type_int_unsigned_by_bitsize((unsigned)type_bits) : type_int_signed_by_bitsize((unsigned)type_bits);
type_base = is_unsigned ? type_int_unsigned_by_bitsize((unsigned)type_bits)
: type_int_signed_by_bitsize((unsigned)type_bits);
}
expr_int->const_expr.ixx = (Int) { i, type->type_kind };
if (!int_fits(expr_int->const_expr.ixx, type->type_kind))
else
{
int min_bits = type_size(type_cint) * 8;
Int test = { .i = i };
for (int type_kind = 0; type_kind < 5; type_kind++)
{
TypeKind kind = (is_unsigned ? TYPE_U8 : TYPE_I8) + type_kind;
int bitsize = type_kind_bitsize(kind);
if (bitsize < min_bits) continue;
test.type = kind;
if (int_fits(test, kind))
{
type_base = is_unsigned ? type_int_unsigned_by_bitsize(bitsize) : type_int_signed_by_bitsize(bitsize);
break;
}
}
if (!type_base) type_base = is_unsigned ? type_cuint : type_cint;
}
expr_int->const_expr.ixx = (Int) { i, type_base->type_kind };
if (!int_fits(expr_int->const_expr.ixx, type_base->type_kind))
{
unsigned radix = 10;
if (hex_characters) radix = 16;
@@ -1268,7 +1283,7 @@ Expr *parse_integer(ParseContext *c, Expr *left)
}
return poisoned_expr;
}
expr_int->type = type;
expr_int->type = type_base;
advance(c);
return expr_int;
}

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.3.125"
#define COMPILER_VERSION "0.3.126"

View File

@@ -5,7 +5,7 @@ fn void syntaxErrors()
if (i + 1) {} // #error: optional, but was 'int!'
for (int x = i;;) {} // #error: 'int!' to 'int'
for (int x = 0; x < i + 1;) {} // #error: optional, but was 'bool!'.
for (int x = 0; x < 10; x += i + 1) {} // #error: Cannot assign an optional value to a non-optional
for (int x = 0; x < 10; x += i + 1) {} // #error: Cannot assign an an optional value to a non-optional
switch (i + 1) // #error: optional, but was 'int!'
{
default: