|
@@ -2164,6 +2164,49 @@ gb_internal Array<Ast *> parse_union_variant_list(AstFile *f) {
|
|
return variants;
|
|
return variants;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+gb_internal void parser_check_polymorphic_record_parameters(AstFile *f, Ast *polymorphic_params) {
|
|
|
|
+ if (polymorphic_params == nullptr) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (polymorphic_params->kind != Ast_FieldList) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ enum {Unknown, Dollar, Bare} prefix = Unknown;
|
|
|
|
+ gb_unused(prefix);
|
|
|
|
+
|
|
|
|
+ for (Ast *field : polymorphic_params->FieldList.list) {
|
|
|
|
+ if (field == nullptr || field->kind != Ast_Field) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ for (Ast *name : field->Field.names) {
|
|
|
|
+ if (name == nullptr) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ bool error = false;
|
|
|
|
+
|
|
|
|
+ if (name->kind == Ast_Ident) {
|
|
|
|
+ switch (prefix) {
|
|
|
|
+ case Unknown: prefix = Bare; break;
|
|
|
|
+ case Dollar: error = true; break;
|
|
|
|
+ case Bare: break;
|
|
|
|
+ }
|
|
|
|
+ } else if (name->kind == Ast_PolyType) {
|
|
|
|
+ switch (prefix) {
|
|
|
|
+ case Unknown: prefix = Dollar; break;
|
|
|
|
+ case Dollar: break;
|
|
|
|
+ case Bare: error = true; break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (error) {
|
|
|
|
+ syntax_error(name, "Mixture of polymorphic $ names and normal identifiers are not allowed within record parameters");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
gb_internal Ast *parse_operand(AstFile *f, bool lhs) {
|
|
gb_internal Ast *parse_operand(AstFile *f, bool lhs) {
|
|
Ast *operand = nullptr; // Operand
|
|
Ast *operand = nullptr; // Operand
|
|
switch (f->curr_token.kind) {
|
|
switch (f->curr_token.kind) {
|
|
@@ -2610,6 +2653,8 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) {
|
|
decls = fields->FieldList.list;
|
|
decls = fields->FieldList.list;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ parser_check_polymorphic_record_parameters(f, polymorphic_params);
|
|
|
|
+
|
|
return ast_struct_type(f, token, decls, name_count, polymorphic_params, is_packed, is_raw_union, no_copy, align, field_align, where_token, where_clauses);
|
|
return ast_struct_type(f, token, decls, name_count, polymorphic_params, is_packed, is_raw_union, no_copy, align, field_align, where_token, where_clauses);
|
|
} break;
|
|
} break;
|
|
|
|
|
|
@@ -2702,6 +2747,8 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) {
|
|
auto variants = parse_union_variant_list(f);
|
|
auto variants = parse_union_variant_list(f);
|
|
Token close = expect_closing_brace_of_field_list(f);
|
|
Token close = expect_closing_brace_of_field_list(f);
|
|
|
|
|
|
|
|
+ parser_check_polymorphic_record_parameters(f, polymorphic_params);
|
|
|
|
+
|
|
return ast_union_type(f, token, variants, polymorphic_params, align, union_kind, where_token, where_clauses);
|
|
return ast_union_type(f, token, variants, polymorphic_params, align, union_kind, where_token, where_clauses);
|
|
} break;
|
|
} break;
|
|
|
|
|