From f1e1814ff91ab0753891536442797ff8544e6b6c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 11 Sep 2018 12:10:32 +0100 Subject: [PATCH] Syntactic sugar for anonymous enum within a bit set --- src/check_decl.cpp | 1 - src/check_type.cpp | 22 ++++++++++++++++++++-- src/parser.cpp | 36 +++++++++++++++++++++++------------- src/types.cpp | 4 ++++ 4 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 9b571867f..a874ce021 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -242,7 +242,6 @@ void check_type_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Type *def) e->type = t_invalid; String name = e->token.string; Type *named = alloc_type_named(name, nullptr, e); - named->Named.type_name = e; if (def != nullptr && def->kind == Type_Named) { def->Named.base = named; } diff --git a/src/check_type.cpp b/src/check_type.cpp index 33b90288f..993db6ff1 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -931,7 +931,7 @@ bool is_type_valid_bit_set_range(Type *t) { return false; } -void check_bit_set_type(CheckerContext *c, Type *type, Ast *node) { +void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *node) { ast_node(bs, BitSetType, node); GB_ASSERT(type->kind == Type_BitSet); @@ -1045,6 +1045,24 @@ void check_bit_set_type(CheckerContext *c, Type *type, Ast *node) { } else { Type *elem = check_type_expr(c, bs->elem, nullptr); + #if 1 + if (named_type != nullptr && named_type->kind == Type_Named && + elem->kind == Type_Enum) { + // NOTE(bill): Anonymous enumeration + + String prefix = named_type->Named.name; + String enum_name = concatenate_strings(heap_allocator(), prefix, str_lit(".enum")); + + Token token = make_token_ident(enum_name); + + Entity *e = alloc_entity_type_name(nullptr, token, nullptr, EntityState_Resolved); + Type *named = alloc_type_named(enum_name, elem, e); + e->type = named; + e->TypeName.is_type_alias = true; + elem = named; + } + #endif + type->BitSet.elem = elem; if (!is_type_valid_bit_set_elem(elem)) { error(bs->elem, "Expected an enum type for a bit_set"); @@ -2436,7 +2454,7 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t case_ast_node(bs, BitSetType, e); *type = alloc_type_bit_set(); set_base_type(named_type, *type); - check_bit_set_type(ctx, *type, e); + check_bit_set_type(ctx, *type, named_type, e); return true; case_end; diff --git a/src/parser.cpp b/src/parser.cpp index a162a4ee3..f029e7159 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2038,22 +2038,32 @@ Ast *parse_operand(AstFile *f, bool lhs) { case Token_bit_set: { Token token = expect_token(f, Token_bit_set); - Token open = expect_token(f, Token_OpenBracket); - Ast *elem = nullptr; - Ast *underlying = nullptr; + if (f->curr_token.kind == Token_OpenBrace) { + Token open = expect_token(f, Token_OpenBrace); - bool prev_allow_range = f->allow_range; - f->allow_range = true; - elem = parse_expr(f, false); - f->allow_range = prev_allow_range; - if (allow_token(f, Token_Semicolon)) { - underlying = parse_type(f); + Array values = parse_element_list(f); + Token close = expect_token(f, Token_CloseBrace); + Ast *enum_type = ast_enum_type(f, token, nullptr, values); + + return ast_bit_set_type(f, token, enum_type, nullptr); + } else { + expect_token(f, Token_OpenBracket); + + Ast *elem = nullptr; + Ast *underlying = nullptr; + + bool prev_allow_range = f->allow_range; + f->allow_range = true; + elem = parse_expr(f, false); + f->allow_range = prev_allow_range; + if (allow_token(f, Token_Semicolon)) { + underlying = parse_type(f); + } + + expect_token(f, Token_CloseBracket); + return ast_bit_set_type(f, token, elem, underlying); } - - Token close = expect_token(f, Token_CloseBracket); - - return ast_bit_set_type(f, token, elem, underlying); } default: { diff --git a/src/types.cpp b/src/types.cpp index 82744cedf..fa30b228b 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -1778,7 +1778,11 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty return sel; } } + } else if (type->kind == Type_BitSet) { + return lookup_field_with_selection(type->BitSet.elem, field_name, true, sel); } + + if (type->kind == Type_Generic && type->Generic.specialized != nullptr) { Type *specialized = type->Generic.specialized; return lookup_field_with_selection(specialized, field_name, is_type, sel);