| ... | @@ -383,13 +383,13 @@ const DocData = struct { | ... | @@ -383,13 +383,13 @@ const DocData = struct { |
| 383 | Pointer: struct { | 383 | Pointer: struct { |
| 384 | size: std.builtin.TypeInfo.Pointer.Size, | 384 | size: std.builtin.TypeInfo.Pointer.Size, |
| 385 | child: Expr, | 385 | child: Expr, |
| 386 | sentinel: bool = false, | 386 | sentinel: ?Expr = null, |
| 387 | is_mutable: bool = true, | 387 | is_mutable: bool = true, |
| 388 | }, | 388 | }, |
| 389 | Array: struct { | 389 | Array: struct { |
| 390 | len: Expr, | 390 | len: Expr, |
| 391 | child: Expr, | 391 | child: Expr, |
| 392 | sentinel: bool = false, | 392 | sentinel: ?Expr = null, |
| 393 | }, | 393 | }, |
| 394 | Struct: struct { | 394 | Struct: struct { |
| 395 | name: []const u8, | 395 | name: []const u8, |
| ... | @@ -482,11 +482,14 @@ const DocData = struct { | ... | @@ -482,11 +482,14 @@ const DocData = struct { |
| 482 | \\ | 482 | \\ |
| 483 | , .{@enumToInt(v.size)}); | 483 | , .{@enumToInt(v.size)}); |
| 484 | if (options.whitespace) |ws| try ws.outputIndent(w); | 484 | if (options.whitespace) |ws| try ws.outputIndent(w); |
| 485 | try w.print( | 485 | if (v.sentinel) |sentinel| { |
| 486 | \\"sentinel": {}, | 486 | try w.print( |
| 487 | \\ | 487 | \\"sentinel": |
| 488 | , .{v.sentinel}); | 488 | , .{}); |
| 489 | if (options.whitespace) |ws| try ws.outputIndent(w); | 489 | if (options.whitespace) |*ws| ws.indent_level += 1; |
| | 490 | try sentinel.jsonStringify(options, w); |
| | 491 | try w.print(",", .{}); |
| | 492 | } |
| 490 | try w.print( | 493 | try w.print( |
| 491 | \\"is_mutable": {}, | 494 | \\"is_mutable": {}, |
| 492 | \\ | 495 | \\ |
| ... | @@ -766,7 +769,10 @@ fn walkInstruction( | ... | @@ -766,7 +769,10 @@ fn walkInstruction( |
| 766 | .Array = .{ | 769 | .Array = .{ |
| 767 | .len = .{ .int = .{ .value = str.len } }, | 770 | .len = .{ .int = .{ .value = str.len } }, |
| 768 | .child = .{ .type = @enumToInt(Ref.u8_type) }, | 771 | .child = .{ .type = @enumToInt(Ref.u8_type) }, |
| 769 | .sentinel = true, | 772 | .sentinel = .{ .int = .{ |
| | 773 | .value = 0, |
| | 774 | .negated = false, |
| | 775 | } }, |
| 770 | }, | 776 | }, |
| 771 | }); | 777 | }); |
| 772 | // const sentinel: ?usize = if (ptr.flags.has_sentinel) 0 else null; | 778 | // const sentinel: ?usize = if (ptr.flags.has_sentinel) 0 else null; |
| ... | @@ -775,7 +781,10 @@ fn walkInstruction( | ... | @@ -775,7 +781,10 @@ fn walkInstruction( |
| 775 | .Pointer = .{ | 781 | .Pointer = .{ |
| 776 | .size = .One, | 782 | .size = .One, |
| 777 | .child = .{ .type = arrTypeId }, | 783 | .child = .{ .type = arrTypeId }, |
| 778 | .sentinel = true, | 784 | .sentinel = .{ .int = .{ |
| | 785 | .value = 0, |
| | 786 | .negated = false, |
| | 787 | } }, |
| 779 | .is_mutable = false, | 788 | .is_mutable = false, |
| 780 | }, | 789 | }, |
| 781 | }); | 790 | }); |
| ... | @@ -842,10 +851,7 @@ fn walkInstruction( | ... | @@ -842,10 +851,7 @@ fn walkInstruction( |
| 842 | false, | 851 | false, |
| 843 | ); | 852 | ); |
| 844 | | 853 | |
| 845 | return DocData.WalkResult{ | 854 | return operand; |
| 846 | .typeRef = .{ .type = operand.typeRef.?.type }, | | |
| 847 | .expr = .{ .type = operand.expr.type }, | | |
| 848 | }; | | |
| 849 | }, | 855 | }, |
| 850 | .ptr_type_simple => { | 856 | .ptr_type_simple => { |
| 851 | const ptr = data[inst_index].ptr_type_simple; | 857 | const ptr = data[inst_index].ptr_type_simple; |
| ... | @@ -868,8 +874,6 @@ fn walkInstruction( | ... | @@ -868,8 +874,6 @@ fn walkInstruction( |
| 868 | const ptr = data[inst_index].ptr_type; | 874 | const ptr = data[inst_index].ptr_type; |
| 869 | const extra = file.zir.extraData(Zir.Inst.PtrType, ptr.payload_index); | 875 | const extra = file.zir.extraData(Zir.Inst.PtrType, ptr.payload_index); |
| 870 | | 876 | |
| 871 | const sentinel: bool = if (ptr.flags.has_sentinel) true else false; | | |
| 872 | | | |
| 873 | const type_slot_index = self.types.items.len; | 877 | const type_slot_index = self.types.items.len; |
| 874 | const elem_type_ref = try self.walkRef( | 878 | const elem_type_ref = try self.walkRef( |
| 875 | file, | 879 | file, |
| ... | @@ -877,8 +881,9 @@ fn walkInstruction( | ... | @@ -877,8 +881,9 @@ fn walkInstruction( |
| 877 | extra.data.elem_type, | 881 | extra.data.elem_type, |
| 878 | false, | 882 | false, |
| 879 | ); | 883 | ); |
| | 884 | |
| 880 | try self.types.append(self.arena, .{ | 885 | try self.types.append(self.arena, .{ |
| 881 | .Pointer = .{ .size = ptr.size, .child = elem_type_ref.expr, .sentinel = sentinel, .is_mutable = ptr.flags.is_mutable }, | 886 | .Pointer = .{ .size = ptr.size, .child = elem_type_ref.expr, .sentinel = .{ .int = .{ .value = 0, .negated = false } }, .is_mutable = ptr.flags.is_mutable }, |
| 882 | }); | 887 | }); |
| 883 | return DocData.WalkResult{ | 888 | return DocData.WalkResult{ |
| 884 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, | 889 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, |
| ... | @@ -907,7 +912,7 @@ fn walkInstruction( | ... | @@ -907,7 +912,7 @@ fn walkInstruction( |
| 907 | const pl_node = data[inst_index].pl_node; | 912 | const pl_node = data[inst_index].pl_node; |
| 908 | const extra = file.zir.extraData(Zir.Inst.ArrayTypeSentinel, pl_node.payload_index); | 913 | const extra = file.zir.extraData(Zir.Inst.ArrayTypeSentinel, pl_node.payload_index); |
| 909 | const len = try self.walkRef(file, parent_scope, extra.data.len, false); | 914 | const len = try self.walkRef(file, parent_scope, extra.data.len, false); |
| 910 | // const sentinel = try self.walkRef(file, parent_scope, extra.data.sentinel, false); | 915 | const sentinel = try self.walkRef(file, parent_scope, extra.data.sentinel, false); |
| 911 | const elem_type = try self.walkRef(file, parent_scope, extra.data.elem_type, false); | 916 | const elem_type = try self.walkRef(file, parent_scope, extra.data.elem_type, false); |
| 912 | | 917 | |
| 913 | const type_slot_index = self.types.items.len; | 918 | const type_slot_index = self.types.items.len; |
| ... | @@ -915,7 +920,7 @@ fn walkInstruction( | ... | @@ -915,7 +920,7 @@ fn walkInstruction( |
| 915 | .Array = .{ | 920 | .Array = .{ |
| 916 | .len = len.expr, | 921 | .len = len.expr, |
| 917 | .child = elem_type.expr, | 922 | .child = elem_type.expr, |
| 918 | .sentinel = true, | 923 | .sentinel = sentinel.expr, |
| 919 | }, | 924 | }, |
| 920 | }); | 925 | }); |
| 921 | return DocData.WalkResult{ | 926 | return DocData.WalkResult{ |
| ... | @@ -966,12 +971,12 @@ fn walkInstruction( | ... | @@ -966,12 +971,12 @@ fn walkInstruction( |
| 966 | .array_init_sent => { | 971 | .array_init_sent => { |
| 967 | const pl_node = data[inst_index].pl_node; | 972 | const pl_node = data[inst_index].pl_node; |
| 968 | const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index); | 973 | const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index); |
| 969 | const operands = file.zir.refSlice(extra.end, extra.data.operands_len - 1); | 974 | const operands = file.zir.refSlice(extra.end, extra.data.operands_len); |
| 970 | const array_data = try self.arena.alloc(usize, operands.len); | 975 | const array_data = try self.arena.alloc(usize, operands.len - 1); |
| 971 | | 976 | |
| 972 | // TODO: make sure that you want the array to be fully normalized for real | 977 | // TODO: make sure that you want the array to be fully normalized for real |
| 973 | // then update this code to conform to your choice. | 978 | // then update this code to conform to your choice. |
| 974 | | 979 | var sentinel: ?DocData.Expr = null; |
| 975 | var array_type: ?DocData.Expr = null; | 980 | var array_type: ?DocData.Expr = null; |
| 976 | for (operands) |op, idx| { | 981 | for (operands) |op, idx| { |
| 977 | // we only ask to figure out type info for the first element | 982 | // we only ask to figure out type info for the first element |
| ... | @@ -981,20 +986,21 @@ fn walkInstruction( | ... | @@ -981,20 +986,21 @@ fn walkInstruction( |
| 981 | array_type = wr.typeRef; | 986 | array_type = wr.typeRef; |
| 982 | } | 987 | } |
| 983 | | 988 | |
| 984 | // We know that Zir wraps every operand in an @as expression | 989 | if (idx == extra.data.operands_len - 1) { |
| 985 | // so we want to peel it away and only save the target type | 990 | sentinel = self.exprs.items[wr.expr.as.exprArg]; |
| 986 | // once, since we need it later to define the array type. | 991 | } else { |
| 987 | array_data[idx] = wr.expr.as.exprArg; | 992 | array_data[idx] = wr.expr.as.exprArg; |
| | 993 | } |
| 988 | } | 994 | } |
| 989 | | 995 | |
| 990 | const type_slot_index = self.types.items.len; | 996 | const type_slot_index = self.types.items.len; |
| 991 | try self.types.append(self.arena, .{ | 997 | try self.types.append(self.arena, .{ |
| 992 | .Array = .{ .len = .{ | 998 | .Array = .{ .len = .{ |
| 993 | .int = .{ | 999 | .int = .{ |
| 994 | .value = operands.len, | 1000 | .value = operands.len - 1, |
| 995 | .negated = false, | 1001 | .negated = false, |
| 996 | }, | 1002 | }, |
| 997 | }, .child = array_type.?, .sentinel = true }, | 1003 | }, .child = array_type.?, .sentinel = sentinel }, |
| 998 | }); | 1004 | }); |
| 999 | | 1005 | |
| 1000 | return DocData.WalkResult{ | 1006 | return DocData.WalkResult{ |
| ... | @@ -1084,28 +1090,36 @@ fn walkInstruction( | ... | @@ -1084,28 +1090,36 @@ fn walkInstruction( |
| 1084 | .array_init_sent_ref => { | 1090 | .array_init_sent_ref => { |
| 1085 | const pl_node = data[inst_index].pl_node; | 1091 | const pl_node = data[inst_index].pl_node; |
| 1086 | const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index); | 1092 | const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index); |
| 1087 | // the sentinel terminator are calculated at compile time | 1093 | const operands = file.zir.refSlice(extra.end, extra.data.operands_len); |
| 1088 | // (extra.data.operands_len - 1) is to not account for that | 1094 | const array_data = try self.arena.alloc(usize, operands.len - 1); |
| 1089 | const operands = file.zir.refSlice(extra.end, extra.data.operands_len - 1); | 1095 | |
| 1090 | const array_data = try self.arena.alloc(usize, operands.len); | 1096 | // TODO: This should output: |
| | 1097 | // const array: *[value:sentinel]type = &.{}; |
| | 1098 | // but right now it's printing: |
| | 1099 | // const array: [value:sentinel]u8 = .{}; |
| 1091 | | 1100 | |
| | 1101 | var sentinel: ?DocData.Expr = null; |
| 1092 | var array_type: ?DocData.Expr = null; | 1102 | var array_type: ?DocData.Expr = null; |
| 1093 | for (operands) |op, idx| { | 1103 | for (operands) |op, idx| { |
| 1094 | const wr = try self.walkRef(file, parent_scope, op, idx == 0); | 1104 | const wr = try self.walkRef(file, parent_scope, op, idx == 0); |
| 1095 | if (idx == 0) { | 1105 | if (idx == 0) { |
| 1096 | array_type = wr.typeRef; | 1106 | array_type = wr.typeRef; |
| 1097 | } | 1107 | } |
| 1098 | array_data[idx] = wr.expr.as.exprArg; | 1108 | if (idx == extra.data.operands_len - 1) { |
| | 1109 | sentinel = self.exprs.items[wr.expr.as.exprArg]; |
| | 1110 | } else { |
| | 1111 | array_data[idx] = wr.expr.as.exprArg; |
| | 1112 | } |
| 1099 | } | 1113 | } |
| 1100 | | 1114 | |
| 1101 | const type_slot_index = self.types.items.len; | 1115 | const type_slot_index = self.types.items.len; |
| 1102 | try self.types.append(self.arena, .{ | 1116 | try self.types.append(self.arena, .{ |
| 1103 | .Array = .{ .len = .{ | 1117 | .Array = .{ .len = .{ |
| 1104 | .int = .{ | 1118 | .int = .{ |
| 1105 | .value = operands.len, | 1119 | .value = operands.len - 1, |
| 1106 | .negated = false, | 1120 | .negated = false, |
| 1107 | }, | 1121 | }, |
| 1108 | }, .child = array_type.?, .sentinel = true }, | 1122 | }, .child = array_type.?, .sentinel = sentinel }, |
| 1109 | }); | 1123 | }); |
| 1110 | | 1124 | |
| 1111 | return DocData.WalkResult{ | 1125 | return DocData.WalkResult{ |
| ... | @@ -1117,7 +1131,9 @@ fn walkInstruction( | ... | @@ -1117,7 +1131,9 @@ fn walkInstruction( |
| 1117 | const pl_node = data[inst_index].pl_node; | 1131 | const pl_node = data[inst_index].pl_node; |
| 1118 | const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index); | 1132 | const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index); |
| 1119 | const operands = file.zir.refSlice(extra.end, extra.data.operands_len); | 1133 | const operands = file.zir.refSlice(extra.end, extra.data.operands_len); |
| 1120 | const array_data = try self.arena.alloc(usize, operands.len); | 1134 | const array_data = try self.arena.alloc(usize, operands.len - 1); |
| | 1135 | |
| | 1136 | var sentinel: ?DocData.Expr = null; |
| 1121 | | 1137 | |
| 1122 | var array_type: ?DocData.Expr = null; | 1138 | var array_type: ?DocData.Expr = null; |
| 1123 | for (operands) |op, idx| { | 1139 | for (operands) |op, idx| { |
| ... | @@ -1125,17 +1141,23 @@ fn walkInstruction( | ... | @@ -1125,17 +1141,23 @@ fn walkInstruction( |
| 1125 | if (idx == 0) { | 1141 | if (idx == 0) { |
| 1126 | array_type = wr.typeRef; | 1142 | array_type = wr.typeRef; |
| 1127 | } | 1143 | } |
| 1128 | array_data[idx] = wr.expr.int.value; | 1144 | |
| | 1145 | if (idx == extra.data.operands_len - 1) { |
| | 1146 | sentinel = wr.expr; |
| | 1147 | const expr_index = self.exprs.items.len; |
| | 1148 | try self.exprs.append(self.arena, wr.expr); |
| | 1149 | array_data[idx] = expr_index; |
| | 1150 | } |
| 1129 | } | 1151 | } |
| 1130 | | 1152 | |
| 1131 | const type_slot_index = self.types.items.len; | 1153 | const type_slot_index = self.types.items.len; |
| 1132 | try self.types.append(self.arena, .{ | 1154 | try self.types.append(self.arena, .{ |
| 1133 | .Array = .{ .len = .{ | 1155 | .Array = .{ .len = .{ |
| 1134 | .int = .{ | 1156 | .int = .{ |
| 1135 | .value = operands.len, | 1157 | .value = operands.len - 1, |
| 1136 | .negated = false, | 1158 | .negated = false, |
| 1137 | }, | 1159 | }, |
| 1138 | }, .child = array_type.? }, | 1160 | }, .child = array_type.?, .sentinel = sentinel }, |
| 1139 | }); | 1161 | }); |
| 1140 | | 1162 | |
| 1141 | return DocData.WalkResult{ | 1163 | return DocData.WalkResult{ |