| 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 | 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 | 607 | if (mod.lookupIdentifier(scope, ident_name)) |decl| { |
| 675 | 608 | const msg = msg: { |
| 676 | 609 | const msg = try mod.errMsg( |
| ... | ... | @@ -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 | 1463 | .enum_decl, |
| 1464 | 1464 | .enum_decl_nonexhaustive, |
| 1465 | 1465 | .opaque_decl, |
| 1466 | .error_set_decl, | |
| 1466 | 1467 | .int_to_enum, |
| 1467 | 1468 | .enum_to_int, |
| 1468 | 1469 | .type_info, |
| ... | ... | @@ -2930,11 +2931,37 @@ fn errorSetDecl( |
| 2930 | 2931 | node: ast.Node.Index, |
| 2931 | 2932 | ) InnerError!Zir.Inst.Ref { |
| 2932 | 2933 | const astgen = gz.astgen; |
| 2934 | const gpa = astgen.gpa; | |
| 2933 | 2935 | const tree = &astgen.file.tree; |
| 2934 | 2936 | const main_tokens = tree.nodes.items(.main_token); |
| 2935 | 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 | 2967 | fn orelseCatchExpr( |
src/Sema.zig+12| ... | ... | @@ -343,6 +343,7 @@ pub fn analyzeBody( |
| 343 | 343 | .enum_decl_nonexhaustive => try sema.zirEnumDecl(block, inst, true), |
| 344 | 344 | .union_decl => try sema.zirUnionDecl(block, inst), |
| 345 | 345 | .opaque_decl => try sema.zirOpaqueDecl(block, inst), |
| 346 | .error_set_decl => try sema.zirErrorSetDecl(block, inst), | |
| 346 | 347 | |
| 347 | 348 | .add => try sema.zirArithmetic(block, inst), |
| 348 | 349 | .addwrap => try sema.zirArithmetic(block, inst), |
| ... | ... | @@ -978,6 +979,17 @@ fn zirOpaqueDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr |
| 978 | 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 | 993 | fn zirRetPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { |
| 982 | 994 | const tracy = trace(@src()); |
| 983 | 995 | defer tracy.end(); |
src/Zir.zig+31-5| ... | ... | @@ -307,6 +307,9 @@ pub const Inst = struct { |
| 307 | 307 | /// An opaque type definition. Provides an AST node only. |
| 308 | 308 | /// Uses the `node` union field. |
| 309 | 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 | 313 | /// Declares the beginning of a statement. Used for debug info. |
| 311 | 314 | /// Uses the `node` union field. |
| 312 | 315 | dbg_stmt_node, |
| ... | ... | @@ -986,6 +989,7 @@ pub const Inst = struct { |
| 986 | 989 | .enum_decl, |
| 987 | 990 | .enum_decl_nonexhaustive, |
| 988 | 991 | .opaque_decl, |
| 992 | .error_set_decl, | |
| 989 | 993 | .dbg_stmt_node, |
| 990 | 994 | .decl_ref, |
| 991 | 995 | .decl_val, |
| ... | ... | @@ -2011,6 +2015,11 @@ pub const Inst = struct { |
| 2011 | 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 | 2023 | /// A f128 value, broken up into 4 u32 parts. |
| 2015 | 2024 | pub const Float128 = struct { |
| 2016 | 2025 | piece0: u32, |
| ... | ... | @@ -2328,6 +2337,8 @@ const Writer = struct { |
| 2328 | 2337 | .builtin_async_call, |
| 2329 | 2338 | => try self.writePlNode(stream, inst), |
| 2330 | 2339 | |
| 2340 | .error_set_decl => try self.writePlNodeErrorSetDecl(stream, inst), | |
| 2341 | ||
| 2331 | 2342 | .add_with_overflow, |
| 2332 | 2343 | .sub_with_overflow, |
| 2333 | 2344 | .mul_with_overflow, |
| ... | ... | @@ -2596,11 +2607,7 @@ const Writer = struct { |
| 2596 | 2607 | try stream.print("\"{}\")", .{std.zig.fmtEscapes(str)}); |
| 2597 | 2608 | } |
| 2598 | 2609 | |
| 2599 | fn writePlNode( | |
| 2600 | self: *Writer, | |
| 2601 | stream: anytype, | |
| 2602 | inst: Inst.Index, | |
| 2603 | ) (@TypeOf(stream).Error || error{OutOfMemory})!void { | |
| 2610 | fn writePlNode(self: *Writer, stream: anytype, inst: Inst.Index) !void { | |
| 2604 | 2611 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; |
| 2605 | 2612 | try stream.writeAll("TODO) "); |
| 2606 | 2613 | try self.writeSrc(stream, inst_data.src()); |
| ... | ... | @@ -2616,6 +2623,25 @@ const Writer = struct { |
| 2616 | 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 | 2645 | fn writePlNodeOverflowArithmetic(self: *Writer, stream: anytype, inst: Inst.Index) !void { |
| 2620 | 2646 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; |
| 2621 | 2647 | const extra = self.code.extraData(Inst.OverflowArithmetic, inst_data.payload_index).data; |