Browse Source

Syntactic sugar for anonymous enum within a bit set

gingerBill 7 years ago
parent
commit
f1e1814ff9
4 changed files with 46 additions and 15 deletions
  1. 0 1
      src/check_decl.cpp
  2. 20 2
      src/check_type.cpp
  3. 22 12
      src/parser.cpp
  4. 4 0
      src/types.cpp

+ 0 - 1
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;
 	}

+ 20 - 2
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;
 

+ 22 - 12
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<Ast *> 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);
 
-		Token close = expect_token(f, Token_CloseBracket);
+			Ast *elem = nullptr;
+			Ast *underlying = nullptr;
 
-		return ast_bit_set_type(f, token, elem, underlying);
+			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);
+		}
 	}
 
 	default: {

+ 4 - 0
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);