| author | |
| committer | |
| log | 7f931a75229b4d6b9d07a7485bfc1726a92fc591 |
| tree | 43204015dc5eee275711d33238d3d40f41815bc1 |
| parent | 2083208f19a4eb7caa1953980f9a2f2496115695 |
4 files changed, 88 insertions(+), 73 deletions(-)
BRANCH_TODO+17-67| ... | @@ -604,73 +604,6 @@ fn astgenAndSemaVarDecl( | ... | @@ -604,73 +604,6 @@ fn astgenAndSemaVarDecl( |
| 604 | } | 604 | } |
| 605 | 605 | ||
| 606 | 606 | ||
| 607 | fn errorSetDecl( | ||
| 608 | gz: *GenZir, | ||
| 609 | scope: *Scope, | ||
| 610 | rl: ResultLoc, | ||
| 611 | node: ast.Node.Index, | ||
| 612 | ) InnerError!Zir.Inst.Ref { | ||
| 613 | const astgen = gz.astgen; | ||
| 614 | const tree = &astgen.file.tree; | ||
| 615 | const main_tokens = tree.nodes.items(.main_token); | ||
| 616 | const token_tags = tree.tokens.items(.tag); | ||
| 617 | |||
| 618 | // Count how many fields there are. | ||
| 619 | const error_token = main_tokens[node]; | ||
| 620 | const count: usize = count: { | ||
| 621 | var tok_i = error_token + 2; | ||
| 622 | var count: usize = 0; | ||
| 623 | while (true) : (tok_i += 1) { | ||
| 624 | switch (token_tags[tok_i]) { | ||
| 625 | .doc_comment, .comma => {}, | ||
| 626 | .identifier => count += 1, | ||
| 627 | .r_brace => break :count count, | ||
| 628 | else => unreachable, | ||
| 629 | } | ||
| 630 | } else unreachable; // TODO should not need else unreachable here | ||
| 631 | }; | ||
| 632 | |||
| 633 | const gpa = astgen.gpa; | ||
| 634 | var new_decl_arena = std.heap.ArenaAllocator.init(gpa); | ||
| 635 | errdefer new_decl_arena.deinit(); | ||
| 636 | const arena = &new_decl_arena.allocator; | ||
| 637 | |||
| 638 | const fields = try arena.alloc([]const u8, count); | ||
| 639 | { | ||
| 640 | var tok_i = error_token + 2; | ||
| 641 | var field_i: usize = 0; | ||
| 642 | while (true) : (tok_i += 1) { | ||
| 643 | switch (token_tags[tok_i]) { | ||
| 644 | .doc_comment, .comma => {}, | ||
| 645 | .identifier => { | ||
| 646 | fields[field_i] = try astgen.identifierTokenStringTreeArena(tok_i, tree, arena); | ||
| 647 | field_i += 1; | ||
| 648 | }, | ||
| 649 | .r_brace => break, | ||
| 650 | else => unreachable, | ||
| 651 | } | ||
| 652 | } | ||
| 653 | } | ||
| 654 | const error_set = try arena.create(Module.ErrorSet); | ||
| 655 | error_set.* = .{ | ||
| 656 | .owner_decl = astgen.decl, | ||
| 657 | .node_offset = astgen.decl.nodeIndexToRelative(node), | ||
| 658 | .names_ptr = fields.ptr, | ||
| 659 | .names_len = @intCast(u32, fields.len), | ||
| 660 | }; | ||
| 661 | const error_set_ty = try Type.Tag.error_set.create(arena, error_set); | ||
| 662 | const error_set_val = try Value.Tag.ty.create(arena, error_set_ty); | ||
| 663 | const new_decl = try mod.createAnonymousDecl(scope, &new_decl_arena, .{ | ||
| 664 | .ty = Type.initTag(.type), | ||
| 665 | .val = error_set_val, | ||
| 666 | }); | ||
| 667 | const decl_index = try mod.declareDeclDependency(astgen.decl, new_decl); | ||
| 668 | const result = try gz.addDecl(.decl_val, decl_index, node); | ||
| 669 | return rvalue(gz, scope, rl, result, node); | ||
| 670 | } | ||
| 671 | |||
| 672 | |||
| 673 | |||
| 674 | if (mod.lookupIdentifier(scope, ident_name)) |decl| { | 607 | if (mod.lookupIdentifier(scope, ident_name)) |decl| { |
| 675 | const msg = msg: { | 608 | const msg = msg: { |
| 676 | const msg = try mod.errMsg( | 609 | const msg = try mod.errMsg( |
| ... | @@ -761,3 +694,20 @@ fn errorSetDecl( | ... | @@ -761,3 +694,20 @@ fn errorSetDecl( |
| 761 | ); | 694 | ); |
| 762 | } | 695 | } |
| 763 | 696 | ||
| 697 | |||
| 698 | const error_set = try arena.create(Module.ErrorSet); | ||
| 699 | error_set.* = .{ | ||
| 700 | .owner_decl = astgen.decl, | ||
| 701 | .node_offset = astgen.decl.nodeIndexToRelative(node), | ||
| 702 | .names_ptr = fields.ptr, | ||
| 703 | .names_len = @intCast(u32, fields.len), | ||
| 704 | }; | ||
| 705 | const error_set_ty = try Type.Tag.error_set.create(arena, error_set); | ||
| 706 | const error_set_val = try Value.Tag.ty.create(arena, error_set_ty); | ||
| 707 | const new_decl = try mod.createAnonymousDecl(scope, &new_decl_arena, .{ | ||
| 708 | .ty = Type.initTag(.type), | ||
| 709 | .val = error_set_val, | ||
| 710 | }); | ||
| 711 | const decl_index = try mod.declareDeclDependency(astgen.decl, new_decl); | ||
| 712 | const result = try gz.addDecl(.decl_val, decl_index, node); | ||
| 713 | return rvalue(gz, scope, rl, result, node); |
src/AstGen.zig+28-1| ... | @@ -1463,6 +1463,7 @@ fn blockExprStmts( | ... | @@ -1463,6 +1463,7 @@ fn blockExprStmts( |
| 1463 | .enum_decl, | 1463 | .enum_decl, |
| 1464 | .enum_decl_nonexhaustive, | 1464 | .enum_decl_nonexhaustive, |
| 1465 | .opaque_decl, | 1465 | .opaque_decl, |
| 1466 | .error_set_decl, | ||
| 1466 | .int_to_enum, | 1467 | .int_to_enum, |
| 1467 | .enum_to_int, | 1468 | .enum_to_int, |
| 1468 | .type_info, | 1469 | .type_info, |
| ... | @@ -2930,11 +2931,37 @@ fn errorSetDecl( | ... | @@ -2930,11 +2931,37 @@ fn errorSetDecl( |
| 2930 | node: ast.Node.Index, | 2931 | node: ast.Node.Index, |
| 2931 | ) InnerError!Zir.Inst.Ref { | 2932 | ) InnerError!Zir.Inst.Ref { |
| 2932 | const astgen = gz.astgen; | 2933 | const astgen = gz.astgen; |
| 2934 | const gpa = astgen.gpa; | ||
| 2933 | const tree = &astgen.file.tree; | 2935 | const tree = &astgen.file.tree; |
| 2934 | const main_tokens = tree.nodes.items(.main_token); | 2936 | const main_tokens = tree.nodes.items(.main_token); |
| 2935 | const token_tags = tree.tokens.items(.tag); | 2937 | const token_tags = tree.tokens.items(.tag); |
| 2936 | 2938 | ||
| 2937 | return astgen.failNode(node, "TODO AstGen errorSetDecl", .{}); | 2939 | var field_names: std.ArrayListUnmanaged(u32) = .{}; |
| 2940 | defer field_names.deinit(gpa); | ||
| 2941 | |||
| 2942 | { | ||
| 2943 | const error_token = main_tokens[node]; | ||
| 2944 | var tok_i = error_token + 2; | ||
| 2945 | var field_i: usize = 0; | ||
| 2946 | while (true) : (tok_i += 1) { | ||
| 2947 | switch (token_tags[tok_i]) { | ||
| 2948 | .doc_comment, .comma => {}, | ||
| 2949 | .identifier => { | ||
| 2950 | const str_index = try gz.identAsString(tok_i); | ||
| 2951 | try field_names.append(gpa, str_index); | ||
| 2952 | field_i += 1; | ||
| 2953 | }, | ||
| 2954 | .r_brace => break, | ||
| 2955 | else => unreachable, | ||
| 2956 | } | ||
| 2957 | } | ||
| 2958 | } | ||
| 2959 | |||
| 2960 | const result = try gz.addPlNode(.error_set_decl, node, Zir.Inst.ErrorSetDecl{ | ||
| 2961 | .fields_len = @intCast(u32, field_names.items.len), | ||
| 2962 | }); | ||
| 2963 | try astgen.extra.appendSlice(gpa, field_names.items); | ||
| 2964 | return rvalue(gz, scope, rl, result, node); | ||
| 2938 | } | 2965 | } |
| 2939 | 2966 | ||
| 2940 | fn orelseCatchExpr( | 2967 | fn orelseCatchExpr( |
src/Sema.zig+12| ... | @@ -343,6 +343,7 @@ pub fn analyzeBody( | ... | @@ -343,6 +343,7 @@ pub fn analyzeBody( |
| 343 | .enum_decl_nonexhaustive => try sema.zirEnumDecl(block, inst, true), | 343 | .enum_decl_nonexhaustive => try sema.zirEnumDecl(block, inst, true), |
| 344 | .union_decl => try sema.zirUnionDecl(block, inst), | 344 | .union_decl => try sema.zirUnionDecl(block, inst), |
| 345 | .opaque_decl => try sema.zirOpaqueDecl(block, inst), | 345 | .opaque_decl => try sema.zirOpaqueDecl(block, inst), |
| 346 | .error_set_decl => try sema.zirErrorSetDecl(block, inst), | ||
| 346 | 347 | ||
| 347 | .add => try sema.zirArithmetic(block, inst), | 348 | .add => try sema.zirArithmetic(block, inst), |
| 348 | .addwrap => try sema.zirArithmetic(block, inst), | 349 | .addwrap => try sema.zirArithmetic(block, inst), |
| ... | @@ -978,6 +979,17 @@ fn zirOpaqueDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr | ... | @@ -978,6 +979,17 @@ fn zirOpaqueDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr |
| 978 | return sema.mod.fail(&block.base, sema.src, "TODO implement zirOpaqueDecl", .{}); | 979 | return sema.mod.fail(&block.base, sema.src, "TODO implement zirOpaqueDecl", .{}); |
| 979 | } | 980 | } |
| 980 | 981 | ||
| 982 | fn zirErrorSetDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { | ||
| 983 | const tracy = trace(@src()); | ||
| 984 | defer tracy.end(); | ||
| 985 | |||
| 986 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | ||
| 987 | const src = inst_data.src(); | ||
| 988 | const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index); | ||
| 989 | |||
| 990 | return sema.mod.fail(&block.base, sema.src, "TODO implement zirErrorSetDecl", .{}); | ||
| 991 | } | ||
| 992 | |||
| 981 | fn zirRetPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { | 993 | fn zirRetPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { |
| 982 | const tracy = trace(@src()); | 994 | const tracy = trace(@src()); |
| 983 | defer tracy.end(); | 995 | defer tracy.end(); |
src/Zir.zig+31-5| ... | @@ -307,6 +307,9 @@ pub const Inst = struct { | ... | @@ -307,6 +307,9 @@ pub const Inst = struct { |
| 307 | /// An opaque type definition. Provides an AST node only. | 307 | /// An opaque type definition. Provides an AST node only. |
| 308 | /// Uses the `node` union field. | 308 | /// Uses the `node` union field. |
| 309 | opaque_decl, | 309 | opaque_decl, |
| 310 | /// An error set type definition. Contains a list of field names. | ||
| 311 | /// Uses the `pl_node` union field. Payload is `ErrorSetDecl`. | ||
| 312 | error_set_decl, | ||
| 310 | /// Declares the beginning of a statement. Used for debug info. | 313 | /// Declares the beginning of a statement. Used for debug info. |
| 311 | /// Uses the `node` union field. | 314 | /// Uses the `node` union field. |
| 312 | dbg_stmt_node, | 315 | dbg_stmt_node, |
| ... | @@ -986,6 +989,7 @@ pub const Inst = struct { | ... | @@ -986,6 +989,7 @@ pub const Inst = struct { |
| 986 | .enum_decl, | 989 | .enum_decl, |
| 987 | .enum_decl_nonexhaustive, | 990 | .enum_decl_nonexhaustive, |
| 988 | .opaque_decl, | 991 | .opaque_decl, |
| 992 | .error_set_decl, | ||
| 989 | .dbg_stmt_node, | 993 | .dbg_stmt_node, |
| 990 | .decl_ref, | 994 | .decl_ref, |
| 991 | .decl_val, | 995 | .decl_val, |
| ... | @@ -2011,6 +2015,11 @@ pub const Inst = struct { | ... | @@ -2011,6 +2015,11 @@ pub const Inst = struct { |
| 2011 | fields_len: u32, | 2015 | fields_len: u32, |
| 2012 | }; | 2016 | }; |
| 2013 | 2017 | ||
| 2018 | /// Trailing: field_name: u32 // for every field: null terminated string index | ||
| 2019 | pub const ErrorSetDecl = struct { | ||
| 2020 | fields_len: u32, | ||
| 2021 | }; | ||
| 2022 | |||
| 2014 | /// A f128 value, broken up into 4 u32 parts. | 2023 | /// A f128 value, broken up into 4 u32 parts. |
| 2015 | pub const Float128 = struct { | 2024 | pub const Float128 = struct { |
| 2016 | piece0: u32, | 2025 | piece0: u32, |
| ... | @@ -2328,6 +2337,8 @@ const Writer = struct { | ... | @@ -2328,6 +2337,8 @@ const Writer = struct { |
| 2328 | .builtin_async_call, | 2337 | .builtin_async_call, |
| 2329 | => try self.writePlNode(stream, inst), | 2338 | => try self.writePlNode(stream, inst), |
| 2330 | 2339 | ||
| 2340 | .error_set_decl => try self.writePlNodeErrorSetDecl(stream, inst), | ||
| 2341 | |||
| 2331 | .add_with_overflow, | 2342 | .add_with_overflow, |
| 2332 | .sub_with_overflow, | 2343 | .sub_with_overflow, |
| 2333 | .mul_with_overflow, | 2344 | .mul_with_overflow, |
| ... | @@ -2596,11 +2607,7 @@ const Writer = struct { | ... | @@ -2596,11 +2607,7 @@ const Writer = struct { |
| 2596 | try stream.print("\"{}\")", .{std.zig.fmtEscapes(str)}); | 2607 | try stream.print("\"{}\")", .{std.zig.fmtEscapes(str)}); |
| 2597 | } | 2608 | } |
| 2598 | 2609 | ||
| 2599 | fn writePlNode( | 2610 | fn writePlNode(self: *Writer, stream: anytype, inst: Inst.Index) !void { |
| 2600 | self: *Writer, | ||
| 2601 | stream: anytype, | ||
| 2602 | inst: Inst.Index, | ||
| 2603 | ) (@TypeOf(stream).Error || error{OutOfMemory})!void { | ||
| 2604 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; | 2611 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; |
| 2605 | try stream.writeAll("TODO) "); | 2612 | try stream.writeAll("TODO) "); |
| 2606 | try self.writeSrc(stream, inst_data.src()); | 2613 | try self.writeSrc(stream, inst_data.src()); |
| ... | @@ -2616,6 +2623,25 @@ const Writer = struct { | ... | @@ -2616,6 +2623,25 @@ const Writer = struct { |
| 2616 | try self.writeSrc(stream, inst_data.src()); | 2623 | try self.writeSrc(stream, inst_data.src()); |
| 2617 | } | 2624 | } |
| 2618 | 2625 | ||
| 2626 | fn writePlNodeErrorSetDecl(self: *Writer, stream: anytype, inst: Inst.Index) !void { | ||
| 2627 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; | ||
| 2628 | const extra = self.code.extraData(Inst.ErrorSetDecl, inst_data.payload_index); | ||
| 2629 | const fields = self.code.extra[extra.end..][0..extra.data.fields_len]; | ||
| 2630 | |||
| 2631 | try stream.writeAll("{\n"); | ||
| 2632 | self.indent += 2; | ||
| 2633 | for (fields) |str_index| { | ||
| 2634 | const name = self.code.nullTerminatedString(str_index); | ||
| 2635 | try stream.writeByteNTimes(' ', self.indent); | ||
| 2636 | try stream.print("{},\n", .{std.zig.fmtId(name)}); | ||
| 2637 | } | ||
| 2638 | self.indent -= 2; | ||
| 2639 | try stream.writeByteNTimes(' ', self.indent); | ||
| 2640 | try stream.writeAll("}) "); | ||
| 2641 | |||
| 2642 | try self.writeSrc(stream, inst_data.src()); | ||
| 2643 | } | ||
| 2644 | |||
| 2619 | fn writePlNodeOverflowArithmetic(self: *Writer, stream: anytype, inst: Inst.Index) !void { | 2645 | fn writePlNodeOverflowArithmetic(self: *Writer, stream: anytype, inst: Inst.Index) !void { |
| 2620 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; | 2646 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; |
| 2621 | const extra = self.code.extraData(Inst.OverflowArithmetic, inst_data.payload_index).data; | 2647 | const extra = self.code.extraData(Inst.OverflowArithmetic, inst_data.payload_index).data; |