| ... | @@ -383,10 +383,12 @@ const DocData = struct { | ... | @@ -383,10 +383,12 @@ 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: ?usize = null, |
| 386 | }, | 387 | }, |
| 387 | Array: struct { | 388 | Array: struct { |
| 388 | len: Expr, | 389 | len: Expr, |
| 389 | child: Expr, | 390 | child: Expr, |
| | 391 | sentinel: ?usize = null, |
| 390 | }, | 392 | }, |
| 391 | Struct: struct { | 393 | Struct: struct { |
| 392 | name: []const u8, | 394 | name: []const u8, |
| ... | @@ -478,6 +480,11 @@ const DocData = struct { | ... | @@ -478,6 +480,11 @@ const DocData = struct { |
| 478 | \\ | 480 | \\ |
| 479 | , .{@enumToInt(v.size)}); | 481 | , .{@enumToInt(v.size)}); |
| 480 | if (options.whitespace) |ws| try ws.outputIndent(w); | 482 | if (options.whitespace) |ws| try ws.outputIndent(w); |
| | 483 | try w.print( |
| | 484 | \\"sentinel": {}, |
| | 485 | \\ |
| | 486 | , .{v.sentinel}); |
| | 487 | if (options.whitespace) |ws| try ws.outputIndent(w); |
| 481 | try w.print( | 488 | try w.print( |
| 482 | \\"child": | 489 | \\"child": |
| 483 | , .{}); | 490 | , .{}); |
| ... | @@ -754,11 +761,13 @@ fn walkInstruction( | ... | @@ -754,11 +761,13 @@ fn walkInstruction( |
| 754 | .child = .{ .type = @enumToInt(Ref.u8_type) }, | 761 | .child = .{ .type = @enumToInt(Ref.u8_type) }, |
| 755 | }, | 762 | }, |
| 756 | }); | 763 | }); |
| | 764 | // const sentinel: ?usize = if (ptr.flags.has_sentinel) 0 else null; |
| 757 | const ptrTypeId = self.types.items.len; | 765 | const ptrTypeId = self.types.items.len; |
| 758 | try self.types.append(self.arena, .{ | 766 | try self.types.append(self.arena, .{ |
| 759 | .Pointer = .{ | 767 | .Pointer = .{ |
| 760 | .size = .One, | 768 | .size = .One, |
| 761 | .child = .{ .type = arrTypeId }, | 769 | .child = .{ .type = arrTypeId }, |
| | 770 | .sentinel = 0, |
| 762 | // TODO: add sentinel! | 771 | // TODO: add sentinel! |
| 763 | }, | 772 | }, |
| 764 | }); | 773 | }); |
| ... | @@ -806,6 +815,24 @@ fn walkInstruction( | ... | @@ -806,6 +815,24 @@ fn walkInstruction( |
| 806 | // TODO: return the actual error union instread of cheating | 815 | // TODO: return the actual error union instread of cheating |
| 807 | return self.walkRef(file, parent_scope, extra.data.rhs, need_type); | 816 | return self.walkRef(file, parent_scope, extra.data.rhs, need_type); |
| 808 | }, | 817 | }, |
| | 818 | .elem_type => { |
| | 819 | const un_node = data[inst_index].un_node; |
| | 820 | std.debug.print("un_node: {}\n", .{un_node}); |
| | 821 | |
| | 822 | var operand: DocData.WalkResult = try self.walkRef( |
| | 823 | file, |
| | 824 | parent_scope, |
| | 825 | un_node.operand, |
| | 826 | false, |
| | 827 | ); |
| | 828 | |
| | 829 | std.debug.print("operand: {}\n", .{operand}); |
| | 830 | |
| | 831 | return DocData.WalkResult{ |
| | 832 | .typeRef = .{ .type = operand.typeRef.?.type }, |
| | 833 | .expr = .{ .type = operand.expr.type }, |
| | 834 | }; |
| | 835 | }, |
| 809 | .ptr_type_simple => { | 836 | .ptr_type_simple => { |
| 810 | const ptr = data[inst_index].ptr_type_simple; | 837 | const ptr = data[inst_index].ptr_type_simple; |
| 811 | const type_slot_index = self.types.items.len; | 838 | const type_slot_index = self.types.items.len; |
| ... | @@ -826,6 +853,14 @@ fn walkInstruction( | ... | @@ -826,6 +853,14 @@ fn walkInstruction( |
| 826 | const ptr = data[inst_index].ptr_type; | 853 | const ptr = data[inst_index].ptr_type; |
| 827 | const extra = file.zir.extraData(Zir.Inst.PtrType, ptr.payload_index); | 854 | const extra = file.zir.extraData(Zir.Inst.PtrType, ptr.payload_index); |
| 828 | | 855 | |
| | 856 | std.debug.print("ptr = {}\n", .{ptr}); |
| | 857 | std.debug.print("extra = {any}\n", .{extra}); |
| | 858 | |
| | 859 | const sentinel: ?usize = if (ptr.flags.has_sentinel) 0 else null; |
| | 860 | |
| | 861 | std.debug.print("sentinel = {} {d}\n", .{ ptr.flags.has_sentinel, sentinel }); |
| | 862 | std.debug.print("type = {d}\n", .{@enumToInt(Ref.type_type)}); |
| | 863 | |
| 829 | const type_slot_index = self.types.items.len; | 864 | const type_slot_index = self.types.items.len; |
| 830 | const elem_type_ref = try self.walkRef( | 865 | const elem_type_ref = try self.walkRef( |
| 831 | file, | 866 | file, |
| ... | @@ -837,9 +872,12 @@ fn walkInstruction( | ... | @@ -837,9 +872,12 @@ fn walkInstruction( |
| 837 | .Pointer = .{ | 872 | .Pointer = .{ |
| 838 | .size = ptr.size, | 873 | .size = ptr.size, |
| 839 | .child = elem_type_ref.expr, | 874 | .child = elem_type_ref.expr, |
| | 875 | .sentinel = sentinel, |
| 840 | }, | 876 | }, |
| 841 | }); | 877 | }); |
| | 878 | std.debug.print("type = {d}\n", .{type_slot_index}); |
| 842 | return DocData.WalkResult{ | 879 | return DocData.WalkResult{ |
| | 880 | // .typeRef = .{ .type = type_slot_index }, |
| 843 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, | 881 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, |
| 844 | .expr = .{ .type = type_slot_index }, | 882 | .expr = .{ .type = type_slot_index }, |
| 845 | }; | 883 | }; |
| ... | @@ -849,6 +887,11 @@ fn walkInstruction( | ... | @@ -849,6 +887,11 @@ fn walkInstruction( |
| 849 | const len = try self.walkRef(file, parent_scope, bin.lhs, false); | 887 | const len = try self.walkRef(file, parent_scope, bin.lhs, false); |
| 850 | const child = try self.walkRef(file, parent_scope, bin.rhs, false); | 888 | const child = try self.walkRef(file, parent_scope, bin.rhs, false); |
| 851 | | 889 | |
| | 890 | std.debug.print("AEHO\n", .{}); |
| | 891 | // std.debug.print("bin = {}\n", .{bin}); |
| | 892 | // std.debug.print("len = {}\n", .{len}); |
| | 893 | // std.debug.print("child = {}\n", .{child}); |
| | 894 | |
| 852 | const type_slot_index = self.types.items.len; | 895 | const type_slot_index = self.types.items.len; |
| 853 | try self.types.append(self.arena, .{ | 896 | try self.types.append(self.arena, .{ |
| 854 | .Array = .{ | 897 | .Array = .{ |
| ... | @@ -861,6 +904,26 @@ fn walkInstruction( | ... | @@ -861,6 +904,26 @@ fn walkInstruction( |
| 861 | .expr = .{ .type = type_slot_index }, | 904 | .expr = .{ .type = type_slot_index }, |
| 862 | }; | 905 | }; |
| 863 | }, | 906 | }, |
| | 907 | .array_type_sentinel => { |
| | 908 | const pl_node = data[inst_index].pl_node; |
| | 909 | const extra = file.zir.extraData(Zir.Inst.ArrayTypeSentinel, pl_node.payload_index); |
| | 910 | const len = try self.walkRef(file, parent_scope, extra.data.len, false); |
| | 911 | const sentinel = try self.walkRef(file, parent_scope, extra.data.sentinel, false); |
| | 912 | const elem_type = try self.walkRef(file, parent_scope, extra.data.elem_type, false); |
| | 913 | |
| | 914 | const type_slot_index = self.types.items.len; |
| | 915 | try self.types.append(self.arena, .{ |
| | 916 | .Array = .{ |
| | 917 | .len = len.expr, |
| | 918 | .child = elem_type.expr, |
| | 919 | .sentinel = sentinel.expr.int.value, |
| | 920 | }, |
| | 921 | }); |
| | 922 | return DocData.WalkResult{ |
| | 923 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, |
| | 924 | .expr = .{ .type = type_slot_index }, |
| | 925 | }; |
| | 926 | }, |
| 864 | .array_init => { | 927 | .array_init => { |
| 865 | const pl_node = data[inst_index].pl_node; | 928 | const pl_node = data[inst_index].pl_node; |
| 866 | const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index); | 929 | const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index); |
| ... | @@ -875,6 +938,7 @@ fn walkInstruction( | ... | @@ -875,6 +938,7 @@ fn walkInstruction( |
| 875 | // we only ask to figure out type info for the first element | 938 | // we only ask to figure out type info for the first element |
| 876 | // as it will be used later on to find out the array type! | 939 | // as it will be used later on to find out the array type! |
| 877 | const wr = try self.walkRef(file, parent_scope, op, idx == 0); | 940 | const wr = try self.walkRef(file, parent_scope, op, idx == 0); |
| | 941 | std.debug.print("wr: {any}\n", .{wr}); |
| 878 | | 942 | |
| 879 | if (idx == 0) { | 943 | if (idx == 0) { |
| 880 | array_type = wr.typeRef; | 944 | array_type = wr.typeRef; |
| ... | @@ -886,6 +950,102 @@ fn walkInstruction( | ... | @@ -886,6 +950,102 @@ fn walkInstruction( |
| 886 | array_data[idx] = wr.expr.as.exprArg; | 950 | array_data[idx] = wr.expr.as.exprArg; |
| 887 | } | 951 | } |
| 888 | | 952 | |
| | 953 | const type_slot_index = self.types.items.len; |
| | 954 | try self.types.append(self.arena, .{ |
| | 955 | .Array = .{ .len = .{ |
| | 956 | .int = .{ |
| | 957 | .value = operands.len, |
| | 958 | .negated = false, |
| | 959 | }, |
| | 960 | }, .child = array_type.? }, |
| | 961 | }); |
| | 962 | |
| | 963 | return DocData.WalkResult{ |
| | 964 | .typeRef = .{ .type = type_slot_index }, |
| | 965 | .expr = .{ .array = array_data }, |
| | 966 | }; |
| | 967 | }, |
| | 968 | .array_init_sent => { |
| | 969 | const pl_node = data[inst_index].pl_node; |
| | 970 | const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index); |
| | 971 | const operands = file.zir.refSlice(extra.end, extra.data.operands_len - 1); |
| | 972 | const array_data = try self.arena.alloc(usize, operands.len); |
| | 973 | |
| | 974 | // TODO: make sure that you want the array to be fully normalized for real |
| | 975 | // then update this code to conform to your choice. |
| | 976 | |
| | 977 | var array_type: ?DocData.Expr = null; |
| | 978 | for (operands) |op, idx| { |
| | 979 | // we only ask to figure out type info for the first element |
| | 980 | // as it will be used later on to find out the array type! |
| | 981 | const wr = try self.walkRef(file, parent_scope, op, idx == 0); |
| | 982 | std.debug.print("wr: {any}\n", .{wr}); |
| | 983 | if (idx == 0) { |
| | 984 | array_type = wr.typeRef; |
| | 985 | } |
| | 986 | |
| | 987 | // We know that Zir wraps every operand in an @as expression |
| | 988 | // so we want to peel it away and only save the target type |
| | 989 | // once, since we need it later to define the array type. |
| | 990 | array_data[idx] = wr.expr.as.exprArg; |
| | 991 | } |
| | 992 | |
| | 993 | // std.debug.print("array: {any}\n", .{array_data}); |
| | 994 | |
| | 995 | const type_slot_index = self.types.items.len; |
| | 996 | try self.types.append(self.arena, .{ |
| | 997 | .Array = .{ .len = .{ |
| | 998 | .int = .{ |
| | 999 | .value = operands.len, |
| | 1000 | .negated = false, |
| | 1001 | }, |
| | 1002 | }, .child = array_type.?, .sentinel = 0 }, |
| | 1003 | }); |
| | 1004 | |
| | 1005 | return DocData.WalkResult{ |
| | 1006 | .typeRef = .{ .type = type_slot_index }, |
| | 1007 | .expr = .{ .array = array_data }, |
| | 1008 | }; |
| | 1009 | }, |
| | 1010 | .array_init_anon => { |
| | 1011 | const pl_node = data[inst_index].pl_node; |
| | 1012 | const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index); |
| | 1013 | const operands = file.zir.refSlice(extra.end, extra.data.operands_len); |
| | 1014 | const array_data = try self.arena.alloc(usize, operands.len); |
| | 1015 | |
| | 1016 | // TODO: make sure that you want the array to be fully normalized for real |
| | 1017 | // then update this code to conform to your choice. |
| | 1018 | |
| | 1019 | // std.debug.print("extra: {}\n", .{extra}); |
| | 1020 | // std.debug.print("operands: {any}\n", .{operands}); |
| | 1021 | |
| | 1022 | var array_type: ?DocData.Expr = null; |
| | 1023 | for (operands) |op, idx| { |
| | 1024 | // we only ask to figure out type info for the first element |
| | 1025 | // as it will be used later on to find out the array type! |
| | 1026 | const wr = try self.walkRef(file, parent_scope, op, idx == 0); |
| | 1027 | // std.debug.print("wr: {any}\n", .{wr}); |
| | 1028 | |
| | 1029 | if (idx == 0) { |
| | 1030 | array_type = wr.typeRef; |
| | 1031 | } |
| | 1032 | // std.debug.print("type: {}\n", .{@intToEnum(Ref, wr.typeRef.?.type)}); |
| | 1033 | |
| | 1034 | // create an untion to hold more than one type |
| | 1035 | switch (@intToEnum(Ref, wr.typeRef.?.type)) { |
| | 1036 | .comptime_int_type => { |
| | 1037 | array_data[idx] = wr.expr.int.value; |
| | 1038 | }, |
| | 1039 | .comptime_float_type => { |
| | 1040 | unreachable; |
| | 1041 | // array_data[idx] = wr.expr.float; |
| | 1042 | }, |
| | 1043 | else => continue, |
| | 1044 | } |
| | 1045 | } |
| | 1046 | |
| | 1047 | // std.debug.print("array: {any}\n", .{array_data}); |
| | 1048 | |
| 889 | const type_slot_index = self.types.items.len; | 1049 | const type_slot_index = self.types.items.len; |
| 890 | try self.types.append(self.arena, .{ | 1050 | try self.types.append(self.arena, .{ |
| 891 | .Array = .{ | 1051 | .Array = .{ |
| ... | @@ -904,6 +1064,20 @@ fn walkInstruction( | ... | @@ -904,6 +1064,20 @@ fn walkInstruction( |
| 904 | .expr = .{ .array = array_data }, | 1064 | .expr = .{ .array = array_data }, |
| 905 | }; | 1065 | }; |
| 906 | }, | 1066 | }, |
| | 1067 | // .validate_array_init_ty => { |
| | 1068 | // const un_node = data[inst_index].un_node; |
| | 1069 | // var operand: DocData.WalkResult = try self.walkRef( |
| | 1070 | // file, |
| | 1071 | // parent_scope, |
| | 1072 | // un_node.operand, |
| | 1073 | // need_type, |
| | 1074 | // ); |
| | 1075 | // |
| | 1076 | // std.debug.print("validate _ array => {}\n", .{un_node}); |
| | 1077 | // std.debug.print("operand = {}\n", .{operand}); |
| | 1078 | // |
| | 1079 | // return operand; |
| | 1080 | // }, |
| 907 | .float => { | 1081 | .float => { |
| 908 | const float = data[inst_index].float; | 1082 | const float = data[inst_index].float; |
| 909 | return DocData.WalkResult{ | 1083 | return DocData.WalkResult{ |