commit 12a3b6704d10e535f777aee06643affc60a1f006
parent b278149b0a839bce086321d7880c175d1d5db9e1
Author: Eyal Sawady <ecs@d2evs.net>
Date: Wed, 10 Feb 2021 12:44:19 -0500
Implement flexible constants
Diffstat:
14 files changed, 223 insertions(+), 25 deletions(-)
diff --git a/include/types.h b/include/types.h
@@ -11,10 +11,12 @@ enum type_storage {
TYPE_STORAGE_ENUM,
TYPE_STORAGE_F32,
TYPE_STORAGE_F64,
+ TYPE_STORAGE_FCONST,
TYPE_STORAGE_I16,
TYPE_STORAGE_I32,
TYPE_STORAGE_I64,
TYPE_STORAGE_I8,
+ TYPE_STORAGE_ICONST,
TYPE_STORAGE_INT,
TYPE_STORAGE_NULL,
TYPE_STORAGE_RUNE,
@@ -179,10 +181,12 @@ extern struct type
builtin_type_char,
builtin_type_f32,
builtin_type_f64,
+ builtin_type_fconst,
builtin_type_i8,
builtin_type_i16,
builtin_type_i32,
builtin_type_i64,
+ builtin_type_iconst,
builtin_type_int,
builtin_type_u8,
builtin_type_u16,
@@ -199,10 +203,12 @@ extern struct type
builtin_type_const_char,
builtin_type_const_f32,
builtin_type_const_f64,
+ builtin_type_const_fconst,
builtin_type_const_i8,
builtin_type_const_i16,
builtin_type_const_i32,
builtin_type_const_i64,
+ builtin_type_const_iconst,
builtin_type_const_int,
builtin_type_const_u8,
builtin_type_const_u16,
diff --git a/src/check.c b/src/check.c
@@ -790,6 +790,81 @@ check_expr_array(struct context *ctx,
}
}
+static const struct type *
+lower_constant(const struct type *type, struct expression *expr)
+{
+ assert(expr->type == EXPR_CONSTANT);
+ type = type_dealias(type);
+ if (type_is_float(type)) {
+ assert(0); // TODO
+ }
+ if (type->storage == TYPE_STORAGE_TAGGED) {
+ const struct type *tag = NULL;
+ for (const struct type_tagged_union *tu = &type->tagged; tu;
+ tu = tu->next) {
+ if (lower_constant(tu->type, expr)) {
+ if (tag != NULL) {
+ // Ambiguous
+ return NULL;
+ }
+ tag = tu->type;
+ }
+ }
+ return tag;
+ }
+ if (!type_is_integer(type)) {
+ return NULL;
+ }
+ if (type_is_signed(type)) {
+ intmax_t max, min;
+ switch (type->size) {
+ case 1:
+ max = INT8_MAX;
+ min = INT8_MIN;
+ break;
+ case 2:
+ max = INT16_MAX;
+ min = INT16_MIN;
+ break;
+ case 4:
+ max = INT32_MAX;
+ min = INT32_MIN;
+ break;
+ case 8:
+ max = INT64_MAX;
+ min = INT64_MIN;
+ break;
+ default:
+ assert(0);
+ }
+ if (expr->constant.ival <= max && expr->constant.ival >= min) {
+ return type;
+ }
+ return NULL;
+ }
+ uintmax_t max;
+ switch (type->size) {
+ case 1:
+ max = UINT8_MAX;
+ break;
+ case 2:
+ max = UINT16_MAX;
+ break;
+ case 4:
+ max = UINT32_MAX;
+ break;
+ case 8:
+ max = UINT64_MAX;
+ break;
+ default:
+ assert(0);
+ }
+ if (expr->constant.uval <= max) {
+ return type;
+ }
+ return NULL;
+}
+
static void
check_expr_constant(struct context *ctx,
const struct ast_expression *aexpr,
@@ -800,11 +875,23 @@ check_expr_constant(struct context *ctx,
expr->type = EXPR_CONSTANT;
expr->result = builtin_type_for_storage(aexpr->constant.storage, false);
+ if (expr->result && expr->result->storage == TYPE_STORAGE_ICONST) {
+ if (hint == NULL) {
+ hint = builtin_type_for_storage(TYPE_STORAGE_INT, false);
+ }
+ expr->constant.ival = aexpr->constant.ival;
+ const struct type *type = lower_constant(hint, expr);
+ // TODO: This error message is awful
+ expect(&aexpr->loc, type, "Integer constant out of range");
+ expr->result = type;
+ }
+
switch (aexpr->constant.storage) {
case TYPE_STORAGE_I8:
case TYPE_STORAGE_I16:
case TYPE_STORAGE_I32:
case TYPE_STORAGE_I64:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_INT:
expr->constant.ival = aexpr->constant.ival;
break;
@@ -837,7 +924,7 @@ check_expr_constant(struct context *ctx,
break;
case TYPE_STORAGE_F32:
case TYPE_STORAGE_F64:
- case TYPE_STORAGE_STRUCT:
+ case TYPE_STORAGE_FCONST:
assert(0); // TODO
case TYPE_STORAGE_CHAR:
case TYPE_STORAGE_ENUM:
@@ -848,6 +935,7 @@ check_expr_constant(struct context *ctx,
case TYPE_STORAGE_SLICE:
case TYPE_STORAGE_TAGGED:
case TYPE_STORAGE_TUPLE:
+ case TYPE_STORAGE_STRUCT:
case TYPE_STORAGE_UNION:
assert(0); // Invariant
}
diff --git a/src/dump.c b/src/dump.c
@@ -65,6 +65,7 @@ dump_const(const struct expression *expr)
break;
case TYPE_STORAGE_F32:
case TYPE_STORAGE_F64:
+ case TYPE_STORAGE_FCONST:
fprintf(stderr, "%lf%s", val->fval,
storage_to_suffix(expr->result->storage));
break;
@@ -72,6 +73,7 @@ dump_const(const struct expression *expr)
case TYPE_STORAGE_I32:
case TYPE_STORAGE_I64:
case TYPE_STORAGE_I8:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_INT:
fprintf(stderr, "%ld%s", val->ival,
storage_to_suffix(expr->result->storage));
@@ -128,10 +130,12 @@ dump_type(const struct type *type)
case TYPE_STORAGE_ENUM:
case TYPE_STORAGE_F32:
case TYPE_STORAGE_F64:
+ case TYPE_STORAGE_FCONST:
case TYPE_STORAGE_I16:
case TYPE_STORAGE_I32:
case TYPE_STORAGE_I64:
case TYPE_STORAGE_I8:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_INT:
case TYPE_STORAGE_NULL:
case TYPE_STORAGE_RUNE:
diff --git a/src/eval.c b/src/eval.c
@@ -34,6 +34,7 @@ itrunc(const struct type *type, uintmax_t val)
case TYPE_STORAGE_UINT:
return (unsigned int)val;
case TYPE_STORAGE_ARRAY:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_POINTER:
case TYPE_STORAGE_SIZE:
case TYPE_STORAGE_UINTPTR:
@@ -49,6 +50,7 @@ itrunc(const struct type *type, uintmax_t val)
case TYPE_STORAGE_CHAR:
case TYPE_STORAGE_F32:
case TYPE_STORAGE_F64:
+ case TYPE_STORAGE_FCONST:
case TYPE_STORAGE_FUNCTION:
case TYPE_STORAGE_RUNE:
case TYPE_STORAGE_SLICE:
@@ -265,10 +267,12 @@ eval_const(struct context *ctx, struct expression *in, struct expression *out)
case TYPE_STORAGE_CHAR:
case TYPE_STORAGE_F32:
case TYPE_STORAGE_F64:
+ case TYPE_STORAGE_FCONST:
case TYPE_STORAGE_I16:
case TYPE_STORAGE_I32:
case TYPE_STORAGE_I64:
case TYPE_STORAGE_I8:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_INT:
case TYPE_STORAGE_NULL:
case TYPE_STORAGE_POINTER:
@@ -319,6 +323,7 @@ eval_cast(struct context *ctx, struct expression *in, struct expression *out)
case TYPE_STORAGE_I32:
case TYPE_STORAGE_I64:
case TYPE_STORAGE_I8:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_INT:
case TYPE_STORAGE_U16:
case TYPE_STORAGE_U32:
@@ -336,6 +341,7 @@ eval_cast(struct context *ctx, struct expression *in, struct expression *out)
return EVAL_OK;
case TYPE_STORAGE_F32:
case TYPE_STORAGE_F64:
+ case TYPE_STORAGE_FCONST:
case TYPE_STORAGE_CHAR:
case TYPE_STORAGE_ENUM:
case TYPE_STORAGE_NULL:
@@ -386,6 +392,7 @@ constant_default(struct context *ctx, struct expression *v)
case TYPE_STORAGE_I32:
case TYPE_STORAGE_I64:
case TYPE_STORAGE_I8:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_INT:
case TYPE_STORAGE_U16:
case TYPE_STORAGE_U32:
@@ -396,6 +403,7 @@ constant_default(struct context *ctx, struct expression *v)
case TYPE_STORAGE_SIZE:
case TYPE_STORAGE_F32:
case TYPE_STORAGE_F64:
+ case TYPE_STORAGE_FCONST:
case TYPE_STORAGE_CHAR:
case TYPE_STORAGE_ENUM:
case TYPE_STORAGE_NULL:
diff --git a/src/gen.c b/src/gen.c
@@ -1307,7 +1307,9 @@ gen_expr_cast(struct gen_context *ctx,
case TYPE_STORAGE_TAGGED:
assert(0); // Handled above
case TYPE_STORAGE_BOOL:
+ case TYPE_STORAGE_FCONST:
case TYPE_STORAGE_FUNCTION:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_STRING:
case TYPE_STORAGE_STRUCT:
case TYPE_STORAGE_TUPLE:
@@ -2501,7 +2503,9 @@ gen_data_item(struct gen_context *ctx, struct expression *expr,
assert(0); // TODO
case TYPE_STORAGE_ALIAS:
case TYPE_STORAGE_CHAR:
+ case TYPE_STORAGE_FCONST:
case TYPE_STORAGE_FUNCTION:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_NULL:
case TYPE_STORAGE_VOID:
assert(0); // Invariant
diff --git a/src/lex.c b/src/lex.c
@@ -343,9 +343,9 @@ lex_literal(struct lexer *lexer, struct token *out)
finalize:
out->token = T_LITERAL;
if (isfloat) {
- out->storage = TYPE_STORAGE_F64;
+ out->storage = TYPE_STORAGE_FCONST;
} else {
- out->storage = TYPE_STORAGE_INT;
+ out->storage = TYPE_STORAGE_ICONST;
}
if (suff) {
const char *suffs[] = {
@@ -404,6 +404,19 @@ finalize:
out->uval *= 10;
}
break;
+ case TYPE_STORAGE_ICONST:
+ if (lexer->buf[0] != '-') {
+ uintmax_t uval = strtoumax(lexer->buf, NULL, base);
+ for (uintmax_t i = 0; i < exponent; i++) {
+ uval *= 10;
+ }
+ if (uval > (uintmax_t)INT64_MAX) {
+ out->storage = TYPE_STORAGE_U64;
+ out->uval = uval;
+ break;
+ }
+ }
+ // Fallthrough
case TYPE_STORAGE_I8:
case TYPE_STORAGE_I16:
case TYPE_STORAGE_I32:
@@ -416,6 +429,7 @@ finalize:
break;
case TYPE_STORAGE_F32:
case TYPE_STORAGE_F64:
+ case TYPE_STORAGE_FCONST:
out->fval = strtod(lexer->buf, NULL);
break;
default:
@@ -1030,11 +1044,13 @@ token_str(const struct token *tok)
case TYPE_STORAGE_I16:
case TYPE_STORAGE_I32:
case TYPE_STORAGE_I64:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_INT:
snprintf(buf, sizeof(buf), "%jd", tok->ival);
break;
case TYPE_STORAGE_F32:
case TYPE_STORAGE_F64:
+ case TYPE_STORAGE_FCONST:
snprintf(buf, sizeof(buf), "%lf", tok->fval);
break;
case TYPE_STORAGE_RUNE:
diff --git a/src/parse.c b/src/parse.c
@@ -783,6 +783,7 @@ parse_constant(struct lexer *lexer)
case TYPE_STORAGE_I16:
case TYPE_STORAGE_I32:
case TYPE_STORAGE_I64:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_INT:
exp->constant.ival = (intmax_t)tok.ival;
break;
diff --git a/src/qtype.c b/src/qtype.c
@@ -42,6 +42,8 @@ qstype_for_type(const struct type *type)
case TYPE_STORAGE_ENUM:
return qstype_for_type(builtin_type_for_storage(type->_enum.storage, true));
case TYPE_STORAGE_ARRAY:
+ case TYPE_STORAGE_FCONST:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_SLICE:
case TYPE_STORAGE_STRING:
case TYPE_STORAGE_STRUCT:
@@ -92,6 +94,9 @@ qxtype_for_type(const struct type *type)
return qstype_for_type(type);
case TYPE_STORAGE_ENUM:
return qxtype_for_type(builtin_type_for_storage(type->_enum.storage, true));
+ case TYPE_STORAGE_FCONST:
+ case TYPE_STORAGE_ICONST:
+ assert(0); // Lowered in check
}
assert(0);
}
@@ -228,12 +233,14 @@ lookup_aggregate(struct gen_context *ctx, const struct type *type)
case TYPE_STORAGE_UINT:
case TYPE_STORAGE_I64:
case TYPE_STORAGE_U64:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_SIZE:
case TYPE_STORAGE_UINTPTR:
case TYPE_STORAGE_POINTER:
case TYPE_STORAGE_NULL:
case TYPE_STORAGE_F32:
case TYPE_STORAGE_F64:
+ case TYPE_STORAGE_FCONST:
case TYPE_STORAGE_VOID:
case TYPE_STORAGE_FUNCTION:
assert(0); // Invariant
@@ -287,6 +294,9 @@ qtype_for_type(struct gen_context *ctx, const struct type *type, bool extended)
return qtype_for_xtype(Q__AGGREGATE, false);
case TYPE_STORAGE_ALIAS:
return qtype_for_type(ctx, type->alias.type, extended);
+ case TYPE_STORAGE_FCONST:
+ case TYPE_STORAGE_ICONST:
+ assert(0); // Lowered in check
}
assert(0); // Unreachable
}
@@ -328,6 +338,9 @@ type_is_aggregate(const struct type *type)
case TYPE_STORAGE_UNION:
case TYPE_STORAGE_FUNCTION:
return true;
+ case TYPE_STORAGE_FCONST:
+ case TYPE_STORAGE_ICONST:
+ assert(0); // Lowered in check
}
assert(0); // Unreachable
}
diff --git a/src/type_store.c b/src/type_store.c
@@ -38,6 +38,8 @@ builtin_type_for_storage(enum type_storage storage, bool is_const)
return is_const ? &builtin_type_const_f32 : &builtin_type_f32;
case TYPE_STORAGE_F64:
return is_const ? &builtin_type_const_f64 : &builtin_type_f64;
+ case TYPE_STORAGE_FCONST:
+ return is_const ? &builtin_type_const_fconst : &builtin_type_fconst;
case TYPE_STORAGE_I8:
return is_const ? &builtin_type_const_i8 : &builtin_type_i8;
case TYPE_STORAGE_I16:
@@ -46,6 +48,8 @@ builtin_type_for_storage(enum type_storage storage, bool is_const)
return is_const ? &builtin_type_const_i32 : &builtin_type_i32;
case TYPE_STORAGE_I64:
return is_const ? &builtin_type_const_i64 : &builtin_type_i64;
+ case TYPE_STORAGE_ICONST:
+ return is_const ? &builtin_type_const_iconst : &builtin_type_iconst;
case TYPE_STORAGE_INT:
return is_const ? &builtin_type_const_int : &builtin_type_int;
case TYPE_STORAGE_RUNE:
@@ -370,10 +374,12 @@ type_init_from_atype(struct type_store *store,
case TYPE_STORAGE_CHAR:
case TYPE_STORAGE_F32:
case TYPE_STORAGE_F64:
+ case TYPE_STORAGE_FCONST:
case TYPE_STORAGE_I8:
case TYPE_STORAGE_I16:
case TYPE_STORAGE_I32:
case TYPE_STORAGE_I64:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_INT:
case TYPE_STORAGE_NULL:
case TYPE_STORAGE_RUNE:
diff --git a/src/typedef.c b/src/typedef.c
@@ -15,6 +15,8 @@ storage_to_suffix(enum type_storage storage)
return "f32";
case TYPE_STORAGE_F64:
return "f64";
+ case TYPE_STORAGE_FCONST:
+ return "";
case TYPE_STORAGE_I16:
return "i16";
case TYPE_STORAGE_I32:
@@ -23,6 +25,8 @@ storage_to_suffix(enum type_storage storage)
return "i64";
case TYPE_STORAGE_I8:
return "i8";
+ case TYPE_STORAGE_ICONST:
+ return "";
case TYPE_STORAGE_INT:
return "i";
case TYPE_STORAGE_SIZE:
@@ -55,6 +59,7 @@ emit_const(const struct expression *expr, FILE *out)
break;
case TYPE_STORAGE_F32:
case TYPE_STORAGE_F64:
+ case TYPE_STORAGE_FCONST:
fprintf(out, "%lf%s", val->fval,
storage_to_suffix(expr->result->storage));
break;
@@ -62,6 +67,7 @@ emit_const(const struct expression *expr, FILE *out)
case TYPE_STORAGE_I32:
case TYPE_STORAGE_I64:
case TYPE_STORAGE_I8:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_INT:
fprintf(out, "%ld%s", val->ival,
storage_to_suffix(expr->result->storage));
@@ -261,6 +267,9 @@ emit_type(const struct type *type, FILE *out)
}
fprintf(out, ")");
break;
+ case TYPE_STORAGE_FCONST:
+ case TYPE_STORAGE_ICONST:
+ assert(0); // Invariant
}
}
diff --git a/src/types.c b/src/types.c
@@ -80,6 +80,8 @@ type_storage_unparse(enum type_storage storage)
return "f32";
case TYPE_STORAGE_F64:
return "f64";
+ case TYPE_STORAGE_FCONST:
+ return "fconst";
case TYPE_STORAGE_FUNCTION:
return "function";
case TYPE_STORAGE_I16:
@@ -90,6 +92,8 @@ type_storage_unparse(enum type_storage storage)
return "i64";
case TYPE_STORAGE_I8:
return "i8";
+ case TYPE_STORAGE_ICONST:
+ return "iconst";
case TYPE_STORAGE_INT:
return "int";
case TYPE_STORAGE_POINTER:
@@ -149,6 +153,7 @@ type_is_integer(const struct type *type)
case TYPE_STORAGE_RUNE:
case TYPE_STORAGE_F32:
case TYPE_STORAGE_F64:
+ case TYPE_STORAGE_FCONST:
return false;
case TYPE_STORAGE_CHAR:
case TYPE_STORAGE_ENUM:
@@ -156,6 +161,7 @@ type_is_integer(const struct type *type)
case TYPE_STORAGE_I16:
case TYPE_STORAGE_I32:
case TYPE_STORAGE_I64:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_INT:
case TYPE_STORAGE_SIZE:
case TYPE_STORAGE_U8:
@@ -195,9 +201,11 @@ type_is_numeric(const struct type *type)
case TYPE_STORAGE_I16:
case TYPE_STORAGE_I32:
case TYPE_STORAGE_I64:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_INT:
case TYPE_STORAGE_F32:
case TYPE_STORAGE_F64:
+ case TYPE_STORAGE_FCONST:
case TYPE_STORAGE_SIZE:
case TYPE_STORAGE_U8:
case TYPE_STORAGE_U16:
@@ -253,7 +261,10 @@ type_storage_is_signed(enum type_storage storage)
case TYPE_STORAGE_INT:
case TYPE_STORAGE_F32:
case TYPE_STORAGE_F64:
+ case TYPE_STORAGE_FCONST:
return true;
+ case TYPE_STORAGE_ICONST:
+ assert(0); // XXX
}
assert(0); // Unreachable
}
@@ -279,10 +290,12 @@ type_hash(const struct type *type)
case TYPE_STORAGE_CHAR:
case TYPE_STORAGE_F32:
case TYPE_STORAGE_F64:
+ case TYPE_STORAGE_FCONST:
case TYPE_STORAGE_I8:
case TYPE_STORAGE_I16:
case TYPE_STORAGE_I32:
case TYPE_STORAGE_I64:
+ case TYPE_STORAGE_ICONST:
case TYPE_STORAGE_INT:
case TYPE_STORAGE_NULL:
case TYPE_STORAGE_RUNE:
@@ -438,6 +451,9 @@ type_is_assignable(const struct type *to, const struct type *from)
struct type _to_secondary, _from_secondary;
const struct type *to_secondary, *from_secondary;
switch (to->storage) {
+ case TYPE_STORAGE_ICONST:
+ case TYPE_STORAGE_FCONST:
+ assert(0); // Invariant
case TYPE_STORAGE_I8:
case TYPE_STORAGE_I16:
case TYPE_STORAGE_I32:
@@ -569,6 +585,9 @@ type_is_castable(const struct type *to, const struct type *from)
}
switch (to->storage) {
+ case TYPE_STORAGE_FCONST:
+ case TYPE_STORAGE_ICONST:
+ assert(0); // TODO
case TYPE_STORAGE_I8:
case TYPE_STORAGE_I16:
case TYPE_STORAGE_I32:
@@ -638,22 +657,24 @@ builtin_types_init()
{
struct type *builtins[] = {
&builtin_type_bool, &builtin_type_char, &builtin_type_f32,
- &builtin_type_f64, &builtin_type_i8, &builtin_type_i16,
- &builtin_type_i32, &builtin_type_i64, &builtin_type_int,
- &builtin_type_u8, &builtin_type_u16, &builtin_type_u32,
- &builtin_type_u64, &builtin_type_uint, &builtin_type_uintptr,
- &builtin_type_null, &builtin_type_rune, &builtin_type_size,
- &builtin_type_void, &builtin_type_const_bool,
- &builtin_type_const_char, &builtin_type_const_f32,
- &builtin_type_const_f64, &builtin_type_const_i8,
+ &builtin_type_f64, &builtin_type_fconst, &builtin_type_i8,
+ &builtin_type_i16, &builtin_type_i32, &builtin_type_i64,
+ &builtin_type_iconst, &builtin_type_int, &builtin_type_u8,
+ &builtin_type_u16, &builtin_type_u32, &builtin_type_u64,
+ &builtin_type_uint, &builtin_type_uintptr, &builtin_type_null,
+ &builtin_type_rune, &builtin_type_size, &builtin_type_void,
+ &builtin_type_const_bool, &builtin_type_const_char,
+ &builtin_type_const_f32, &builtin_type_const_f64,
+ &builtin_type_const_fconst, &builtin_type_const_i8,
&builtin_type_const_i16, &builtin_type_const_i32,
- &builtin_type_const_i64, &builtin_type_const_int,
- &builtin_type_const_u8, &builtin_type_const_u16,
- &builtin_type_const_u32, &builtin_type_const_u64,
- &builtin_type_const_uint, &builtin_type_const_uintptr,
- &builtin_type_const_rune, &builtin_type_const_size,
- &builtin_type_const_void, &builtin_type_const_ptr_char,
- &builtin_type_str, &builtin_type_const_str,
+ &builtin_type_const_i64, &builtin_type_const_iconst,
+ &builtin_type_const_int, &builtin_type_const_u8,
+ &builtin_type_const_u16, &builtin_type_const_u32,
+ &builtin_type_const_u64, &builtin_type_const_uint,
+ &builtin_type_const_uintptr, &builtin_type_const_rune,
+ &builtin_type_const_size, &builtin_type_const_void,
+ &builtin_type_const_ptr_char, &builtin_type_str,
+ &builtin_type_const_str,
};
for (size_t i = 0; i < sizeof(builtins) / sizeof(builtins[0]); ++i) {
builtins[i]->id = type_hash(builtins[i]);
@@ -681,6 +702,11 @@ builtin_type_f64 = {
.size = 8,
.align = 8,
},
+builtin_type_fconst = {
+ .storage = TYPE_STORAGE_FCONST,
+ .size = SIZE_UNDEFINED,
+ .align = ALIGN_UNDEFINED,
+},
builtin_type_i8 = {
.storage = TYPE_STORAGE_I8,
.size = 1,
@@ -701,6 +727,11 @@ builtin_type_i64 = {
.size = 8,
.align = 8,
},
+builtin_type_iconst = {
+ .storage = TYPE_STORAGE_ICONST,
+ .size = SIZE_UNDEFINED,
+ .align = ALIGN_UNDEFINED,
+},
builtin_type_int = {
.storage = TYPE_STORAGE_INT,
.size = 4, // XXX: ARCH
@@ -780,6 +811,12 @@ builtin_type_const_f64 = {
.size = 8,
.align = 8,
},
+builtin_type_const_fconst = {
+ .storage = TYPE_STORAGE_FCONST,
+ .flags = TYPE_CONST,
+ .size = SIZE_UNDEFINED,
+ .align = ALIGN_UNDEFINED,
+},
builtin_type_const_i8 = {
.storage = TYPE_STORAGE_I8,
.flags = TYPE_CONST,
@@ -804,6 +841,12 @@ builtin_type_const_i64 = {
.size = 8,
.align = 8,
},
+builtin_type_const_iconst = {
+ .storage = TYPE_STORAGE_ICONST,
+ .flags = TYPE_CONST,
+ .size = SIZE_UNDEFINED,
+ .align = ALIGN_UNDEFINED,
+},
builtin_type_const_int = {
.storage = TYPE_STORAGE_INT,
.flags = TYPE_CONST,
diff --git a/tests/13-tagged.ha b/tests/13-tagged.ha
@@ -67,7 +67,7 @@ fn reduction() void = {
assert(size((i8 | i16 | i32)) == size((i8 | (i16 | i32))));
assert(size(integer) == size(signed));
assert(size(integer) != size((signed | unsigned)));
- const i: integer = 10;
+ const i: integer = 10i;
assert(i is int);
};
diff --git a/tests/14-switch.ha b/tests/14-switch.ha
@@ -27,14 +27,14 @@ fn termination() void = {
fn tagged_result() void = {
let x = 42;
let y: (int | uint) = switch (x) {
- 42 => 1337,
+ 42 => 1337i,
* => 1337u,
};
assert(y is int);
x = 24;
y = switch (x) {
- 42 => 1337,
+ 42 => 1337i,
* => 1337u,
};
assert(y is uint);
diff --git a/tests/18-match.ha b/tests/18-match.ha
@@ -1,5 +1,5 @@
fn tagged() void = {
- let cases: [3](int | uint | str) = [10, 10u, "hello"];
+ let cases: [3](int | uint | str) = [10i, 10u, "hello"];
let expected = [1z, 2z, 5z];
for (let i = 0z; i < len(cases); i += 1z) {
let y: size = match (cases[i]) {
@@ -12,7 +12,7 @@ fn tagged() void = {
};
fn termination() void = {
- let x: (int | uint | str) = 1337;
+ let x: (int | uint | str) = 1337i;
for (true) {
let y: int = match (x) {
int => 42,
@@ -67,7 +67,7 @@ fn alias() void = {
};
fn tagged_result() void = {
- let x: (int | uint) = 42;
+ let x: (int | uint) = 42i;
let y: (int | uint) = match (x) {
x: int => x,
x: uint => x,
@@ -167,7 +167,7 @@ type integer = (...signed | ...unsigned);
export fn numeric() void = {
// Real-world test
let visit = true;
- let x: integer = 1337;
+ let x: integer = 1337i;
match (x) {
s: signed => match (s) {
i: int => {