diff options
| author | gingerBill <bill@gingerbill.org> | 2018-02-05 22:46:30 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2018-02-05 22:46:30 +0000 |
| commit | 92780e2683927b75d2b4a35e96cf4ebe0637006c (patch) | |
| tree | 34c74f47b549d71496206d63324ee1a90981d10a /src/check_decl.cpp | |
| parent | 2891988d3bd04c173f79eb462d2f8dfd58d9c171 (diff) | |
`distinct` keyword for type declarations
Diffstat (limited to 'src/check_decl.cpp')
| -rw-r--r-- | src/check_decl.cpp | 75 |
1 files changed, 57 insertions, 18 deletions
diff --git a/src/check_decl.cpp b/src/check_decl.cpp index f85e88c0f..0c4ff6735 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -170,22 +170,57 @@ void check_init_constant(Checker *c, Entity *e, Operand *operand) { e->Constant.value = operand->value; } -AstNode *remove_type_alias(AstNode *node) { + +bool is_type_distinct(AstNode *node) { + for (;;) { + if (node == nullptr) { + return false; + } + if (node->kind == AstNode_ParenExpr) { + node = node->ParenExpr.expr; + } else if (node->kind == AstNode_HelperType) { + node = node->HelperType.type; + } else { + break; + } + } + + switch (node->kind) { + case AstNode_DistinctType: + return true; + + case AstNode_StructType: + case AstNode_UnionType: + case AstNode_EnumType: + case AstNode_BitFieldType: + case AstNode_ProcType: + return true; + + case AstNode_PointerType: + case AstNode_ArrayType: + case AstNode_DynamicArrayType: + case AstNode_MapType: + return true; + } + return false; +} + +AstNode *remove_type_alias_clutter(AstNode *node) { for (;;) { if (node == nullptr) { return nullptr; } if (node->kind == AstNode_ParenExpr) { node = node->ParenExpr.expr; - } else if (node->kind == AstNode_AliasType) { - node = node->AliasType.type; + } else if (node->kind == AstNode_DistinctType) { + node = node->DistinctType.type; } else { return node; } } } -void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, bool is_alias) { +void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def) { GB_ASSERT(e->type == nullptr); DeclInfo *decl = decl_info_of_entity(&c->info, e); @@ -193,7 +228,8 @@ void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, bool error(decl->attributes[0], "Attributes are not allowed on type declarations"); } - AstNode *te = remove_type_alias(type_expr); + bool is_distinct = is_type_distinct(type_expr); + AstNode *te = remove_type_alias_clutter(type_expr); e->type = t_invalid; String name = e->token.string; Type *named = make_type_named(c->allocator, name, nullptr, e); @@ -205,16 +241,20 @@ void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, bool Type *bt = check_type(c, te, named); named->Named.base = base_type(bt); - if (is_alias) { - if (is_type_named(bt)) { - e->type = bt; - e->TypeName.is_type_alias = true; - } else { - gbString str = type_to_string(bt); - error(type_expr, "Type alias declaration with a non-named type '%s'", str); - gb_string_free(str); - } - } + if (!is_distinct) { + e->type = bt; + e->TypeName.is_type_alias = true; + } + // if (is_alias) { + // if (is_type_named(bt)) { + // e->type = bt; + // e->TypeName.is_type_alias = true; + // } else { + // gbString str = type_to_string(bt); + // error(type_expr, "Type alias declaration with a non-named type '%s'", str); + // gb_string_free(str); + // } + // } } void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init, Type *named_type) { @@ -261,7 +301,7 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init, error(e->token, "A type declaration cannot have an type parameter"); } d->type_expr = d->init_expr; - check_type_decl(c, e, d->type_expr, named_type, false); + check_type_decl(c, e, d->type_expr, named_type); return; } @@ -866,8 +906,7 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) { check_const_decl(c, e, d->type_expr, d->init_expr, named_type); break; case Entity_TypeName: { - bool is_alias = unparen_expr(d->type_expr)->kind == AstNode_AliasType; - check_type_decl(c, e, d->type_expr, named_type, is_alias); + check_type_decl(c, e, d->type_expr, named_type); break; } case Entity_Procedure: |