|
@@ -349,10 +349,12 @@ Ast *clone_ast(Ast *node) {
|
|
|
n->StructType.fields = clone_ast_array(n->StructType.fields);
|
|
|
n->StructType.polymorphic_params = clone_ast(n->StructType.polymorphic_params);
|
|
|
n->StructType.align = clone_ast(n->StructType.align);
|
|
|
+ n->StructType.where_clauses = clone_ast_array(n->StructType.where_clauses);
|
|
|
break;
|
|
|
case Ast_UnionType:
|
|
|
n->UnionType.variants = clone_ast_array(n->UnionType.variants);
|
|
|
n->UnionType.polymorphic_params = clone_ast(n->UnionType.polymorphic_params);
|
|
|
+ n->UnionType.where_clauses = clone_ast_array(n->UnionType.where_clauses);
|
|
|
break;
|
|
|
case Ast_EnumType:
|
|
|
n->EnumType.base_type = clone_ast(n->EnumType.base_type);
|
|
@@ -921,7 +923,8 @@ Ast *ast_dynamic_array_type(AstFile *f, Token token, Ast *elem) {
|
|
|
|
|
|
Ast *ast_struct_type(AstFile *f, Token token, Array<Ast *> fields, isize field_count,
|
|
|
Ast *polymorphic_params, bool is_packed, bool is_raw_union,
|
|
|
- Ast *align) {
|
|
|
+ Ast *align,
|
|
|
+ Token where_token, Array<Ast *> const &where_clauses) {
|
|
|
Ast *result = alloc_ast_node(f, Ast_StructType);
|
|
|
result->StructType.token = token;
|
|
|
result->StructType.fields = fields;
|
|
@@ -930,17 +933,22 @@ Ast *ast_struct_type(AstFile *f, Token token, Array<Ast *> fields, isize field_c
|
|
|
result->StructType.is_packed = is_packed;
|
|
|
result->StructType.is_raw_union = is_raw_union;
|
|
|
result->StructType.align = align;
|
|
|
+ result->StructType.where_token = where_token;
|
|
|
+ result->StructType.where_clauses = where_clauses;
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
|
|
|
-Ast *ast_union_type(AstFile *f, Token token, Array<Ast *> variants, Ast *polymorphic_params, Ast *align, bool no_nil) {
|
|
|
+Ast *ast_union_type(AstFile *f, Token token, Array<Ast *> variants, Ast *polymorphic_params, Ast *align, bool no_nil,
|
|
|
+ Token where_token, Array<Ast *> const &where_clauses) {
|
|
|
Ast *result = alloc_ast_node(f, Ast_UnionType);
|
|
|
result->UnionType.token = token;
|
|
|
result->UnionType.variants = variants;
|
|
|
result->UnionType.polymorphic_params = polymorphic_params;
|
|
|
result->UnionType.align = align;
|
|
|
result->UnionType.no_nil = no_nil;
|
|
|
+ result->UnionType.where_token = where_token;
|
|
|
+ result->UnionType.where_clauses = where_clauses;
|
|
|
return result;
|
|
|
}
|
|
|
|
|
@@ -2020,6 +2028,18 @@ Ast *parse_operand(AstFile *f, bool lhs) {
|
|
|
syntax_error(token, "'#raw_union' cannot also be '#packed'");
|
|
|
}
|
|
|
|
|
|
+ Token where_token = {};
|
|
|
+ Array<Ast *> where_clauses = {};
|
|
|
+
|
|
|
+ if (f->curr_token.kind == Token_where) {
|
|
|
+ where_token = expect_token(f, Token_where);
|
|
|
+ isize prev_level = f->expr_level;
|
|
|
+ f->expr_level = -1;
|
|
|
+ where_clauses = parse_rhs_expr_list(f);
|
|
|
+ f->expr_level = prev_level;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
Token open = expect_token_after(f, Token_OpenBrace, "struct");
|
|
|
|
|
|
isize name_count = 0;
|
|
@@ -2032,7 +2052,7 @@ Ast *parse_operand(AstFile *f, bool lhs) {
|
|
|
decls = fields->FieldList.list;
|
|
|
}
|
|
|
|
|
|
- return ast_struct_type(f, token, decls, name_count, polymorphic_params, is_packed, is_raw_union, align);
|
|
|
+ return ast_struct_type(f, token, decls, name_count, polymorphic_params, is_packed, is_raw_union, align, where_token, where_clauses);
|
|
|
} break;
|
|
|
|
|
|
case Token_union: {
|
|
@@ -2073,6 +2093,18 @@ Ast *parse_operand(AstFile *f, bool lhs) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ Token where_token = {};
|
|
|
+ Array<Ast *> where_clauses = {};
|
|
|
+
|
|
|
+ if (f->curr_token.kind == Token_where) {
|
|
|
+ where_token = expect_token(f, Token_where);
|
|
|
+ isize prev_level = f->expr_level;
|
|
|
+ f->expr_level = -1;
|
|
|
+ where_clauses = parse_rhs_expr_list(f);
|
|
|
+ f->expr_level = prev_level;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
Token open = expect_token_after(f, Token_OpenBrace, "union");
|
|
|
|
|
|
while (f->curr_token.kind != Token_CloseBrace &&
|
|
@@ -2088,7 +2120,7 @@ Ast *parse_operand(AstFile *f, bool lhs) {
|
|
|
|
|
|
Token close = expect_token(f, Token_CloseBrace);
|
|
|
|
|
|
- return ast_union_type(f, token, variants, polymorphic_params, align, no_nil);
|
|
|
+ return ast_union_type(f, token, variants, polymorphic_params, align, no_nil, where_token, where_clauses);
|
|
|
} break;
|
|
|
|
|
|
case Token_enum: {
|
|
@@ -4424,19 +4456,6 @@ bool determine_path_from_string(gbMutex *file_mutex, Ast *node, String base_dir,
|
|
|
}
|
|
|
|
|
|
|
|
|
- if (is_package_name_reserved(file_str)) {
|
|
|
- *path = file_str;
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- if (file_mutex) gb_mutex_lock(file_mutex);
|
|
|
- defer (if (file_mutex) gb_mutex_unlock(file_mutex));
|
|
|
-
|
|
|
-
|
|
|
- if (node->kind == Ast_ForeignImportDecl) {
|
|
|
- node->ForeignImportDecl.collection_name = collection_name;
|
|
|
- }
|
|
|
-
|
|
|
if (collection_name.len > 0) {
|
|
|
if (collection_name == "system") {
|
|
|
if (node->kind != Ast_ForeignImportDecl) {
|
|
@@ -4467,6 +4486,20 @@ bool determine_path_from_string(gbMutex *file_mutex, Ast *node, String base_dir,
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ if (is_package_name_reserved(file_str)) {
|
|
|
+ *path = file_str;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (file_mutex) gb_mutex_lock(file_mutex);
|
|
|
+ defer (if (file_mutex) gb_mutex_unlock(file_mutex));
|
|
|
+
|
|
|
+
|
|
|
+ if (node->kind == Ast_ForeignImportDecl) {
|
|
|
+ node->ForeignImportDecl.collection_name = collection_name;
|
|
|
+ }
|
|
|
+
|
|
|
if (has_windows_drive) {
|
|
|
*path = file_str;
|
|
|
} else {
|