diff options
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index 520a23c5a..aa90651d3 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -448,7 +448,8 @@ gb_internal Ast *clone_ast(Ast *node, AstFile *f) { n->StructType.fields = clone_ast_array(n->StructType.fields, f); n->StructType.polymorphic_params = clone_ast(n->StructType.polymorphic_params, f); n->StructType.align = clone_ast(n->StructType.align, f); - n->StructType.field_align = clone_ast(n->StructType.field_align, f); + n->StructType.min_field_align = clone_ast(n->StructType.min_field_align, f); + n->StructType.max_field_align = clone_ast(n->StructType.max_field_align, f); n->StructType.where_clauses = clone_ast_array(n->StructType.where_clauses, f); break; case Ast_UnionType: @@ -1217,7 +1218,7 @@ gb_internal Ast *ast_dynamic_array_type(AstFile *f, Token token, Ast *elem) { gb_internal Ast *ast_struct_type(AstFile *f, Token token, Slice<Ast *> fields, isize field_count, Ast *polymorphic_params, bool is_packed, bool is_raw_union, bool is_no_copy, - Ast *align, Ast *field_align, + Ast *align, Ast *min_field_align, Ast *max_field_align, Token where_token, Array<Ast *> const &where_clauses) { Ast *result = alloc_ast_node(f, Ast_StructType); result->StructType.token = token; @@ -1228,7 +1229,8 @@ gb_internal Ast *ast_struct_type(AstFile *f, Token token, Slice<Ast *> fields, i result->StructType.is_raw_union = is_raw_union; result->StructType.is_no_copy = is_no_copy; result->StructType.align = align; - result->StructType.field_align = field_align; + result->StructType.min_field_align = min_field_align; + result->StructType.max_field_align = max_field_align; result->StructType.where_token = where_token; result->StructType.where_clauses = slice_from_array(where_clauses); return result; @@ -2486,6 +2488,7 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { tag = parse_call_expr(f, tag); } Ast *type = parse_type(f); + syntax_error(tag, "#relative types have now been removed in favour of \"core:relative\""); return ast_relative_type(f, tag, type); } else if (name.string == "force_inline" || name.string == "force_no_inline") { @@ -2757,7 +2760,8 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { bool is_raw_union = false; bool no_copy = false; Ast *align = nullptr; - Ast *field_align = nullptr; + Ast *min_field_align = nullptr; + Ast *max_field_align = nullptr; if (allow_token(f, Token_OpenParen)) { isize param_count = 0; @@ -2795,18 +2799,43 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { gb_string_free(s); } } else if (tag.string == "field_align") { - if (field_align) { + if (min_field_align) { syntax_error(tag, "Duplicate struct tag '#%.*s'", LIT(tag.string)); } - field_align = parse_expr(f, true); - if (field_align && field_align->kind != Ast_ParenExpr) { + syntax_warning(tag, "#field_align has been deprecated in favour of #min_field_align"); + min_field_align = parse_expr(f, true); + if (min_field_align && min_field_align->kind != Ast_ParenExpr) { ERROR_BLOCK(); - gbString s = expr_to_string(field_align); + gbString s = expr_to_string(min_field_align); syntax_warning(tag, "#field_align requires parentheses around the expression"); - error_line("\tSuggestion: #field_align(%s)", s); + error_line("\tSuggestion: #min_field_align(%s)", s); gb_string_free(s); } - } else if (tag.string == "raw_union") { + } else if (tag.string == "min_field_align") { + if (min_field_align) { + syntax_error(tag, "Duplicate struct tag '#%.*s'", LIT(tag.string)); + } + min_field_align = parse_expr(f, true); + if (min_field_align && min_field_align->kind != Ast_ParenExpr) { + ERROR_BLOCK(); + gbString s = expr_to_string(min_field_align); + syntax_warning(tag, "#min_field_align requires parentheses around the expression"); + error_line("\tSuggestion: #min_field_align(%s)", s); + gb_string_free(s); + } + } else if (tag.string == "max_field_align") { + if (max_field_align) { + syntax_error(tag, "Duplicate struct tag '#%.*s'", LIT(tag.string)); + } + max_field_align = parse_expr(f, true); + if (max_field_align && max_field_align->kind != Ast_ParenExpr) { + ERROR_BLOCK(); + gbString s = expr_to_string(max_field_align); + syntax_warning(tag, "#max_field_align requires parentheses around the expression"); + error_line("\tSuggestion: #max_field_align(%s)", s); + gb_string_free(s); + } + }else if (tag.string == "raw_union") { if (is_raw_union) { syntax_error(tag, "Duplicate struct tag '#%.*s'", LIT(tag.string)); } @@ -2856,7 +2885,7 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { 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, min_field_align, max_field_align, where_token, where_clauses); } break; case Token_union: { @@ -4234,8 +4263,6 @@ gb_internal bool allow_field_separator(AstFile *f) { gb_internal Ast *parse_struct_field_list(AstFile *f, isize *name_count_) { Token start_token = f->curr_token; - auto decls = array_make<Ast *>(ast_allocator(f)); - isize total_name_count = 0; Ast *params = parse_field_list(f, &total_name_count, FieldFlag_Struct, Token_CloseBrace, false, false); @@ -4377,10 +4404,14 @@ gb_internal Ast *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_fl } } - allow_field_separator(f); + bool more_fields = allow_field_separator(f); Ast *param = ast_field(f, names, type, default_value, set_flags, tag, docs, f->line_comment); array_add(¶ms, param); + if (!more_fields) { + if (name_count_) *name_count_ = total_name_count; + return ast_field_list(f, start_token, params); + } while (f->curr_token.kind != follow && f->curr_token.kind != Token_EOF && |