aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2018-09-02 16:33:54 +0100
committergingerBill <bill@gingerbill.org>2018-09-02 16:33:54 +0100
commit11f5236434ca08ae034a195639c8ed377e125015 (patch)
treeae295c53970f5a187d2d4f2fc7cf2ac9d8f1c04e /src
parent220485a2d2cd180e7ff2a15bab66c867c06b05d7 (diff)
Add `$T: typeid/[]$E`; Deprecate `T: type/[]$E`
`type` as a keyword will soon be removed in favour of polymorphic names (identifiers) in procedures
Diffstat (limited to 'src')
-rw-r--r--src/check_type.cpp43
-rw-r--r--src/parser.cpp56
2 files changed, 86 insertions, 13 deletions
diff --git a/src/check_type.cpp b/src/check_type.cpp
index 2eff33922..98d35cf0b 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -374,18 +374,20 @@ void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast *node, Array<
type_expr = type_expr->Ellipsis.expr;
error(param, "A polymorphic parameter cannot be variadic");
}
- if (type_expr->kind == Ast_TypeType) {
+ if (type_expr->kind == Ast_TypeidType) {
+ is_type_param = true;
+ Type *specialization = nullptr;
+ if (type_expr->TypeidType.specialization != nullptr) {
+ Ast *s = type_expr->TypeidType.specialization;
+ specialization = check_type(ctx, s);
+ }
+ type = alloc_type_generic(ctx->scope, 0, str_lit(""), specialization);
+ } else if (type_expr->kind == Ast_TypeType) {
is_type_param = true;
Type *specialization = nullptr;
if (type_expr->TypeType.specialization != nullptr) {
Ast *s = type_expr->TypeType.specialization;
specialization = check_type(ctx, s);
- // if (!is_type_polymorphic_struct(specialization)) {
- // gbString str = type_to_string(specialization);
- // defer (gb_string_free(str));
- // error(s, "Expected a polymorphic struct, got %s", str);
- // specialization = nullptr;
- // }
}
type = alloc_type_generic(ctx->scope, 0, str_lit(""), specialization);
} else {
@@ -1159,7 +1161,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
continue;
}
ast_node(p, Field, param);
- Ast *type_expr = p->type;
+ Ast *type_expr = unparen_expr(p->type);
Type *type = nullptr;
Ast *default_value = unparen_expr(p->default_value);
ParameterValue param_value = {};
@@ -1183,7 +1185,24 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
success = false;
}
}
- if (type_expr->kind == Ast_TypeType) {
+ if (type_expr->kind == Ast_TypeidType) {
+ ast_node(tt, TypeidType, type_expr);
+ if (tt->specialization) {
+ specialization = check_type(ctx, tt->specialization);
+ if (specialization == t_invalid){
+ specialization = nullptr;
+ }
+
+ if (operands != nullptr) {
+ detemine_type_from_operand = true;
+ type = t_invalid;
+ } else {
+ type = alloc_type_generic(ctx->scope, 0, str_lit(""), specialization);
+ }
+ } else {
+ type = t_typeid;
+ }
+ } else if (type_expr->kind == Ast_TypeType) {
ast_node(tt, TypeType, type_expr);
is_type_param = true;
specialization = check_type(ctx, tt->specialization);
@@ -1213,7 +1232,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
}
if (default_value != nullptr) {
- if (type_expr != nullptr && type_expr->kind == Ast_TypeType) {
+ if (type_expr != nullptr && (type_expr->kind == Ast_TypeType || type_expr->kind == Ast_TypeidType)) {
error(type_expr, "A type parameter may not have a default value");
} else {
param_value = handle_parameter_value(ctx, type, nullptr, default_value, true);
@@ -1281,7 +1300,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
}
if (is_poly_name) {
- if (type != nullptr && is_type_typeid(type)) {
+ if (type != nullptr && type_expr->kind == Ast_TypeidType) {
is_type_param = true;
} else {
error(name, "Polymorphic names are not yet supported for non-typeid parameters");
@@ -1324,7 +1343,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
}
if (p->flags&FieldFlag_auto_cast) {
- error(name, "'auto_cast' can only be applied variable fields");
+ error(name, "'auto_cast' can only be applied to variable fields");
p->flags &= ~FieldFlag_auto_cast;
}
diff --git a/src/parser.cpp b/src/parser.cpp
index f30728682..45a8dc3aa 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -2435,6 +2435,7 @@ Ast *parse_value_decl(AstFile *f, Array<Ast *> names, CommentGroup *docs) {
if (f->curr_token.kind == Token_type) {
type = ast_type_type(f, advance_token(f), nullptr);
+ warning(type, "'type' is deprecated");
is_mutable = false;
} else {
type = parse_type_or_ident(f);
@@ -2718,6 +2719,19 @@ Ast *parse_var_type(AstFile *f, bool allow_ellipsis, bool allow_type_token) {
specialization = parse_type(f);
}
type = ast_type_type(f, token, specialization);
+ if (specialization) {
+ warning(type, "'type' is deprecated, please use something like '$T: typeid/[]$E'");
+ } else {
+ warning(type, "'type' is deprecated, please use something like '$T: typeid'");
+ }
+ } else if (allow_type_token &&
+ f->curr_token.kind == Token_typeid) {
+ Token token = expect_token(f, Token_typeid);
+ Ast *specialization = nullptr;
+ if (allow_token(f, Token_Quo)) {
+ specialization = parse_type(f);
+ }
+ type = ast_typeid_type(f, token, specialization);
} else {
type = parse_type(f);
}
@@ -2855,7 +2869,7 @@ Array<Ast *> convert_to_ident_list(AstFile *f, Array<AstAndFlags> list, bool ign
case Ast_PolyType:
if (allow_poly_names) {
if (ident->PolyType.specialization == nullptr) {
- syntax_error(ident, "Polymorphic identifiers are not yet supported");
+ // syntax_error(ident, "Polymorphic identifiers are not yet supported");
break;
} else {
syntax_error(ident, "Expected a polymorphic identifier without any specialization");
@@ -2925,6 +2939,36 @@ Ast *parse_struct_field_list(AstFile *f, isize *name_count_) {
return params;
}
+
+// Returns true if any are polymorphic names
+bool check_procedure_name_list(Array<Ast *> const &names) {
+ if (names.count == 0) {
+ return false;
+ }
+ bool first_is_polymorphic = names[0]->kind == Ast_PolyType;
+ bool any_polymorphic_names = first_is_polymorphic;
+ for (isize i = 1; i < names.count; i++) {
+ Ast *name = names[i];
+ if (first_is_polymorphic) {
+ if (name->kind == Ast_PolyType) {
+ any_polymorphic_names = true;
+ } else {
+ syntax_error(name, "Mixture of polymorphic and non-polymorphic identifiers");
+ return any_polymorphic_names;
+ }
+ } else {
+ if (name->kind == Ast_PolyType) {
+ any_polymorphic_names = true;
+ syntax_error(name, "Mixture of polymorphic and non-polymorphic identifiers");
+ return any_polymorphic_names;
+ } else {
+ // Okay
+ }
+ }
+ }
+ return any_polymorphic_names;
+}
+
Ast *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKind follow, bool allow_default_parameters, bool allow_type_token) {
Token start_token = f->curr_token;
@@ -2965,6 +3009,7 @@ Ast *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKi
if (names.count == 0) {
syntax_error(f->curr_token, "Empty field declaration");
}
+ bool any_polymorphic_names = check_procedure_name_list(names);
u32 set_flags = 0;
if (list.count > 0) {
set_flags = list[0].flags;
@@ -2978,6 +3023,10 @@ Ast *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKi
expect_token_after(f, Token_Colon, "field list");
if (f->curr_token.kind != Token_Eq) {
type = parse_var_type(f, allow_ellipsis, allow_type_token);
+ Ast *tt = unparen_expr(type);
+ if (!any_polymorphic_names && tt->kind == Ast_TypeidType && tt->TypeidType.specialization != nullptr) {
+ syntax_error(type, "Specialization of typeid is not allowed without polymorphic names");
+ }
}
if (allow_token(f, Token_Eq)) {
@@ -3022,6 +3071,7 @@ Ast *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKi
syntax_error(f->curr_token, "Empty field declaration");
break;
}
+ bool any_polymorphic_names = check_procedure_name_list(names);
set_flags = check_field_prefixes(f, names.count, allowed_flags, set_flags);
total_name_count += names.count;
@@ -3030,6 +3080,10 @@ Ast *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKi
expect_token_after(f, Token_Colon, "field list");
if (f->curr_token.kind != Token_Eq) {
type = parse_var_type(f, allow_ellipsis, allow_type_token);
+ Ast *tt = unparen_expr(type);
+ if (!any_polymorphic_names && tt->kind == Ast_TypeidType && tt->TypeidType.specialization != nullptr) {
+ syntax_error(type, "Specialization of typeid is not allowed without polymorphic names");
+ }
}
if (allow_token(f, Token_Eq)) {