commit c0625069db5e482cea9f83f94cde1010c6feb0b6
parent 626125cf49771d4a54783df8edbab7214e3e53f6
Author: Sebastian <sebastian@sebsite.pw>
Date: Mon, 28 Mar 2022 17:37:15 -0400
Allow enums with rune storage
Implements: https://todo.sr.ht/~sircmpwn/hare/368
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
3 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/parse.c b/src/parse.c
@@ -437,8 +437,11 @@ parse_enum_type(struct lexer *lexer)
unlex(lexer, &tok);
type->_enum.storage = parse_integer_type(lexer);
break;
+ case T_RUNE:
+ type->_enum.storage = STORAGE_RUNE;
+ break;
default:
- synassert_msg(false, "Enum storage must be an integer", &tok);
+ synassert_msg(false, "Enum storage must be an integer or rune", &tok);
}
want(lexer, T_LBRACE, NULL);
while (tok.token != T_RBRACE) {
diff --git a/src/type_store.c b/src/type_store.c
@@ -703,9 +703,10 @@ type_init_from_atype(struct type_store *store,
type->_enum.storage = atype->_enum.storage;
const struct type *storage =
builtin_type_for_storage(type->_enum.storage, true);
- if (!type_is_integer(storage)) {
+ if (!type_is_integer(storage)
+ && type->_enum.storage != STORAGE_RUNE) {
error(store->check_context, atype->loc,
- "Enum storage must be an integer");
+ "Enum storage must be an integer or rune");
*type = builtin_type_void;
return (struct dimensions){0};
}
diff --git a/tests/15-enums.ha b/tests/15-enums.ha
@@ -38,6 +38,11 @@ type char_storage = enum char {
BAR = 1,
};
+type rune_storage = enum rune {
+ FOO = '0',
+ BAR = '1',
+};
+
fn storage() void = {
assert(size(explicit_values) == size(int));
assert(size(with_storage) == 2);
@@ -48,6 +53,7 @@ fn storage() void = {
assert(with_storage::DEAD: u8 == (if (is_little) 0xADu8 else 0xDEu8));
assert(with_storage::BEEF: u8 == (if (is_little) 0xEFu8 else 0xBEu8));
assert(char_storage::FOO == 0 && char_storage::BAR == 1);
+ assert(rune_storage::FOO == '0' && rune_storage::BAR == '1');
};
export fn main() void = {