| ... | ... | @@ -383,10 +383,12 @@ const DocData = struct { |
| 383 | 383 | Pointer: struct { |
| 384 | 384 | size: std.builtin.TypeInfo.Pointer.Size, |
| 385 | 385 | child: Expr, |
| 386 | sentinel: ?usize = null, |
| 386 | 387 | }, |
| 387 | 388 | Array: struct { |
| 388 | 389 | len: Expr, |
| 389 | 390 | child: Expr, |
| 391 | sentinel: ?usize = null, |
| 390 | 392 | }, |
| 391 | 393 | Struct: struct { |
| 392 | 394 | name: []const u8, |
| ... | ... | @@ -478,6 +480,11 @@ const DocData = struct { |
| 478 | 480 | \\ |
| 479 | 481 | , .{@enumToInt(v.size)}); |
| 480 | 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 | 488 | try w.print( |
| 482 | 489 | \\"child": |
| 483 | 490 | , .{}); |
| ... | ... | @@ -754,11 +761,13 @@ fn walkInstruction( |
| 754 | 761 | .child = .{ .type = @enumToInt(Ref.u8_type) }, |
| 755 | 762 | }, |
| 756 | 763 | }); |
| 764 | // const sentinel: ?usize = if (ptr.flags.has_sentinel) 0 else null; |
| 757 | 765 | const ptrTypeId = self.types.items.len; |
| 758 | 766 | try self.types.append(self.arena, .{ |
| 759 | 767 | .Pointer = .{ |
| 760 | 768 | .size = .One, |
| 761 | 769 | .child = .{ .type = arrTypeId }, |
| 770 | .sentinel = 0, |
| 762 | 771 | // TODO: add sentinel! |
| 763 | 772 | }, |
| 764 | 773 | }); |
| ... | ... | @@ -806,6 +815,24 @@ fn walkInstruction( |
| 806 | 815 | // TODO: return the actual error union instread of cheating |
| 807 | 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 | 836 | .ptr_type_simple => { |
| 810 | 837 | const ptr = data[inst_index].ptr_type_simple; |
| 811 | 838 | const type_slot_index = self.types.items.len; |
| ... | ... | @@ -826,6 +853,14 @@ fn walkInstruction( |
| 826 | 853 | const ptr = data[inst_index].ptr_type; |
| 827 | 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 | 864 | const type_slot_index = self.types.items.len; |
| 830 | 865 | const elem_type_ref = try self.walkRef( |
| 831 | 866 | file, |
| ... | ... | @@ -837,9 +872,12 @@ fn walkInstruction( |
| 837 | 872 | .Pointer = .{ |
| 838 | 873 | .size = ptr.size, |
| 839 | 874 | .child = elem_type_ref.expr, |
| 875 | .sentinel = sentinel, |
| 840 | 876 | }, |
| 841 | 877 | }); |
| 878 | std.debug.print("type = {d}\n", .{type_slot_index}); |
| 842 | 879 | return DocData.WalkResult{ |
| 880 | // .typeRef = .{ .type = type_slot_index }, |
| 843 | 881 | .typeRef = .{ .type = @enumToInt(Ref.type_type) }, |
| 844 | 882 | .expr = .{ .type = type_slot_index }, |
| 845 | 883 | }; |
| ... | ... | @@ -849,6 +887,11 @@ fn walkInstruction( |
| 849 | 887 | const len = try self.walkRef(file, parent_scope, bin.lhs, false); |
| 850 | 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 | 895 | const type_slot_index = self.types.items.len; |
| 853 | 896 | try self.types.append(self.arena, .{ |
| 854 | 897 | .Array = .{ |
| ... | ... | @@ -861,6 +904,26 @@ fn walkInstruction( |
| 861 | 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 | 927 | .array_init => { |
| 865 | 928 | const pl_node = data[inst_index].pl_node; |
| 866 | 929 | const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index); |
| ... | ... | @@ -875,6 +938,7 @@ fn walkInstruction( |
| 875 | 938 | // we only ask to figure out type info for the first element |
| 876 | 939 | // as it will be used later on to find out the array type! |
| 877 | 940 | const wr = try self.walkRef(file, parent_scope, op, idx == 0); |
| 941 | std.debug.print("wr: {any}\n", .{wr}); |
| 878 | 942 | |
| 879 | 943 | if (idx == 0) { |
| 880 | 944 | array_type = wr.typeRef; |
| ... | ... | @@ -886,6 +950,102 @@ fn walkInstruction( |
| 886 | 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 | 1049 | const type_slot_index = self.types.items.len; |
| 890 | 1050 | try self.types.append(self.arena, .{ |
| 891 | 1051 | .Array = .{ |
| ... | ... | @@ -904,6 +1064,20 @@ fn walkInstruction( |
| 904 | 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 | 1081 | .float => { |
| 908 | 1082 | const float = data[inst_index].float; |
| 909 | 1083 | return DocData.WalkResult{ |