harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 12a3b6704d10e535f777aee06643affc60a1f006
parent b278149b0a839bce086321d7880c175d1d5db9e1
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Wed, 10 Feb 2021 12:44:19 -0500

Implement flexible constants

Diffstat:
Minclude/types.h | 6++++++
Msrc/check.c | 90++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/dump.c | 4++++
Msrc/eval.c | 8++++++++
Msrc/gen.c | 4++++
Msrc/lex.c | 20++++++++++++++++++--
Msrc/parse.c | 1+
Msrc/qtype.c | 13+++++++++++++
Msrc/type_store.c | 6++++++
Msrc/typedef.c | 9+++++++++
Msrc/types.c | 73++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Mtests/13-tagged.ha | 2+-
Mtests/14-switch.ha | 4++--
Mtests/18-match.ha | 8++++----
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 => {