| author | |
| committer | |
| log | 6e05d53e88e07d6234aaf6e0b86cd52d8c9aea92 |
| tree | ce5cfe10979d9da235a2944b714bfc1eb77ba824 |
| parent | 91e1414b50beac41b8eee5e3a9f8ef7bdc67fdef |
3 files changed, 70 insertions(+), 1 deletions(-)
src/AstGen.zig+27-1| ... | @@ -823,7 +823,31 @@ pub fn structInitExpr( | ... | @@ -823,7 +823,31 @@ pub fn structInitExpr( |
| 823 | .none, .none_or_ref => return mod.failNode(scope, node, "TODO implement structInitExpr none", .{}), | 823 | .none, .none_or_ref => return mod.failNode(scope, node, "TODO implement structInitExpr none", .{}), |
| 824 | .ref => unreachable, // struct literal not valid as l-value | 824 | .ref => unreachable, // struct literal not valid as l-value |
| 825 | .ty => |ty_inst| { | 825 | .ty => |ty_inst| { |
| 826 | return mod.failNode(scope, node, "TODO implement structInitExpr ty", .{}); | 826 | const fields_list = try gpa.alloc(zir.Inst.StructInit.Item, struct_init.ast.fields.len); |
| 827 | defer gpa.free(fields_list); | ||
| 828 | |||
| 829 | for (struct_init.ast.fields) |field_init, i| { | ||
| 830 | const name_token = tree.firstToken(field_init) - 2; | ||
| 831 | const str_index = try gz.identAsString(name_token); | ||
| 832 | |||
| 833 | const field_ty_inst = try gz.addPlNode(.field_type, field_init, zir.Inst.FieldType{ | ||
| 834 | .container_type = ty_inst, | ||
| 835 | .name_start = str_index, | ||
| 836 | }); | ||
| 837 | fields_list[i] = .{ | ||
| 838 | .field_type = astgen.refToIndex(field_ty_inst).?, | ||
| 839 | .init = try expr(gz, scope, .{ .ty = field_ty_inst }, field_init), | ||
| 840 | }; | ||
| 841 | } | ||
| 842 | const init_inst = try gz.addPlNode(.struct_init, node, zir.Inst.StructInit{ | ||
| 843 | .fields_len = @intCast(u32, fields_list.len), | ||
| 844 | }); | ||
| 845 | try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len + | ||
| 846 | fields_list.len * @typeInfo(zir.Inst.StructInit.Item).Struct.fields.len); | ||
| 847 | for (fields_list) |field| { | ||
| 848 | _ = gz.astgen.addExtraAssumeCapacity(field); | ||
| 849 | } | ||
| 850 | return rvalue(gz, scope, rl, init_inst, node); | ||
| 827 | }, | 851 | }, |
| 828 | .ptr => |ptr_inst| { | 852 | .ptr => |ptr_inst| { |
| 829 | const field_ptr_list = try gpa.alloc(zir.Inst.Index, struct_init.ast.fields.len); | 853 | const field_ptr_list = try gpa.alloc(zir.Inst.Index, struct_init.ast.fields.len); |
| ... | @@ -1321,6 +1345,8 @@ fn blockExprStmts( | ... | @@ -1321,6 +1345,8 @@ fn blockExprStmts( |
| 1321 | .switch_capture_else, | 1345 | .switch_capture_else, |
| 1322 | .switch_capture_else_ref, | 1346 | .switch_capture_else_ref, |
| 1323 | .struct_init_empty, | 1347 | .struct_init_empty, |
| 1348 | .struct_init, | ||
| 1349 | .field_type, | ||
| 1324 | .struct_decl, | 1350 | .struct_decl, |
| 1325 | .struct_decl_packed, | 1351 | .struct_decl_packed, |
| 1326 | .struct_decl_extern, | 1352 | .struct_decl_extern, |
src/Sema.zig+14| ... | @@ -264,6 +264,8 @@ pub fn analyzeBody( | ... | @@ -264,6 +264,8 @@ pub fn analyzeBody( |
| 264 | .typeof_peer => try sema.zirTypeofPeer(block, inst), | 264 | .typeof_peer => try sema.zirTypeofPeer(block, inst), |
| 265 | .xor => try sema.zirBitwise(block, inst, .xor), | 265 | .xor => try sema.zirBitwise(block, inst, .xor), |
| 266 | .struct_init_empty => try sema.zirStructInitEmpty(block, inst), | 266 | .struct_init_empty => try sema.zirStructInitEmpty(block, inst), |
| 267 | .struct_init => try sema.zirStructInit(block, inst), | ||
| 268 | .field_type => try sema.zirFieldType(block, inst), | ||
| 267 | 269 | ||
| 268 | .struct_decl => try sema.zirStructDecl(block, inst, .Auto), | 270 | .struct_decl => try sema.zirStructDecl(block, inst, .Auto), |
| 269 | .struct_decl_packed => try sema.zirStructDecl(block, inst, .Packed), | 271 | .struct_decl_packed => try sema.zirStructDecl(block, inst, .Packed), |
| ... | @@ -4493,6 +4495,18 @@ fn zirStructInitEmpty(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In | ... | @@ -4493,6 +4495,18 @@ fn zirStructInitEmpty(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In |
| 4493 | }); | 4495 | }); |
| 4494 | } | 4496 | } |
| 4495 | 4497 | ||
| 4498 | fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | ||
| 4499 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | ||
| 4500 | const src = inst_data.src(); | ||
| 4501 | return sema.mod.fail(&block.base, src, "TODO: Sema.zirStructInit", .{}); | ||
| 4502 | } | ||
| 4503 | |||
| 4504 | fn zirFieldType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | ||
| 4505 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | ||
| 4506 | const src = inst_data.src(); | ||
| 4507 | return sema.mod.fail(&block.base, src, "TODO: Sema.zirFieldType", .{}); | ||
| 4508 | } | ||
| 4509 | |||
| 4496 | fn requireFunctionBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void { | 4510 | fn requireFunctionBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void { |
| 4497 | if (sema.func == null) { | 4511 | if (sema.func == null) { |
| 4498 | return sema.mod.fail(&block.base, src, "instruction illegal outside function body", .{}); | 4512 | return sema.mod.fail(&block.base, src, "instruction illegal outside function body", .{}); |
src/zir.zig+29| ... | @@ -674,6 +674,13 @@ pub const Inst = struct { | ... | @@ -674,6 +674,13 @@ pub const Inst = struct { |
| 674 | /// A struct literal with a specified type, with no fields. | 674 | /// A struct literal with a specified type, with no fields. |
| 675 | /// Uses the `un_node` field. | 675 | /// Uses the `un_node` field. |
| 676 | struct_init_empty, | 676 | struct_init_empty, |
| 677 | /// Given a struct, union, enum, or opaque and a field name, returns the field type. | ||
| 678 | /// Uses the `pl_node` field. Payload is `FieldType`. | ||
| 679 | field_type, | ||
| 680 | /// Finalizes a typed struct initialization, performs validation, and returns the | ||
| 681 | /// struct value. | ||
| 682 | /// Uses the `pl_node` field. Payload is `StructInit`. | ||
| 683 | struct_init, | ||
| 677 | /// Converts an integer into an enum value. | 684 | /// Converts an integer into an enum value. |
| 678 | /// Uses `pl_node` with payload `Bin`. `lhs` is enum type, `rhs` is operand. | 685 | /// Uses `pl_node` with payload `Bin`. `lhs` is enum type, `rhs` is operand. |
| 679 | int_to_enum, | 686 | int_to_enum, |
| ... | @@ -839,6 +846,8 @@ pub const Inst = struct { | ... | @@ -839,6 +846,8 @@ pub const Inst = struct { |
| 839 | .switch_block_ref_under_multi, | 846 | .switch_block_ref_under_multi, |
| 840 | .validate_struct_init_ptr, | 847 | .validate_struct_init_ptr, |
| 841 | .struct_init_empty, | 848 | .struct_init_empty, |
| 849 | .struct_init, | ||
| 850 | .field_type, | ||
| 842 | .int_to_enum, | 851 | .int_to_enum, |
| 843 | .enum_to_int, | 852 | .enum_to_int, |
| 844 | => false, | 853 | => false, |
| ... | @@ -1551,6 +1560,24 @@ pub const Inst = struct { | ... | @@ -1551,6 +1560,24 @@ pub const Inst = struct { |
| 1551 | return @bitCast(f128, int_bits); | 1560 | return @bitCast(f128, int_bits); |
| 1552 | } | 1561 | } |
| 1553 | }; | 1562 | }; |
| 1563 | |||
| 1564 | /// Trailing is an item per field. | ||
| 1565 | pub const StructInit = struct { | ||
| 1566 | fields_len: u32, | ||
| 1567 | |||
| 1568 | pub const Item = struct { | ||
| 1569 | /// The `field_type` ZIR instruction for this field init. | ||
| 1570 | field_type: Index, | ||
| 1571 | /// The field init expression to be used as the field value. | ||
| 1572 | init: Ref, | ||
| 1573 | }; | ||
| 1574 | }; | ||
| 1575 | |||
| 1576 | pub const FieldType = struct { | ||
| 1577 | container_type: Ref, | ||
| 1578 | /// Offset into `string_bytes`, null terminated. | ||
| 1579 | name_start: u32, | ||
| 1580 | }; | ||
| 1554 | }; | 1581 | }; |
| 1555 | 1582 | ||
| 1556 | pub const SpecialProng = enum { none, @"else", under }; | 1583 | pub const SpecialProng = enum { none, @"else", under }; |
| ... | @@ -1665,6 +1692,8 @@ const Writer = struct { | ... | @@ -1665,6 +1692,8 @@ const Writer = struct { |
| 1665 | .union_decl, | 1692 | .union_decl, |
| 1666 | .enum_decl, | 1693 | .enum_decl, |
| 1667 | .enum_decl_nonexhaustive, | 1694 | .enum_decl_nonexhaustive, |
| 1695 | .struct_init, | ||
| 1696 | .field_type, | ||
| 1668 | => try self.writePlNode(stream, inst), | 1697 | => try self.writePlNode(stream, inst), |
| 1669 | 1698 | ||
| 1670 | .add, | 1699 | .add, |