| author | |
| committer | |
| log | ca6fb30e992fd86ee41a6510ef731e86f5de77c9 |
| tree | 72fc291a37d62fb3eee341ae1203c559968c0856 |
| parent | 6dcd8f4f75098c716ed617a388c96238c70aff17 |
| signature |
This commits adds the following distinct integer types to std.zig.Ast:
- OptionalTokenIndex
- TokenOffset
- OptionalTokenOffset
- Node.OptionalIndex
- Node.Offset
- Node.OptionalOffset
The `Node.Index` type has also been converted to a distinct type while
`TokenIndex` remains unchanged.
`Ast.Node.Data` has also been changed to a (untagged) union to provide
safety checks.25 files changed, 4559 insertions(+), 5056 deletions(-)
lib/compiler/aro_translate_c/ast.zig+383-440| ... | @@ -775,10 +775,7 @@ pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast { | ... | @@ -775,10 +775,7 @@ pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast { |
| 775 | ctx.nodes.appendAssumeCapacity(.{ | 775 | ctx.nodes.appendAssumeCapacity(.{ |
| 776 | .tag = .root, | 776 | .tag = .root, |
| 777 | .main_token = 0, | 777 | .main_token = 0, |
| 778 | .data = .{ | 778 | .data = undefined, |
| 779 | .lhs = undefined, | ||
| 780 | .rhs = undefined, | ||
| 781 | }, | ||
| 782 | }); | 779 | }); |
| 783 | 780 | ||
| 784 | const root_members = blk: { | 781 | const root_members = blk: { |
| ... | @@ -793,10 +790,7 @@ pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast { | ... | @@ -793,10 +790,7 @@ pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast { |
| 793 | break :blk try ctx.listToSpan(result.items); | 790 | break :blk try ctx.listToSpan(result.items); |
| 794 | }; | 791 | }; |
| 795 | 792 | ||
| 796 | ctx.nodes.items(.data)[0] = .{ | 793 | ctx.nodes.items(.data)[0] = .{ .extra_range = root_members }; |
| 797 | .lhs = root_members.start, | ||
| 798 | .rhs = root_members.end, | ||
| 799 | }; | ||
| 800 | 794 | ||
| 801 | try ctx.tokens.append(gpa, .{ | 795 | try ctx.tokens.append(gpa, .{ |
| 802 | .tag = .eof, | 796 | .tag = .eof, |
| ... | @@ -814,15 +808,18 @@ pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast { | ... | @@ -814,15 +808,18 @@ pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast { |
| 814 | } | 808 | } |
| 815 | 809 | ||
| 816 | const NodeIndex = std.zig.Ast.Node.Index; | 810 | const NodeIndex = std.zig.Ast.Node.Index; |
| 811 | const NodeOptionalIndex = std.zig.Ast.Node.OptionalIndex; | ||
| 817 | const NodeSubRange = std.zig.Ast.Node.SubRange; | 812 | const NodeSubRange = std.zig.Ast.Node.SubRange; |
| 818 | const TokenIndex = std.zig.Ast.TokenIndex; | 813 | const TokenIndex = std.zig.Ast.TokenIndex; |
| 814 | const TokenOptionalIndex = std.zig.Ast.OptionalTokenIndex; | ||
| 819 | const TokenTag = std.zig.Token.Tag; | 815 | const TokenTag = std.zig.Token.Tag; |
| 816 | const ExtraIndex = std.zig.Ast.ExtraIndex; | ||
| 820 | 817 | ||
| 821 | const Context = struct { | 818 | const Context = struct { |
| 822 | gpa: Allocator, | 819 | gpa: Allocator, |
| 823 | buf: std.ArrayList(u8), | 820 | buf: std.ArrayList(u8), |
| 824 | nodes: std.zig.Ast.NodeList = .{}, | 821 | nodes: std.zig.Ast.NodeList = .{}, |
| 825 | extra_data: std.ArrayListUnmanaged(std.zig.Ast.Node.Index) = .empty, | 822 | extra_data: std.ArrayListUnmanaged(u32) = .empty, |
| 826 | tokens: std.zig.Ast.TokenList = .{}, | 823 | tokens: std.zig.Ast.TokenList = .{}, |
| 827 | 824 | ||
| 828 | fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex { | 825 | fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex { |
| ... | @@ -834,7 +831,7 @@ const Context = struct { | ... | @@ -834,7 +831,7 @@ const Context = struct { |
| 834 | .start = @as(u32, @intCast(start_index)), | 831 | .start = @as(u32, @intCast(start_index)), |
| 835 | }); | 832 | }); |
| 836 | 833 | ||
| 837 | return @as(u32, @intCast(c.tokens.len - 1)); | 834 | return @intCast(c.tokens.len - 1); |
| 838 | } | 835 | } |
| 839 | 836 | ||
| 840 | fn addToken(c: *Context, tag: TokenTag, bytes: []const u8) Allocator.Error!TokenIndex { | 837 | fn addToken(c: *Context, tag: TokenTag, bytes: []const u8) Allocator.Error!TokenIndex { |
| ... | @@ -848,26 +845,33 @@ const Context = struct { | ... | @@ -848,26 +845,33 @@ const Context = struct { |
| 848 | } | 845 | } |
| 849 | 846 | ||
| 850 | fn listToSpan(c: *Context, list: []const NodeIndex) Allocator.Error!NodeSubRange { | 847 | fn listToSpan(c: *Context, list: []const NodeIndex) Allocator.Error!NodeSubRange { |
| 851 | try c.extra_data.appendSlice(c.gpa, list); | 848 | try c.extra_data.appendSlice(c.gpa, @ptrCast(list)); |
| 852 | return NodeSubRange{ | 849 | return NodeSubRange{ |
| 853 | .start = @as(NodeIndex, @intCast(c.extra_data.items.len - list.len)), | 850 | .start = @enumFromInt(c.extra_data.items.len - list.len), |
| 854 | .end = @as(NodeIndex, @intCast(c.extra_data.items.len)), | 851 | .end = @enumFromInt(c.extra_data.items.len), |
| 855 | }; | 852 | }; |
| 856 | } | 853 | } |
| 857 | 854 | ||
| 858 | fn addNode(c: *Context, elem: std.zig.Ast.Node) Allocator.Error!NodeIndex { | 855 | fn addNode(c: *Context, elem: std.zig.Ast.Node) Allocator.Error!NodeIndex { |
| 859 | const result = @as(NodeIndex, @intCast(c.nodes.len)); | 856 | const result: NodeIndex = @enumFromInt(c.nodes.len); |
| 860 | try c.nodes.append(c.gpa, elem); | 857 | try c.nodes.append(c.gpa, elem); |
| 861 | return result; | 858 | return result; |
| 862 | } | 859 | } |
| 863 | 860 | ||
| 864 | fn addExtra(c: *Context, extra: anytype) Allocator.Error!NodeIndex { | 861 | fn addExtra(c: *Context, extra: anytype) Allocator.Error!std.zig.Ast.ExtraIndex { |
| 865 | const fields = std.meta.fields(@TypeOf(extra)); | 862 | const fields = std.meta.fields(@TypeOf(extra)); |
| 866 | try c.extra_data.ensureUnusedCapacity(c.gpa, fields.len); | 863 | try c.extra_data.ensureUnusedCapacity(c.gpa, fields.len); |
| 867 | const result = @as(u32, @intCast(c.extra_data.items.len)); | 864 | const result: ExtraIndex = @enumFromInt(c.extra_data.items.len); |
| 868 | inline for (fields) |field| { | 865 | inline for (fields) |field| { |
| 869 | comptime std.debug.assert(field.type == NodeIndex); | 866 | switch (field.type) { |
| 870 | c.extra_data.appendAssumeCapacity(@field(extra, field.name)); | 867 | NodeIndex, |
| 868 | NodeOptionalIndex, | ||
| 869 | TokenIndex, | ||
| 870 | TokenOptionalIndex, | ||
| 871 | ExtraIndex, | ||
| 872 | => c.extra_data.appendAssumeCapacity(@intFromEnum(@field(extra, field.name))), | ||
| 873 | else => @compileError("unexpected field type"), | ||
| 874 | } | ||
| 871 | } | 875 | } |
| 872 | return result; | 876 | return result; |
| 873 | } | 877 | } |
| ... | @@ -894,7 +898,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -894,7 +898,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 894 | try c.buf.append('\n'); | 898 | try c.buf.append('\n'); |
| 895 | try c.buf.appendSlice(payload); | 899 | try c.buf.appendSlice(payload); |
| 896 | try c.buf.append('\n'); | 900 | try c.buf.append('\n'); |
| 897 | return @as(NodeIndex, 0); // error: integer value 0 cannot be coerced to type 'std.mem.Allocator.Error!u32' | 901 | return @enumFromInt(0); |
| 898 | }, | 902 | }, |
| 899 | .helpers_cast => { | 903 | .helpers_cast => { |
| 900 | const payload = node.castTag(.helpers_cast).?.data; | 904 | const payload = node.castTag(.helpers_cast).?.data; |
| ... | @@ -991,26 +995,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -991,26 +995,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 991 | .@"continue" => return c.addNode(.{ | 995 | .@"continue" => return c.addNode(.{ |
| 992 | .tag = .@"continue", | 996 | .tag = .@"continue", |
| 993 | .main_token = try c.addToken(.keyword_continue, "continue"), | 997 | .main_token = try c.addToken(.keyword_continue, "continue"), |
| 994 | .data = .{ | 998 | .data = .{ .opt_token_and_opt_node = .{ .none, .none } }, |
| 995 | .lhs = 0, | ||
| 996 | .rhs = 0, | ||
| 997 | }, | ||
| 998 | }), | 999 | }), |
| 999 | .return_void => return c.addNode(.{ | 1000 | .return_void => return c.addNode(.{ |
| 1000 | .tag = .@"return", | 1001 | .tag = .@"return", |
| 1001 | .main_token = try c.addToken(.keyword_return, "return"), | 1002 | .main_token = try c.addToken(.keyword_return, "return"), |
| 1002 | .data = .{ | 1003 | .data = .{ .opt_node = .none }, |
| 1003 | .lhs = 0, | ||
| 1004 | .rhs = undefined, | ||
| 1005 | }, | ||
| 1006 | }), | 1004 | }), |
| 1007 | .@"break" => return c.addNode(.{ | 1005 | .@"break" => return c.addNode(.{ |
| 1008 | .tag = .@"break", | 1006 | .tag = .@"break", |
| 1009 | .main_token = try c.addToken(.keyword_break, "break"), | 1007 | .main_token = try c.addToken(.keyword_break, "break"), |
| 1010 | .data = .{ | 1008 | .data = .{ .opt_token_and_opt_node = .{ .none, .none } }, |
| 1011 | .lhs = 0, | ||
| 1012 | .rhs = 0, | ||
| 1013 | }, | ||
| 1014 | }), | 1009 | }), |
| 1015 | .break_val => { | 1010 | .break_val => { |
| 1016 | const payload = node.castTag(.break_val).?.data; | 1011 | const payload = node.castTag(.break_val).?.data; |
| ... | @@ -1018,14 +1013,14 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1018,14 +1013,14 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1018 | const break_label = if (payload.label) |some| blk: { | 1013 | const break_label = if (payload.label) |some| blk: { |
| 1019 | _ = try c.addToken(.colon, ":"); | 1014 | _ = try c.addToken(.colon, ":"); |
| 1020 | break :blk try c.addIdentifier(some); | 1015 | break :blk try c.addIdentifier(some); |
| 1021 | } else 0; | 1016 | } else null; |
| 1022 | return c.addNode(.{ | 1017 | return c.addNode(.{ |
| 1023 | .tag = .@"break", | 1018 | .tag = .@"break", |
| 1024 | .main_token = tok, | 1019 | .main_token = tok, |
| 1025 | .data = .{ | 1020 | .data = .{ .opt_token_and_opt_node = .{ |
| 1026 | .lhs = break_label, | 1021 | .fromOptional(break_label), |
| 1027 | .rhs = try renderNode(c, payload.val), | 1022 | (try renderNode(c, payload.val)).toOptional(), |
| 1028 | }, | 1023 | } }, |
| 1029 | }); | 1024 | }); |
| 1030 | }, | 1025 | }, |
| 1031 | .@"return" => { | 1026 | .@"return" => { |
| ... | @@ -1033,10 +1028,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1033,10 +1028,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1033 | return c.addNode(.{ | 1028 | return c.addNode(.{ |
| 1034 | .tag = .@"return", | 1029 | .tag = .@"return", |
| 1035 | .main_token = try c.addToken(.keyword_return, "return"), | 1030 | .main_token = try c.addToken(.keyword_return, "return"), |
| 1036 | .data = .{ | 1031 | .data = .{ .opt_node = (try renderNode(c, payload)).toOptional() }, |
| 1037 | .lhs = try renderNode(c, payload), | ||
| 1038 | .rhs = undefined, | ||
| 1039 | }, | ||
| 1040 | }); | 1032 | }); |
| 1041 | }, | 1033 | }, |
| 1042 | .@"comptime" => { | 1034 | .@"comptime" => { |
| ... | @@ -1044,10 +1036,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1044,10 +1036,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1044 | return c.addNode(.{ | 1036 | return c.addNode(.{ |
| 1045 | .tag = .@"comptime", | 1037 | .tag = .@"comptime", |
| 1046 | .main_token = try c.addToken(.keyword_comptime, "comptime"), | 1038 | .main_token = try c.addToken(.keyword_comptime, "comptime"), |
| 1047 | .data = .{ | 1039 | .data = .{ .node = try renderNode(c, payload) }, |
| 1048 | .lhs = try renderNode(c, payload), | ||
| 1049 | .rhs = undefined, | ||
| 1050 | }, | ||
| 1051 | }); | 1040 | }); |
| 1052 | }, | 1041 | }, |
| 1053 | .@"defer" => { | 1042 | .@"defer" => { |
| ... | @@ -1055,10 +1044,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1055,10 +1044,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1055 | return c.addNode(.{ | 1044 | return c.addNode(.{ |
| 1056 | .tag = .@"defer", | 1045 | .tag = .@"defer", |
| 1057 | .main_token = try c.addToken(.keyword_defer, "defer"), | 1046 | .main_token = try c.addToken(.keyword_defer, "defer"), |
| 1058 | .data = .{ | 1047 | .data = .{ .node = try renderNode(c, payload) }, |
| 1059 | .lhs = undefined, | ||
| 1060 | .rhs = try renderNode(c, payload), | ||
| 1061 | }, | ||
| 1062 | }); | 1048 | }); |
| 1063 | }, | 1049 | }, |
| 1064 | .asm_simple => { | 1050 | .asm_simple => { |
| ... | @@ -1068,10 +1054,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1068,10 +1054,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1068 | return c.addNode(.{ | 1054 | return c.addNode(.{ |
| 1069 | .tag = .asm_simple, | 1055 | .tag = .asm_simple, |
| 1070 | .main_token = asm_token, | 1056 | .main_token = asm_token, |
| 1071 | .data = .{ | 1057 | .data = .{ .node_and_token = .{ |
| 1072 | .lhs = try renderNode(c, payload), | 1058 | try renderNode(c, payload), |
| 1073 | .rhs = try c.addToken(.r_paren, ")"), | 1059 | try c.addToken(.r_paren, ")"), |
| 1074 | }, | 1060 | } }, |
| 1075 | }); | 1061 | }); |
| 1076 | }, | 1062 | }, |
| 1077 | .type => { | 1063 | .type => { |
| ... | @@ -1104,10 +1090,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1104,10 +1090,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1104 | return c.addNode(.{ | 1090 | return c.addNode(.{ |
| 1105 | .tag = .address_of, | 1091 | .tag = .address_of, |
| 1106 | .main_token = tok, | 1092 | .main_token = tok, |
| 1107 | .data = .{ | 1093 | .data = .{ .node = arg }, |
| 1108 | .lhs = arg, | ||
| 1109 | .rhs = undefined, | ||
| 1110 | }, | ||
| 1111 | }); | 1094 | }); |
| 1112 | }, | 1095 | }, |
| 1113 | .float_literal => { | 1096 | .float_literal => { |
| ... | @@ -1191,13 +1174,13 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1191,13 +1174,13 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1191 | return c.addNode(.{ | 1174 | return c.addNode(.{ |
| 1192 | .tag = .slice, | 1175 | .tag = .slice, |
| 1193 | .main_token = l_bracket, | 1176 | .main_token = l_bracket, |
| 1194 | .data = .{ | 1177 | .data = .{ .node_and_extra = .{ |
| 1195 | .lhs = string, | 1178 | string, |
| 1196 | .rhs = try c.addExtra(std.zig.Ast.Node.Slice{ | 1179 | try c.addExtra(std.zig.Ast.Node.Slice{ |
| 1197 | .start = start, | 1180 | .start = start, |
| 1198 | .end = end, | 1181 | .end = end, |
| 1199 | }), | 1182 | }), |
| 1200 | }, | 1183 | } }, |
| 1201 | }); | 1184 | }); |
| 1202 | }, | 1185 | }, |
| 1203 | .fail_decl => { | 1186 | .fail_decl => { |
| ... | @@ -1220,20 +1203,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1220,20 +1203,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1220 | const compile_error = try c.addNode(.{ | 1203 | const compile_error = try c.addNode(.{ |
| 1221 | .tag = .builtin_call_two, | 1204 | .tag = .builtin_call_two, |
| 1222 | .main_token = compile_error_tok, | 1205 | .main_token = compile_error_tok, |
| 1223 | .data = .{ | 1206 | .data = .{ .opt_node_and_opt_node = .{ err_msg.toOptional(), .none } }, |
| 1224 | .lhs = err_msg, | ||
| 1225 | .rhs = 0, | ||
| 1226 | }, | ||
| 1227 | }); | 1207 | }); |
| 1228 | _ = try c.addToken(.semicolon, ";"); | 1208 | _ = try c.addToken(.semicolon, ";"); |
| 1229 | 1209 | ||
| 1230 | return c.addNode(.{ | 1210 | return c.addNode(.{ |
| 1231 | .tag = .simple_var_decl, | 1211 | .tag = .simple_var_decl, |
| 1232 | .main_token = const_tok, | 1212 | .main_token = const_tok, |
| 1233 | .data = .{ | 1213 | .data = .{ .opt_node_and_opt_node = .{ |
| 1234 | .lhs = 0, | 1214 | .none, |
| 1235 | .rhs = compile_error, | 1215 | compile_error.toOptional(), |
| 1236 | }, | 1216 | } }, |
| 1237 | }); | 1217 | }); |
| 1238 | }, | 1218 | }, |
| 1239 | .pub_var_simple, .var_simple => { | 1219 | .pub_var_simple, .var_simple => { |
| ... | @@ -1249,10 +1229,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1249,10 +1229,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1249 | return c.addNode(.{ | 1229 | return c.addNode(.{ |
| 1250 | .tag = .simple_var_decl, | 1230 | .tag = .simple_var_decl, |
| 1251 | .main_token = const_tok, | 1231 | .main_token = const_tok, |
| 1252 | .data = .{ | 1232 | .data = .{ .opt_node_and_opt_node = .{ |
| 1253 | .lhs = 0, | 1233 | .none, |
| 1254 | .rhs = init, | 1234 | init.toOptional(), |
| 1255 | }, | 1235 | } }, |
| 1256 | }); | 1236 | }); |
| 1257 | }, | 1237 | }, |
| 1258 | .static_local_var => { | 1238 | .static_local_var => { |
| ... | @@ -1268,10 +1248,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1268,10 +1248,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1268 | const container_def = try c.addNode(.{ | 1248 | const container_def = try c.addNode(.{ |
| 1269 | .tag = .container_decl_two_trailing, | 1249 | .tag = .container_decl_two_trailing, |
| 1270 | .main_token = kind_tok, | 1250 | .main_token = kind_tok, |
| 1271 | .data = .{ | 1251 | .data = .{ .opt_node_and_opt_node = .{ |
| 1272 | .lhs = try renderNode(c, payload.init), | 1252 | (try renderNode(c, payload.init)).toOptional(), |
| 1273 | .rhs = 0, | 1253 | .none, |
| 1274 | }, | 1254 | } }, |
| 1275 | }); | 1255 | }); |
| 1276 | _ = try c.addToken(.r_brace, "}"); | 1256 | _ = try c.addToken(.r_brace, "}"); |
| 1277 | _ = try c.addToken(.semicolon, ";"); | 1257 | _ = try c.addToken(.semicolon, ";"); |
| ... | @@ -1279,10 +1259,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1279,10 +1259,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1279 | return c.addNode(.{ | 1259 | return c.addNode(.{ |
| 1280 | .tag = .simple_var_decl, | 1260 | .tag = .simple_var_decl, |
| 1281 | .main_token = const_tok, | 1261 | .main_token = const_tok, |
| 1282 | .data = .{ | 1262 | .data = .{ .opt_node_and_opt_node = .{ |
| 1283 | .lhs = 0, | 1263 | .none, |
| 1284 | .rhs = container_def, | 1264 | container_def.toOptional(), |
| 1285 | }, | 1265 | } }, |
| 1286 | }); | 1266 | }); |
| 1287 | }, | 1267 | }, |
| 1288 | .extern_local_var => { | 1268 | .extern_local_var => { |
| ... | @@ -1298,10 +1278,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1298,10 +1278,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1298 | const container_def = try c.addNode(.{ | 1278 | const container_def = try c.addNode(.{ |
| 1299 | .tag = .container_decl_two_trailing, | 1279 | .tag = .container_decl_two_trailing, |
| 1300 | .main_token = kind_tok, | 1280 | .main_token = kind_tok, |
| 1301 | .data = .{ | 1281 | .data = .{ .opt_node_and_opt_node = .{ |
| 1302 | .lhs = try renderNode(c, payload.init), | 1282 | (try renderNode(c, payload.init)).toOptional(), |
| 1303 | .rhs = 0, | 1283 | .none, |
| 1304 | }, | 1284 | } }, |
| 1305 | }); | 1285 | }); |
| 1306 | _ = try c.addToken(.r_brace, "}"); | 1286 | _ = try c.addToken(.r_brace, "}"); |
| 1307 | _ = try c.addToken(.semicolon, ";"); | 1287 | _ = try c.addToken(.semicolon, ";"); |
| ... | @@ -1309,10 +1289,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1309,10 +1289,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1309 | return c.addNode(.{ | 1289 | return c.addNode(.{ |
| 1310 | .tag = .simple_var_decl, | 1290 | .tag = .simple_var_decl, |
| 1311 | .main_token = const_tok, | 1291 | .main_token = const_tok, |
| 1312 | .data = .{ | 1292 | .data = .{ .opt_node_and_opt_node = .{ |
| 1313 | .lhs = 0, | 1293 | .none, |
| 1314 | .rhs = container_def, | 1294 | container_def.toOptional(), |
| 1315 | }, | 1295 | } }, |
| 1316 | }); | 1296 | }); |
| 1317 | }, | 1297 | }, |
| 1318 | .mut_str => { | 1298 | .mut_str => { |
| ... | @@ -1324,10 +1304,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1324,10 +1304,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1324 | 1304 | ||
| 1325 | const deref = try c.addNode(.{ | 1305 | const deref = try c.addNode(.{ |
| 1326 | .tag = .deref, | 1306 | .tag = .deref, |
| 1327 | .data = .{ | 1307 | .data = .{ .node = try renderNodeGrouped(c, payload.init) }, |
| 1328 | .lhs = try renderNodeGrouped(c, payload.init), | ||
| 1329 | .rhs = undefined, | ||
| 1330 | }, | ||
| 1331 | .main_token = try c.addToken(.period_asterisk, ".*"), | 1308 | .main_token = try c.addToken(.period_asterisk, ".*"), |
| 1332 | }); | 1309 | }); |
| 1333 | _ = try c.addToken(.semicolon, ";"); | 1310 | _ = try c.addToken(.semicolon, ";"); |
| ... | @@ -1335,7 +1312,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1335,7 +1312,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1335 | return c.addNode(.{ | 1312 | return c.addNode(.{ |
| 1336 | .tag = .simple_var_decl, | 1313 | .tag = .simple_var_decl, |
| 1337 | .main_token = var_tok, | 1314 | .main_token = var_tok, |
| 1338 | .data = .{ .lhs = 0, .rhs = deref }, | 1315 | .data = .{ .opt_node_and_opt_node = .{ |
| 1316 | .none, | ||
| 1317 | deref.toOptional(), | ||
| 1318 | } }, | ||
| 1339 | }); | 1319 | }); |
| 1340 | }, | 1320 | }, |
| 1341 | .var_decl => return renderVar(c, node), | 1321 | .var_decl => return renderVar(c, node), |
| ... | @@ -1359,10 +1339,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1359,10 +1339,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1359 | return c.addNode(.{ | 1339 | return c.addNode(.{ |
| 1360 | .tag = .simple_var_decl, | 1340 | .tag = .simple_var_decl, |
| 1361 | .main_token = mut_tok, | 1341 | .main_token = mut_tok, |
| 1362 | .data = .{ | 1342 | .data = .{ .opt_node_and_opt_node = .{ |
| 1363 | .lhs = 0, | 1343 | .none, |
| 1364 | .rhs = init, | 1344 | init.toOptional(), |
| 1365 | }, | 1345 | } }, |
| 1366 | }); | 1346 | }); |
| 1367 | }, | 1347 | }, |
| 1368 | .int_cast => { | 1348 | .int_cast => { |
| ... | @@ -1505,10 +1485,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1505,10 +1485,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1505 | return c.addNode(.{ | 1485 | return c.addNode(.{ |
| 1506 | .tag = .address_of, | 1486 | .tag = .address_of, |
| 1507 | .main_token = ampersand, | 1487 | .main_token = ampersand, |
| 1508 | .data = .{ | 1488 | .data = .{ .node = base }, |
| 1509 | .lhs = base, | ||
| 1510 | .rhs = undefined, | ||
| 1511 | }, | ||
| 1512 | }); | 1489 | }); |
| 1513 | }, | 1490 | }, |
| 1514 | .deref => { | 1491 | .deref => { |
| ... | @@ -1518,10 +1495,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1518,10 +1495,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1518 | return c.addNode(.{ | 1495 | return c.addNode(.{ |
| 1519 | .tag = .deref, | 1496 | .tag = .deref, |
| 1520 | .main_token = deref_tok, | 1497 | .main_token = deref_tok, |
| 1521 | .data = .{ | 1498 | .data = .{ .node = operand }, |
| 1522 | .lhs = operand, | ||
| 1523 | .rhs = undefined, | ||
| 1524 | }, | ||
| 1525 | }); | 1499 | }); |
| 1526 | }, | 1500 | }, |
| 1527 | .unwrap => { | 1501 | .unwrap => { |
| ... | @@ -1532,10 +1506,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1532,10 +1506,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1532 | return c.addNode(.{ | 1506 | return c.addNode(.{ |
| 1533 | .tag = .unwrap_optional, | 1507 | .tag = .unwrap_optional, |
| 1534 | .main_token = period, | 1508 | .main_token = period, |
| 1535 | .data = .{ | 1509 | .data = .{ .node_and_token = .{ |
| 1536 | .lhs = operand, | 1510 | operand, |
| 1537 | .rhs = question_mark, | 1511 | question_mark, |
| 1538 | }, | 1512 | } }, |
| 1539 | }); | 1513 | }); |
| 1540 | }, | 1514 | }, |
| 1541 | .c_pointer, .single_pointer => { | 1515 | .c_pointer, .single_pointer => { |
| ... | @@ -1557,10 +1531,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1557,10 +1531,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1557 | return c.addNode(.{ | 1531 | return c.addNode(.{ |
| 1558 | .tag = .ptr_type_aligned, | 1532 | .tag = .ptr_type_aligned, |
| 1559 | .main_token = main_token, | 1533 | .main_token = main_token, |
| 1560 | .data = .{ | 1534 | .data = .{ .opt_node_and_node = .{ |
| 1561 | .lhs = 0, | 1535 | .none, |
| 1562 | .rhs = elem_type, | 1536 | elem_type, |
| 1563 | }, | 1537 | } }, |
| 1564 | }); | 1538 | }); |
| 1565 | }, | 1539 | }, |
| 1566 | .add => return renderBinOpGrouped(c, node, .add, .plus, "+"), | 1540 | .add => return renderBinOpGrouped(c, node, .add, .plus, "+"), |
| ... | @@ -1606,10 +1580,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1606,10 +1580,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1606 | return c.addNode(.{ | 1580 | return c.addNode(.{ |
| 1607 | .tag = .block_two, | 1581 | .tag = .block_two, |
| 1608 | .main_token = l_brace, | 1582 | .main_token = l_brace, |
| 1609 | .data = .{ | 1583 | .data = .{ .opt_node_and_opt_node = .{ |
| 1610 | .lhs = 0, | 1584 | .none, |
| 1611 | .rhs = 0, | 1585 | .none, |
| 1612 | }, | 1586 | } }, |
| 1613 | }); | 1587 | }); |
| 1614 | }, | 1588 | }, |
| 1615 | .block_single => { | 1589 | .block_single => { |
| ... | @@ -1623,10 +1597,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1623,10 +1597,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1623 | return c.addNode(.{ | 1597 | return c.addNode(.{ |
| 1624 | .tag = .block_two_semicolon, | 1598 | .tag = .block_two_semicolon, |
| 1625 | .main_token = l_brace, | 1599 | .main_token = l_brace, |
| 1626 | .data = .{ | 1600 | .data = .{ .opt_node_and_opt_node = .{ |
| 1627 | .lhs = stmt, | 1601 | stmt.toOptional(), |
| 1628 | .rhs = 0, | 1602 | .none, |
| 1629 | }, | 1603 | } }, |
| 1630 | }); | 1604 | }); |
| 1631 | }, | 1605 | }, |
| 1632 | .block => { | 1606 | .block => { |
| ... | @@ -1641,7 +1615,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1641,7 +1615,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1641 | defer stmts.deinit(); | 1615 | defer stmts.deinit(); |
| 1642 | for (payload.stmts) |stmt| { | 1616 | for (payload.stmts) |stmt| { |
| 1643 | const res = try renderNode(c, stmt); | 1617 | const res = try renderNode(c, stmt); |
| 1644 | if (res == 0) continue; | 1618 | if (@intFromEnum(res) == 0) continue; |
| 1645 | try addSemicolonIfNeeded(c, stmt); | 1619 | try addSemicolonIfNeeded(c, stmt); |
| 1646 | try stmts.append(res); | 1620 | try stmts.append(res); |
| 1647 | } | 1621 | } |
| ... | @@ -1652,17 +1626,14 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1652,17 +1626,14 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1652 | return c.addNode(.{ | 1626 | return c.addNode(.{ |
| 1653 | .tag = if (semicolon) .block_semicolon else .block, | 1627 | .tag = if (semicolon) .block_semicolon else .block, |
| 1654 | .main_token = l_brace, | 1628 | .main_token = l_brace, |
| 1655 | .data = .{ | 1629 | .data = .{ .extra_range = span }, |
| 1656 | .lhs = span.start, | ||
| 1657 | .rhs = span.end, | ||
| 1658 | }, | ||
| 1659 | }); | 1630 | }); |
| 1660 | }, | 1631 | }, |
| 1661 | .func => return renderFunc(c, node), | 1632 | .func => return renderFunc(c, node), |
| 1662 | .pub_inline_fn => return renderMacroFunc(c, node), | 1633 | .pub_inline_fn => return renderMacroFunc(c, node), |
| 1663 | .discard => { | 1634 | .discard => { |
| 1664 | const payload = node.castTag(.discard).?.data; | 1635 | const payload = node.castTag(.discard).?.data; |
| 1665 | if (payload.should_skip) return @as(NodeIndex, 0); | 1636 | if (payload.should_skip) return @enumFromInt(0); |
| 1666 | 1637 | ||
| 1667 | const lhs = try c.addNode(.{ | 1638 | const lhs = try c.addNode(.{ |
| 1668 | .tag = .identifier, | 1639 | .tag = .identifier, |
| ... | @@ -1680,19 +1651,19 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1680,19 +1651,19 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1680 | return c.addNode(.{ | 1651 | return c.addNode(.{ |
| 1681 | .tag = .assign, | 1652 | .tag = .assign, |
| 1682 | .main_token = main_token, | 1653 | .main_token = main_token, |
| 1683 | .data = .{ | 1654 | .data = .{ .node_and_node = .{ |
| 1684 | .lhs = lhs, | 1655 | lhs, |
| 1685 | .rhs = try renderNode(c, addr_of), | 1656 | try renderNode(c, addr_of), |
| 1686 | }, | 1657 | } }, |
| 1687 | }); | 1658 | }); |
| 1688 | } else { | 1659 | } else { |
| 1689 | return c.addNode(.{ | 1660 | return c.addNode(.{ |
| 1690 | .tag = .assign, | 1661 | .tag = .assign, |
| 1691 | .main_token = main_token, | 1662 | .main_token = main_token, |
| 1692 | .data = .{ | 1663 | .data = .{ .node_and_node = .{ |
| 1693 | .lhs = lhs, | 1664 | lhs, |
| 1694 | .rhs = try renderNode(c, payload.value), | 1665 | try renderNode(c, payload.value), |
| 1695 | }, | 1666 | } }, |
| 1696 | }); | 1667 | }); |
| 1697 | } | 1668 | } |
| 1698 | }, | 1669 | }, |
| ... | @@ -1709,29 +1680,29 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1709,29 +1680,29 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1709 | const res = try renderNode(c, some); | 1680 | const res = try renderNode(c, some); |
| 1710 | _ = try c.addToken(.r_paren, ")"); | 1681 | _ = try c.addToken(.r_paren, ")"); |
| 1711 | break :blk res; | 1682 | break :blk res; |
| 1712 | } else 0; | 1683 | } else null; |
| 1713 | const body = try renderNode(c, payload.body); | 1684 | const body = try renderNode(c, payload.body); |
| 1714 | 1685 | ||
| 1715 | if (cont_expr == 0) { | 1686 | if (cont_expr == null) { |
| 1716 | return c.addNode(.{ | 1687 | return c.addNode(.{ |
| 1717 | .tag = .while_simple, | 1688 | .tag = .while_simple, |
| 1718 | .main_token = while_tok, | 1689 | .main_token = while_tok, |
| 1719 | .data = .{ | 1690 | .data = .{ .node_and_node = .{ |
| 1720 | .lhs = cond, | 1691 | cond, |
| 1721 | .rhs = body, | 1692 | body, |
| 1722 | }, | 1693 | } }, |
| 1723 | }); | 1694 | }); |
| 1724 | } else { | 1695 | } else { |
| 1725 | return c.addNode(.{ | 1696 | return c.addNode(.{ |
| 1726 | .tag = .while_cont, | 1697 | .tag = .while_cont, |
| 1727 | .main_token = while_tok, | 1698 | .main_token = while_tok, |
| 1728 | .data = .{ | 1699 | .data = .{ .node_and_extra = .{ |
| 1729 | .lhs = cond, | 1700 | cond, |
| 1730 | .rhs = try c.addExtra(std.zig.Ast.Node.WhileCont{ | 1701 | try c.addExtra(std.zig.Ast.Node.WhileCont{ |
| 1731 | .cont_expr = cont_expr, | 1702 | .cont_expr = cont_expr.?, |
| 1732 | .then_expr = body, | 1703 | .then_expr = body, |
| 1733 | }), | 1704 | }), |
| 1734 | }, | 1705 | } }, |
| 1735 | }); | 1706 | }); |
| 1736 | } | 1707 | } |
| 1737 | }, | 1708 | }, |
| ... | @@ -1750,10 +1721,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1750,10 +1721,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1750 | return c.addNode(.{ | 1721 | return c.addNode(.{ |
| 1751 | .tag = .while_simple, | 1722 | .tag = .while_simple, |
| 1752 | .main_token = while_tok, | 1723 | .main_token = while_tok, |
| 1753 | .data = .{ | 1724 | .data = .{ .node_and_node = .{ |
| 1754 | .lhs = cond, | 1725 | cond, |
| 1755 | .rhs = body, | 1726 | body, |
| 1756 | }, | 1727 | } }, |
| 1757 | }); | 1728 | }); |
| 1758 | }, | 1729 | }, |
| 1759 | .@"if" => { | 1730 | .@"if" => { |
| ... | @@ -1767,10 +1738,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1767,10 +1738,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1767 | const else_node = payload.@"else" orelse return c.addNode(.{ | 1738 | const else_node = payload.@"else" orelse return c.addNode(.{ |
| 1768 | .tag = .if_simple, | 1739 | .tag = .if_simple, |
| 1769 | .main_token = if_tok, | 1740 | .main_token = if_tok, |
| 1770 | .data = .{ | 1741 | .data = .{ .node_and_node = .{ |
| 1771 | .lhs = cond, | 1742 | cond, |
| 1772 | .rhs = then_expr, | 1743 | then_expr, |
| 1773 | }, | 1744 | } }, |
| 1774 | }); | 1745 | }); |
| 1775 | _ = try c.addToken(.keyword_else, "else"); | 1746 | _ = try c.addToken(.keyword_else, "else"); |
| 1776 | const else_expr = try renderNode(c, else_node); | 1747 | const else_expr = try renderNode(c, else_node); |
| ... | @@ -1778,13 +1749,13 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1778,13 +1749,13 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1778 | return c.addNode(.{ | 1749 | return c.addNode(.{ |
| 1779 | .tag = .@"if", | 1750 | .tag = .@"if", |
| 1780 | .main_token = if_tok, | 1751 | .main_token = if_tok, |
| 1781 | .data = .{ | 1752 | .data = .{ .node_and_extra = .{ |
| 1782 | .lhs = cond, | 1753 | cond, |
| 1783 | .rhs = try c.addExtra(std.zig.Ast.Node.If{ | 1754 | try c.addExtra(std.zig.Ast.Node.If{ |
| 1784 | .then_expr = then_expr, | 1755 | .then_expr = then_expr, |
| 1785 | .else_expr = else_expr, | 1756 | .else_expr = else_expr, |
| 1786 | }), | 1757 | }), |
| 1787 | }, | 1758 | } }, |
| 1788 | }); | 1759 | }); |
| 1789 | }, | 1760 | }, |
| 1790 | .if_not_break => { | 1761 | .if_not_break => { |
| ... | @@ -1794,28 +1765,25 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1794,28 +1765,25 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1794 | const cond = try c.addNode(.{ | 1765 | const cond = try c.addNode(.{ |
| 1795 | .tag = .bool_not, | 1766 | .tag = .bool_not, |
| 1796 | .main_token = try c.addToken(.bang, "!"), | 1767 | .main_token = try c.addToken(.bang, "!"), |
| 1797 | .data = .{ | 1768 | .data = .{ .node = try renderNodeGrouped(c, payload) }, |
| 1798 | .lhs = try renderNodeGrouped(c, payload), | ||
| 1799 | .rhs = undefined, | ||
| 1800 | }, | ||
| 1801 | }); | 1769 | }); |
| 1802 | _ = try c.addToken(.r_paren, ")"); | 1770 | _ = try c.addToken(.r_paren, ")"); |
| 1803 | const then_expr = try c.addNode(.{ | 1771 | const then_expr = try c.addNode(.{ |
| 1804 | .tag = .@"break", | 1772 | .tag = .@"break", |
| 1805 | .main_token = try c.addToken(.keyword_break, "break"), | 1773 | .main_token = try c.addToken(.keyword_break, "break"), |
| 1806 | .data = .{ | 1774 | .data = .{ .opt_token_and_opt_node = .{ |
| 1807 | .lhs = 0, | 1775 | .none, |
| 1808 | .rhs = 0, | 1776 | .none, |
| 1809 | }, | 1777 | } }, |
| 1810 | }); | 1778 | }); |
| 1811 | 1779 | ||
| 1812 | return c.addNode(.{ | 1780 | return c.addNode(.{ |
| 1813 | .tag = .if_simple, | 1781 | .tag = .if_simple, |
| 1814 | .main_token = if_tok, | 1782 | .main_token = if_tok, |
| 1815 | .data = .{ | 1783 | .data = .{ .node_and_node = .{ |
| 1816 | .lhs = cond, | 1784 | cond, |
| 1817 | .rhs = then_expr, | 1785 | then_expr, |
| 1818 | }, | 1786 | } }, |
| 1819 | }); | 1787 | }); |
| 1820 | }, | 1788 | }, |
| 1821 | .@"switch" => { | 1789 | .@"switch" => { |
| ... | @@ -1837,13 +1805,12 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1837,13 +1805,12 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1837 | return c.addNode(.{ | 1805 | return c.addNode(.{ |
| 1838 | .tag = .switch_comma, | 1806 | .tag = .switch_comma, |
| 1839 | .main_token = switch_tok, | 1807 | .main_token = switch_tok, |
| 1840 | .data = .{ | 1808 | .data = .{ .node_and_extra = .{ |
| 1841 | .lhs = cond, | 1809 | cond, try c.addExtra(NodeSubRange{ |
| 1842 | .rhs = try c.addExtra(NodeSubRange{ | ||
| 1843 | .start = span.start, | 1810 | .start = span.start, |
| 1844 | .end = span.end, | 1811 | .end = span.end, |
| 1845 | }), | 1812 | }), |
| 1846 | }, | 1813 | } }, |
| 1847 | }); | 1814 | }); |
| 1848 | }, | 1815 | }, |
| 1849 | .switch_else => { | 1816 | .switch_else => { |
| ... | @@ -1852,43 +1819,42 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1852,43 +1819,42 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1852 | return c.addNode(.{ | 1819 | return c.addNode(.{ |
| 1853 | .tag = .switch_case_one, | 1820 | .tag = .switch_case_one, |
| 1854 | .main_token = try c.addToken(.equal_angle_bracket_right, "=>"), | 1821 | .main_token = try c.addToken(.equal_angle_bracket_right, "=>"), |
| 1855 | .data = .{ | 1822 | .data = .{ .opt_node_and_node = .{ |
| 1856 | .lhs = 0, | 1823 | .none, |
| 1857 | .rhs = try renderNode(c, payload), | 1824 | try renderNode(c, payload), |
| 1858 | }, | 1825 | } }, |
| 1859 | }); | 1826 | }); |
| 1860 | }, | 1827 | }, |
| 1861 | .switch_prong => { | 1828 | .switch_prong => { |
| 1862 | const payload = node.castTag(.switch_prong).?.data; | 1829 | const payload = node.castTag(.switch_prong).?.data; |
| 1863 | var items = try c.gpa.alloc(NodeIndex, @max(payload.cases.len, 1)); | 1830 | var items = try c.gpa.alloc(NodeIndex, payload.cases.len); |
| 1864 | defer c.gpa.free(items); | 1831 | defer c.gpa.free(items); |
| 1865 | items[0] = 0; | 1832 | for (payload.cases, items, 0..) |case, *item, i| { |
| 1866 | for (payload.cases, 0..) |item, i| { | ||
| 1867 | if (i != 0) _ = try c.addToken(.comma, ","); | 1833 | if (i != 0) _ = try c.addToken(.comma, ","); |
| 1868 | items[i] = try renderNode(c, item); | 1834 | item.* = try renderNode(c, case); |
| 1869 | } | 1835 | } |
| 1870 | _ = try c.addToken(.r_brace, "}"); | 1836 | _ = try c.addToken(.r_brace, "}"); |
| 1871 | if (items.len < 2) { | 1837 | if (items.len < 2) { |
| 1872 | return c.addNode(.{ | 1838 | return c.addNode(.{ |
| 1873 | .tag = .switch_case_one, | 1839 | .tag = .switch_case_one, |
| 1874 | .main_token = try c.addToken(.equal_angle_bracket_right, "=>"), | 1840 | .main_token = try c.addToken(.equal_angle_bracket_right, "=>"), |
| 1875 | .data = .{ | 1841 | .data = .{ .opt_node_and_node = .{ |
| 1876 | .lhs = items[0], | 1842 | if (items.len == 0) .none else items[0].toOptional(), |
| 1877 | .rhs = try renderNode(c, payload.cond), | 1843 | try renderNode(c, payload.cond), |
| 1878 | }, | 1844 | } }, |
| 1879 | }); | 1845 | }); |
| 1880 | } else { | 1846 | } else { |
| 1881 | const span = try c.listToSpan(items); | 1847 | const span = try c.listToSpan(items); |
| 1882 | return c.addNode(.{ | 1848 | return c.addNode(.{ |
| 1883 | .tag = .switch_case, | 1849 | .tag = .switch_case, |
| 1884 | .main_token = try c.addToken(.equal_angle_bracket_right, "=>"), | 1850 | .main_token = try c.addToken(.equal_angle_bracket_right, "=>"), |
| 1885 | .data = .{ | 1851 | .data = .{ .extra_and_node = .{ |
| 1886 | .lhs = try c.addExtra(NodeSubRange{ | 1852 | try c.addExtra(NodeSubRange{ |
| 1887 | .start = span.start, | 1853 | .start = span.start, |
| 1888 | .end = span.end, | 1854 | .end = span.end, |
| 1889 | }), | 1855 | }), |
| 1890 | .rhs = try renderNode(c, payload.cond), | 1856 | try renderNode(c, payload.cond), |
| 1891 | }, | 1857 | } }, |
| 1892 | }); | 1858 | }); |
| 1893 | } | 1859 | } |
| 1894 | }, | 1860 | }, |
| ... | @@ -1900,10 +1866,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1900,10 +1866,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1900 | return c.addNode(.{ | 1866 | return c.addNode(.{ |
| 1901 | .tag = .container_decl_two, | 1867 | .tag = .container_decl_two, |
| 1902 | .main_token = opaque_tok, | 1868 | .main_token = opaque_tok, |
| 1903 | .data = .{ | 1869 | .data = .{ .opt_node_and_opt_node = .{ |
| 1904 | .lhs = 0, | 1870 | .none, |
| 1905 | .rhs = 0, | 1871 | .none, |
| 1906 | }, | 1872 | } }, |
| 1907 | }); | 1873 | }); |
| 1908 | }, | 1874 | }, |
| 1909 | .array_access => { | 1875 | .array_access => { |
| ... | @@ -1915,10 +1881,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1915,10 +1881,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1915 | return c.addNode(.{ | 1881 | return c.addNode(.{ |
| 1916 | .tag = .array_access, | 1882 | .tag = .array_access, |
| 1917 | .main_token = l_bracket, | 1883 | .main_token = l_bracket, |
| 1918 | .data = .{ | 1884 | .data = .{ .node_and_node = .{ |
| 1919 | .lhs = lhs, | 1885 | lhs, |
| 1920 | .rhs = index_expr, | 1886 | index_expr, |
| 1921 | }, | 1887 | } }, |
| 1922 | }); | 1888 | }); |
| 1923 | }, | 1889 | }, |
| 1924 | .array_type => { | 1890 | .array_type => { |
| ... | @@ -1940,22 +1906,22 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1940,22 +1906,22 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1940 | const init = try c.addNode(.{ | 1906 | const init = try c.addNode(.{ |
| 1941 | .tag = .array_init_one, | 1907 | .tag = .array_init_one, |
| 1942 | .main_token = l_brace, | 1908 | .main_token = l_brace, |
| 1943 | .data = .{ | 1909 | .data = .{ .node_and_node = .{ |
| 1944 | .lhs = type_expr, | 1910 | type_expr, |
| 1945 | .rhs = val, | 1911 | val, |
| 1946 | }, | 1912 | } }, |
| 1947 | }); | 1913 | }); |
| 1948 | return c.addNode(.{ | 1914 | return c.addNode(.{ |
| 1949 | .tag = .array_cat, | 1915 | .tag = .array_cat, |
| 1950 | .main_token = try c.addToken(.asterisk_asterisk, "**"), | 1916 | .main_token = try c.addToken(.asterisk_asterisk, "**"), |
| 1951 | .data = .{ | 1917 | .data = .{ .node_and_node = .{ |
| 1952 | .lhs = init, | 1918 | init, |
| 1953 | .rhs = try c.addNode(.{ | 1919 | try c.addNode(.{ |
| 1954 | .tag = .number_literal, | 1920 | .tag = .number_literal, |
| 1955 | .main_token = try c.addTokenFmt(.number_literal, "{d}", .{payload.count}), | 1921 | .main_token = try c.addTokenFmt(.number_literal, "{d}", .{payload.count}), |
| 1956 | .data = undefined, | 1922 | .data = undefined, |
| 1957 | }), | 1923 | }), |
| 1958 | }, | 1924 | } }, |
| 1959 | }); | 1925 | }); |
| 1960 | }, | 1926 | }, |
| 1961 | .empty_array => { | 1927 | .empty_array => { |
| ... | @@ -1989,7 +1955,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1989,7 +1955,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1989 | const type_node = if (payload.type) |enum_const_type| blk: { | 1955 | const type_node = if (payload.type) |enum_const_type| blk: { |
| 1990 | _ = try c.addToken(.colon, ":"); | 1956 | _ = try c.addToken(.colon, ":"); |
| 1991 | break :blk try renderNode(c, enum_const_type); | 1957 | break :blk try renderNode(c, enum_const_type); |
| 1992 | } else 0; | 1958 | } else null; |
| 1993 | 1959 | ||
| 1994 | _ = try c.addToken(.equal, "="); | 1960 | _ = try c.addToken(.equal, "="); |
| 1995 | 1961 | ||
| ... | @@ -1999,20 +1965,18 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -1999,20 +1965,18 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 1999 | return c.addNode(.{ | 1965 | return c.addNode(.{ |
| 2000 | .tag = .simple_var_decl, | 1966 | .tag = .simple_var_decl, |
| 2001 | .main_token = const_tok, | 1967 | .main_token = const_tok, |
| 2002 | .data = .{ | 1968 | .data = .{ .opt_node_and_opt_node = .{ |
| 2003 | .lhs = type_node, | 1969 | .fromOptional(type_node), |
| 2004 | .rhs = init_node, | 1970 | init_node.toOptional(), |
| 2005 | }, | 1971 | } }, |
| 2006 | }); | 1972 | }); |
| 2007 | }, | 1973 | }, |
| 2008 | .tuple => { | 1974 | .tuple => { |
| 2009 | const payload = node.castTag(.tuple).?.data; | 1975 | const payload = node.castTag(.tuple).?.data; |
| 2010 | _ = try c.addToken(.period, "."); | 1976 | _ = try c.addToken(.period, "."); |
| 2011 | const l_brace = try c.addToken(.l_brace, "{"); | 1977 | const l_brace = try c.addToken(.l_brace, "{"); |
| 2012 | var inits = try c.gpa.alloc(NodeIndex, @max(payload.len, 2)); | 1978 | var inits = try c.gpa.alloc(NodeIndex, payload.len); |
| 2013 | defer c.gpa.free(inits); | 1979 | defer c.gpa.free(inits); |
| 2014 | inits[0] = 0; | ||
| 2015 | inits[1] = 0; | ||
| 2016 | for (payload, 0..) |init, i| { | 1980 | for (payload, 0..) |init, i| { |
| 2017 | if (i != 0) _ = try c.addToken(.comma, ","); | 1981 | if (i != 0) _ = try c.addToken(.comma, ","); |
| 2018 | inits[i] = try renderNode(c, init); | 1982 | inits[i] = try renderNode(c, init); |
| ... | @@ -2022,20 +1986,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -2022,20 +1986,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 2022 | return c.addNode(.{ | 1986 | return c.addNode(.{ |
| 2023 | .tag = .array_init_dot_two, | 1987 | .tag = .array_init_dot_two, |
| 2024 | .main_token = l_brace, | 1988 | .main_token = l_brace, |
| 2025 | .data = .{ | 1989 | .data = .{ .opt_node_and_opt_node = .{ |
| 2026 | .lhs = inits[0], | 1990 | if (inits.len < 1) .none else inits[0].toOptional(), |
| 2027 | .rhs = inits[1], | 1991 | if (inits.len < 2) .none else inits[1].toOptional(), |
| 2028 | }, | 1992 | } }, |
| 2029 | }); | 1993 | }); |
| 2030 | } else { | 1994 | } else { |
| 2031 | const span = try c.listToSpan(inits); | 1995 | const span = try c.listToSpan(inits); |
| 2032 | return c.addNode(.{ | 1996 | return c.addNode(.{ |
| 2033 | .tag = .array_init_dot, | 1997 | .tag = .array_init_dot, |
| 2034 | .main_token = l_brace, | 1998 | .main_token = l_brace, |
| 2035 | .data = .{ | 1999 | .data = .{ .extra_range = span }, |
| 2036 | .lhs = span.start, | ||
| 2037 | .rhs = span.end, | ||
| 2038 | }, | ||
| 2039 | }); | 2000 | }); |
| 2040 | } | 2001 | } |
| 2041 | }, | 2002 | }, |
| ... | @@ -2043,10 +2004,8 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -2043,10 +2004,8 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 2043 | const payload = node.castTag(.container_init_dot).?.data; | 2004 | const payload = node.castTag(.container_init_dot).?.data; |
| 2044 | _ = try c.addToken(.period, "."); | 2005 | _ = try c.addToken(.period, "."); |
| 2045 | const l_brace = try c.addToken(.l_brace, "{"); | 2006 | const l_brace = try c.addToken(.l_brace, "{"); |
| 2046 | var inits = try c.gpa.alloc(NodeIndex, @max(payload.len, 2)); | 2007 | var inits = try c.gpa.alloc(NodeIndex, payload.len); |
| 2047 | defer c.gpa.free(inits); | 2008 | defer c.gpa.free(inits); |
| 2048 | inits[0] = 0; | ||
| 2049 | inits[1] = 0; | ||
| 2050 | for (payload, 0..) |init, i| { | 2009 | for (payload, 0..) |init, i| { |
| 2051 | _ = try c.addToken(.period, "."); | 2010 | _ = try c.addToken(.period, "."); |
| 2052 | _ = try c.addIdentifier(init.name); | 2011 | _ = try c.addIdentifier(init.name); |
| ... | @@ -2060,20 +2019,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -2060,20 +2019,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 2060 | return c.addNode(.{ | 2019 | return c.addNode(.{ |
| 2061 | .tag = .struct_init_dot_two_comma, | 2020 | .tag = .struct_init_dot_two_comma, |
| 2062 | .main_token = l_brace, | 2021 | .main_token = l_brace, |
| 2063 | .data = .{ | 2022 | .data = .{ .opt_node_and_opt_node = .{ |
| 2064 | .lhs = inits[0], | 2023 | if (inits.len < 1) .none else inits[0].toOptional(), |
| 2065 | .rhs = inits[1], | 2024 | if (inits.len < 2) .none else inits[1].toOptional(), |
| 2066 | }, | 2025 | } }, |
| 2067 | }); | 2026 | }); |
| 2068 | } else { | 2027 | } else { |
| 2069 | const span = try c.listToSpan(inits); | 2028 | const span = try c.listToSpan(inits); |
| 2070 | return c.addNode(.{ | 2029 | return c.addNode(.{ |
| 2071 | .tag = .struct_init_dot_comma, | 2030 | .tag = .struct_init_dot_comma, |
| 2072 | .main_token = l_brace, | 2031 | .main_token = l_brace, |
| 2073 | .data = .{ | 2032 | .data = .{ .extra_range = span }, |
| 2074 | .lhs = span.start, | ||
| 2075 | .rhs = span.end, | ||
| 2076 | }, | ||
| 2077 | }); | 2033 | }); |
| 2078 | } | 2034 | } |
| 2079 | }, | 2035 | }, |
| ... | @@ -2082,9 +2038,8 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -2082,9 +2038,8 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 2082 | const lhs = try renderNode(c, payload.lhs); | 2038 | const lhs = try renderNode(c, payload.lhs); |
| 2083 | 2039 | ||
| 2084 | const l_brace = try c.addToken(.l_brace, "{"); | 2040 | const l_brace = try c.addToken(.l_brace, "{"); |
| 2085 | var inits = try c.gpa.alloc(NodeIndex, @max(payload.inits.len, 1)); | 2041 | var inits = try c.gpa.alloc(NodeIndex, payload.inits.len); |
| 2086 | defer c.gpa.free(inits); | 2042 | defer c.gpa.free(inits); |
| 2087 | inits[0] = 0; | ||
| 2088 | for (payload.inits, 0..) |init, i| { | 2043 | for (payload.inits, 0..) |init, i| { |
| 2089 | _ = try c.addToken(.period, "."); | 2044 | _ = try c.addToken(.period, "."); |
| 2090 | _ = try c.addIdentifier(init.name); | 2045 | _ = try c.addIdentifier(init.name); |
| ... | @@ -2098,31 +2053,30 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -2098,31 +2053,30 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 2098 | 0 => c.addNode(.{ | 2053 | 0 => c.addNode(.{ |
| 2099 | .tag = .struct_init_one, | 2054 | .tag = .struct_init_one, |
| 2100 | .main_token = l_brace, | 2055 | .main_token = l_brace, |
| 2101 | .data = .{ | 2056 | .data = .{ .node_and_opt_node = .{ |
| 2102 | .lhs = lhs, | 2057 | lhs, |
| 2103 | .rhs = 0, | 2058 | .none, |
| 2104 | }, | 2059 | } }, |
| 2105 | }), | 2060 | }), |
| 2106 | 1 => c.addNode(.{ | 2061 | 1 => c.addNode(.{ |
| 2107 | .tag = .struct_init_one_comma, | 2062 | .tag = .struct_init_one_comma, |
| 2108 | .main_token = l_brace, | 2063 | .main_token = l_brace, |
| 2109 | .data = .{ | 2064 | .data = .{ .node_and_opt_node = .{ |
| 2110 | .lhs = lhs, | 2065 | lhs, |
| 2111 | .rhs = inits[0], | 2066 | inits[0].toOptional(), |
| 2112 | }, | 2067 | } }, |
| 2113 | }), | 2068 | }), |
| 2114 | else => blk: { | 2069 | else => blk: { |
| 2115 | const span = try c.listToSpan(inits); | 2070 | const span = try c.listToSpan(inits); |
| 2116 | break :blk c.addNode(.{ | 2071 | break :blk c.addNode(.{ |
| 2117 | .tag = .struct_init_comma, | 2072 | .tag = .struct_init_comma, |
| 2118 | .main_token = l_brace, | 2073 | .main_token = l_brace, |
| 2119 | .data = .{ | 2074 | .data = .{ .node_and_extra = .{ |
| 2120 | .lhs = lhs, | 2075 | lhs, try c.addExtra(NodeSubRange{ |
| 2121 | .rhs = try c.addExtra(NodeSubRange{ | ||
| 2122 | .start = span.start, | 2076 | .start = span.start, |
| 2123 | .end = span.end, | 2077 | .end = span.end, |
| 2124 | }), | 2078 | }), |
| 2125 | }, | 2079 | } }, |
| 2126 | }); | 2080 | }); |
| 2127 | }, | 2081 | }, |
| 2128 | }; | 2082 | }; |
| ... | @@ -2147,10 +2101,8 @@ fn renderRecord(c: *Context, node: Node) !NodeIndex { | ... | @@ -2147,10 +2101,8 @@ fn renderRecord(c: *Context, node: Node) !NodeIndex { |
| 2147 | const num_vars = payload.variables.len; | 2101 | const num_vars = payload.variables.len; |
| 2148 | const num_funcs = payload.functions.len; | 2102 | const num_funcs = payload.functions.len; |
| 2149 | const total_members = payload.fields.len + num_vars + num_funcs; | 2103 | const total_members = payload.fields.len + num_vars + num_funcs; |
| 2150 | const members = try c.gpa.alloc(NodeIndex, @max(total_members, 2)); | 2104 | const members = try c.gpa.alloc(NodeIndex, total_members); |
| 2151 | defer c.gpa.free(members); | 2105 | defer c.gpa.free(members); |
| 2152 | members[0] = 0; | ||
| 2153 | members[1] = 0; | ||
| 2154 | 2106 | ||
| 2155 | for (payload.fields, 0..) |field, i| { | 2107 | for (payload.fields, 0..) |field, i| { |
| 2156 | const name_tok = try c.addTokenFmt(.identifier, "{p}", .{std.zig.fmtId(field.name)}); | 2108 | const name_tok = try c.addTokenFmt(.identifier, "{p}", .{std.zig.fmtId(field.name)}); |
| ... | @@ -2167,37 +2119,36 @@ fn renderRecord(c: *Context, node: Node) !NodeIndex { | ... | @@ -2167,37 +2119,36 @@ fn renderRecord(c: *Context, node: Node) !NodeIndex { |
| 2167 | }); | 2119 | }); |
| 2168 | _ = try c.addToken(.r_paren, ")"); | 2120 | _ = try c.addToken(.r_paren, ")"); |
| 2169 | break :blk align_expr; | 2121 | break :blk align_expr; |
| 2170 | } else 0; | 2122 | } else null; |
| 2171 | 2123 | ||
| 2172 | const value_expr = if (field.default_value) |value| blk: { | 2124 | const value_expr = if (field.default_value) |value| blk: { |
| 2173 | _ = try c.addToken(.equal, "="); | 2125 | _ = try c.addToken(.equal, "="); |
| 2174 | break :blk try renderNode(c, value); | 2126 | break :blk try renderNode(c, value); |
| 2175 | } else 0; | 2127 | } else null; |
| 2176 | 2128 | ||
| 2177 | members[i] = try c.addNode(if (align_expr == 0) .{ | 2129 | members[i] = try c.addNode(if (align_expr == null) .{ |
| 2178 | .tag = .container_field_init, | 2130 | .tag = .container_field_init, |
| 2179 | .main_token = name_tok, | 2131 | .main_token = name_tok, |
| 2180 | .data = .{ | 2132 | .data = .{ .node_and_opt_node = .{ |
| 2181 | .lhs = type_expr, | 2133 | type_expr, |
| 2182 | .rhs = value_expr, | 2134 | .fromOptional(value_expr), |
| 2183 | }, | 2135 | } }, |
| 2184 | } else if (value_expr == 0) .{ | 2136 | } else if (value_expr == null) .{ |
| 2185 | .tag = .container_field_align, | 2137 | .tag = .container_field_align, |
| 2186 | .main_token = name_tok, | 2138 | .main_token = name_tok, |
| 2187 | .data = .{ | 2139 | .data = .{ .node_and_node = .{ |
| 2188 | .lhs = type_expr, | 2140 | type_expr, |
| 2189 | .rhs = align_expr, | 2141 | align_expr.?, |
| 2190 | }, | 2142 | } }, |
| 2191 | } else .{ | 2143 | } else .{ |
| 2192 | .tag = .container_field, | 2144 | .tag = .container_field, |
| 2193 | .main_token = name_tok, | 2145 | .main_token = name_tok, |
| 2194 | .data = .{ | 2146 | .data = .{ .node_and_extra = .{ |
| 2195 | .lhs = type_expr, | 2147 | type_expr, try c.addExtra(std.zig.Ast.Node.ContainerField{ |
| 2196 | .rhs = try c.addExtra(std.zig.Ast.Node.ContainerField{ | 2148 | .align_expr = align_expr.?, |
| 2197 | .align_expr = align_expr, | 2149 | .value_expr = value_expr.?, |
| 2198 | .value_expr = value_expr, | ||
| 2199 | }), | 2150 | }), |
| 2200 | }, | 2151 | } }, |
| 2201 | }); | 2152 | }); |
| 2202 | _ = try c.addToken(.comma, ","); | 2153 | _ = try c.addToken(.comma, ","); |
| 2203 | } | 2154 | } |
| ... | @@ -2213,29 +2164,26 @@ fn renderRecord(c: *Context, node: Node) !NodeIndex { | ... | @@ -2213,29 +2164,26 @@ fn renderRecord(c: *Context, node: Node) !NodeIndex { |
| 2213 | return c.addNode(.{ | 2164 | return c.addNode(.{ |
| 2214 | .tag = .container_decl_two, | 2165 | .tag = .container_decl_two, |
| 2215 | .main_token = kind_tok, | 2166 | .main_token = kind_tok, |
| 2216 | .data = .{ | 2167 | .data = .{ .opt_node_and_opt_node = .{ |
| 2217 | .lhs = 0, | 2168 | .none, |
| 2218 | .rhs = 0, | 2169 | .none, |
| 2219 | }, | 2170 | } }, |
| 2220 | }); | 2171 | }); |
| 2221 | } else if (total_members <= 2) { | 2172 | } else if (total_members <= 2) { |
| 2222 | return c.addNode(.{ | 2173 | return c.addNode(.{ |
| 2223 | .tag = if (num_funcs == 0) .container_decl_two_trailing else .container_decl_two, | 2174 | .tag = if (num_funcs == 0) .container_decl_two_trailing else .container_decl_two, |
| 2224 | .main_token = kind_tok, | 2175 | .main_token = kind_tok, |
| 2225 | .data = .{ | 2176 | .data = .{ .opt_node_and_opt_node = .{ |
| 2226 | .lhs = members[0], | 2177 | if (members.len < 1) .none else members[0].toOptional(), |
| 2227 | .rhs = members[1], | 2178 | if (members.len < 2) .none else members[1].toOptional(), |
| 2228 | }, | 2179 | } }, |
| 2229 | }); | 2180 | }); |
| 2230 | } else { | 2181 | } else { |
| 2231 | const span = try c.listToSpan(members); | 2182 | const span = try c.listToSpan(members); |
| 2232 | return c.addNode(.{ | 2183 | return c.addNode(.{ |
| 2233 | .tag = if (num_funcs == 0) .container_decl_trailing else .container_decl, | 2184 | .tag = if (num_funcs == 0) .container_decl_trailing else .container_decl, |
| 2234 | .main_token = kind_tok, | 2185 | .main_token = kind_tok, |
| 2235 | .data = .{ | 2186 | .data = .{ .extra_range = span }, |
| 2236 | .lhs = span.start, | ||
| 2237 | .rhs = span.end, | ||
| 2238 | }, | ||
| 2239 | }); | 2187 | }); |
| 2240 | } | 2188 | } |
| 2241 | } | 2189 | } |
| ... | @@ -2244,45 +2192,52 @@ fn renderFieldAccess(c: *Context, lhs: NodeIndex, field_name: []const u8) !NodeI | ... | @@ -2244,45 +2192,52 @@ fn renderFieldAccess(c: *Context, lhs: NodeIndex, field_name: []const u8) !NodeI |
| 2244 | return c.addNode(.{ | 2192 | return c.addNode(.{ |
| 2245 | .tag = .field_access, | 2193 | .tag = .field_access, |
| 2246 | .main_token = try c.addToken(.period, "."), | 2194 | .main_token = try c.addToken(.period, "."), |
| 2247 | .data = .{ | 2195 | .data = .{ .node_and_token = .{ |
| 2248 | .lhs = lhs, | 2196 | lhs, |
| 2249 | .rhs = try c.addTokenFmt(.identifier, "{p}", .{std.zig.fmtId(field_name)}), | 2197 | try c.addTokenFmt(.identifier, "{p}", .{std.zig.fmtId(field_name)}), |
| 2250 | }, | 2198 | } }, |
| 2251 | }); | 2199 | }); |
| 2252 | } | 2200 | } |
| 2253 | 2201 | ||
| 2254 | fn renderArrayInit(c: *Context, lhs: NodeIndex, inits: []const Node) !NodeIndex { | 2202 | fn renderArrayInit(c: *Context, lhs: NodeIndex, inits: []const Node) !NodeIndex { |
| 2255 | const l_brace = try c.addToken(.l_brace, "{"); | 2203 | const l_brace = try c.addToken(.l_brace, "{"); |
| 2256 | var rendered = try c.gpa.alloc(NodeIndex, @max(inits.len, 1)); | 2204 | var rendered = try c.gpa.alloc(NodeIndex, inits.len); |
| 2257 | defer c.gpa.free(rendered); | 2205 | defer c.gpa.free(rendered); |
| 2258 | rendered[0] = 0; | ||
| 2259 | for (inits, 0..) |init, i| { | 2206 | for (inits, 0..) |init, i| { |
| 2260 | rendered[i] = try renderNode(c, init); | 2207 | rendered[i] = try renderNode(c, init); |
| 2261 | _ = try c.addToken(.comma, ","); | 2208 | _ = try c.addToken(.comma, ","); |
| 2262 | } | 2209 | } |
| 2263 | _ = try c.addToken(.r_brace, "}"); | 2210 | _ = try c.addToken(.r_brace, "}"); |
| 2264 | if (inits.len < 2) { | 2211 | switch (inits.len) { |
| 2265 | return c.addNode(.{ | 2212 | 0 => return c.addNode(.{ |
| 2266 | .tag = .array_init_one_comma, | 2213 | .tag = .struct_init_one, |
| 2267 | .main_token = l_brace, | 2214 | .main_token = l_brace, |
| 2268 | .data = .{ | 2215 | .data = .{ .node_and_opt_node = .{ |
| 2269 | .lhs = lhs, | 2216 | lhs, |
| 2270 | .rhs = rendered[0], | 2217 | .none, |
| 2271 | }, | 2218 | } }, |
| 2272 | }); | 2219 | }), |
| 2273 | } else { | 2220 | 1 => return c.addNode(.{ |
| 2274 | const span = try c.listToSpan(rendered); | 2221 | .tag = .array_init_one_comma, |
| 2275 | return c.addNode(.{ | ||
| 2276 | .tag = .array_init_comma, | ||
| 2277 | .main_token = l_brace, | 2222 | .main_token = l_brace, |
| 2278 | .data = .{ | 2223 | .data = .{ .node_and_node = .{ |
| 2279 | .lhs = lhs, | 2224 | lhs, |
| 2280 | .rhs = try c.addExtra(NodeSubRange{ | 2225 | rendered[0], |
| 2281 | .start = span.start, | 2226 | } }, |
| 2282 | .end = span.end, | 2227 | }), |
| 2283 | }), | 2228 | else => { |
| 2284 | }, | 2229 | const span = try c.listToSpan(rendered); |
| 2285 | }); | 2230 | return c.addNode(.{ |
| 2231 | .tag = .array_init_comma, | ||
| 2232 | .main_token = l_brace, | ||
| 2233 | .data = .{ .node_and_extra = .{ | ||
| 2234 | lhs, try c.addExtra(NodeSubRange{ | ||
| 2235 | .start = span.start, | ||
| 2236 | .end = span.end, | ||
| 2237 | }), | ||
| 2238 | } }, | ||
| 2239 | }); | ||
| 2240 | }, | ||
| 2286 | } | 2241 | } |
| 2287 | } | 2242 | } |
| 2288 | 2243 | ||
| ... | @@ -2298,10 +2253,10 @@ fn renderArrayType(c: *Context, len: usize, elem_type: Node) !NodeIndex { | ... | @@ -2298,10 +2253,10 @@ fn renderArrayType(c: *Context, len: usize, elem_type: Node) !NodeIndex { |
| 2298 | return c.addNode(.{ | 2253 | return c.addNode(.{ |
| 2299 | .tag = .array_type, | 2254 | .tag = .array_type, |
| 2300 | .main_token = l_bracket, | 2255 | .main_token = l_bracket, |
| 2301 | .data = .{ | 2256 | .data = .{ .node_and_node = .{ |
| 2302 | .lhs = len_expr, | 2257 | len_expr, |
| 2303 | .rhs = elem_type_expr, | 2258 | elem_type_expr, |
| 2304 | }, | 2259 | } }, |
| 2305 | }); | 2260 | }); |
| 2306 | } | 2261 | } |
| 2307 | 2262 | ||
| ... | @@ -2325,13 +2280,13 @@ fn renderNullSentinelArrayType(c: *Context, len: usize, elem_type: Node) !NodeIn | ... | @@ -2325,13 +2280,13 @@ fn renderNullSentinelArrayType(c: *Context, len: usize, elem_type: Node) !NodeIn |
| 2325 | return c.addNode(.{ | 2280 | return c.addNode(.{ |
| 2326 | .tag = .array_type_sentinel, | 2281 | .tag = .array_type_sentinel, |
| 2327 | .main_token = l_bracket, | 2282 | .main_token = l_bracket, |
| 2328 | .data = .{ | 2283 | .data = .{ .node_and_extra = .{ |
| 2329 | .lhs = len_expr, | 2284 | len_expr, |
| 2330 | .rhs = try c.addExtra(std.zig.Ast.Node.ArrayTypeSentinel{ | 2285 | try c.addExtra(std.zig.Ast.Node.ArrayTypeSentinel{ |
| 2331 | .sentinel = sentinel_expr, | 2286 | .sentinel = sentinel_expr, |
| 2332 | .elem_type = elem_type_expr, | 2287 | .elem_type = elem_type_expr, |
| 2333 | }), | 2288 | }), |
| 2334 | }, | 2289 | } }, |
| 2335 | }); | 2290 | }); |
| 2336 | } | 2291 | } |
| 2337 | 2292 | ||
| ... | @@ -2482,10 +2437,10 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { | ... | @@ -2482,10 +2437,10 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { |
| 2482 | => return c.addNode(.{ | 2437 | => return c.addNode(.{ |
| 2483 | .tag = .grouped_expression, | 2438 | .tag = .grouped_expression, |
| 2484 | .main_token = try c.addToken(.l_paren, "("), | 2439 | .main_token = try c.addToken(.l_paren, "("), |
| 2485 | .data = .{ | 2440 | .data = .{ .node_and_token = .{ |
| 2486 | .lhs = try renderNode(c, node), | 2441 | try renderNode(c, node), |
| 2487 | .rhs = try c.addToken(.r_paren, ")"), | 2442 | try c.addToken(.r_paren, ")"), |
| 2488 | }, | 2443 | } }, |
| 2489 | }), | 2444 | }), |
| 2490 | .ellipsis3, | 2445 | .ellipsis3, |
| 2491 | .switch_prong, | 2446 | .switch_prong, |
| ... | @@ -2539,10 +2494,7 @@ fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: T | ... | @@ -2539,10 +2494,7 @@ fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: T |
| 2539 | return c.addNode(.{ | 2494 | return c.addNode(.{ |
| 2540 | .tag = tag, | 2495 | .tag = tag, |
| 2541 | .main_token = try c.addToken(tok_tag, bytes), | 2496 | .main_token = try c.addToken(tok_tag, bytes), |
| 2542 | .data = .{ | 2497 | .data = .{ .node = try renderNodeGrouped(c, payload) }, |
| 2543 | .lhs = try renderNodeGrouped(c, payload), | ||
| 2544 | .rhs = undefined, | ||
| 2545 | }, | ||
| 2546 | }); | 2498 | }); |
| 2547 | } | 2499 | } |
| 2548 | 2500 | ||
| ... | @@ -2552,10 +2504,10 @@ fn renderBinOpGrouped(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_ta | ... | @@ -2552,10 +2504,10 @@ fn renderBinOpGrouped(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_ta |
| 2552 | return c.addNode(.{ | 2504 | return c.addNode(.{ |
| 2553 | .tag = tag, | 2505 | .tag = tag, |
| 2554 | .main_token = try c.addToken(tok_tag, bytes), | 2506 | .main_token = try c.addToken(tok_tag, bytes), |
| 2555 | .data = .{ | 2507 | .data = .{ .node_and_node = .{ |
| 2556 | .lhs = lhs, | 2508 | lhs, |
| 2557 | .rhs = try renderNodeGrouped(c, payload.rhs), | 2509 | try renderNodeGrouped(c, payload.rhs), |
| 2558 | }, | 2510 | } }, |
| 2559 | }); | 2511 | }); |
| 2560 | } | 2512 | } |
| 2561 | 2513 | ||
| ... | @@ -2565,10 +2517,10 @@ fn renderBinOp(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: Toke | ... | @@ -2565,10 +2517,10 @@ fn renderBinOp(c: *Context, node: Node, tag: std.zig.Ast.Node.Tag, tok_tag: Toke |
| 2565 | return c.addNode(.{ | 2517 | return c.addNode(.{ |
| 2566 | .tag = tag, | 2518 | .tag = tag, |
| 2567 | .main_token = try c.addToken(tok_tag, bytes), | 2519 | .main_token = try c.addToken(tok_tag, bytes), |
| 2568 | .data = .{ | 2520 | .data = .{ .node_and_node = .{ |
| 2569 | .lhs = lhs, | 2521 | lhs, |
| 2570 | .rhs = try renderNode(c, payload.rhs), | 2522 | try renderNode(c, payload.rhs), |
| 2571 | }, | 2523 | } }, |
| 2572 | }); | 2524 | }); |
| 2573 | } | 2525 | } |
| 2574 | 2526 | ||
| ... | @@ -2586,10 +2538,7 @@ fn renderStdImport(c: *Context, parts: []const []const u8) !NodeIndex { | ... | @@ -2586,10 +2538,7 @@ fn renderStdImport(c: *Context, parts: []const []const u8) !NodeIndex { |
| 2586 | const import_node = try c.addNode(.{ | 2538 | const import_node = try c.addNode(.{ |
| 2587 | .tag = .builtin_call_two, | 2539 | .tag = .builtin_call_two, |
| 2588 | .main_token = import_tok, | 2540 | .main_token = import_tok, |
| 2589 | .data = .{ | 2541 | .data = .{ .opt_node_and_opt_node = .{ std_node.toOptional(), .none } }, |
| 2590 | .lhs = std_node, | ||
| 2591 | .rhs = 0, | ||
| 2592 | }, | ||
| 2593 | }); | 2542 | }); |
| 2594 | 2543 | ||
| 2595 | var access_chain = import_node; | 2544 | var access_chain = import_node; |
| ... | @@ -2605,20 +2554,14 @@ fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex { | ... | @@ -2605,20 +2554,14 @@ fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex { |
| 2605 | 0 => try c.addNode(.{ | 2554 | 0 => try c.addNode(.{ |
| 2606 | .tag = .call_one, | 2555 | .tag = .call_one, |
| 2607 | .main_token = lparen, | 2556 | .main_token = lparen, |
| 2608 | .data = .{ | 2557 | .data = .{ .node_and_opt_node = .{ lhs, .none } }, |
| 2609 | .lhs = lhs, | ||
| 2610 | .rhs = 0, | ||
| 2611 | }, | ||
| 2612 | }), | 2558 | }), |
| 2613 | 1 => blk: { | 2559 | 1 => blk: { |
| 2614 | const arg = try renderNode(c, args[0]); | 2560 | const arg = try renderNode(c, args[0]); |
| 2615 | break :blk try c.addNode(.{ | 2561 | break :blk try c.addNode(.{ |
| 2616 | .tag = .call_one, | 2562 | .tag = .call_one, |
| 2617 | .main_token = lparen, | 2563 | .main_token = lparen, |
| 2618 | .data = .{ | 2564 | .data = .{ .node_and_opt_node = .{ lhs, arg.toOptional() } }, |
| 2619 | .lhs = lhs, | ||
| 2620 | .rhs = arg, | ||
| 2621 | }, | ||
| 2622 | }); | 2565 | }); |
| 2623 | }, | 2566 | }, |
| 2624 | else => blk: { | 2567 | else => blk: { |
| ... | @@ -2633,13 +2576,10 @@ fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex { | ... | @@ -2633,13 +2576,10 @@ fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex { |
| 2633 | break :blk try c.addNode(.{ | 2576 | break :blk try c.addNode(.{ |
| 2634 | .tag = .call, | 2577 | .tag = .call, |
| 2635 | .main_token = lparen, | 2578 | .main_token = lparen, |
| 2636 | .data = .{ | 2579 | .data = .{ .node_and_extra = .{ |
| 2637 | .lhs = lhs, | 2580 | lhs, |
| 2638 | .rhs = try c.addExtra(NodeSubRange{ | 2581 | try c.addExtra(NodeSubRange{ .start = span.start, .end = span.end }), |
| 2639 | .start = span.start, | 2582 | } }, |
| 2640 | .end = span.end, | ||
| 2641 | }), | ||
| 2642 | }, | ||
| 2643 | }); | 2583 | }); |
| 2644 | }, | 2584 | }, |
| 2645 | }; | 2585 | }; |
| ... | @@ -2650,10 +2590,10 @@ fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex { | ... | @@ -2650,10 +2590,10 @@ fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex { |
| 2650 | fn renderBuiltinCall(c: *Context, builtin: []const u8, args: []const Node) !NodeIndex { | 2590 | fn renderBuiltinCall(c: *Context, builtin: []const u8, args: []const Node) !NodeIndex { |
| 2651 | const builtin_tok = try c.addToken(.builtin, builtin); | 2591 | const builtin_tok = try c.addToken(.builtin, builtin); |
| 2652 | _ = try c.addToken(.l_paren, "("); | 2592 | _ = try c.addToken(.l_paren, "("); |
| 2653 | var arg_1: NodeIndex = 0; | 2593 | var arg_1: NodeIndex = undefined; |
| 2654 | var arg_2: NodeIndex = 0; | 2594 | var arg_2: NodeIndex = undefined; |
| 2655 | var arg_3: NodeIndex = 0; | 2595 | var arg_3: NodeIndex = undefined; |
| 2656 | var arg_4: NodeIndex = 0; | 2596 | var arg_4: NodeIndex = undefined; |
| 2657 | switch (args.len) { | 2597 | switch (args.len) { |
| 2658 | 0 => {}, | 2598 | 0 => {}, |
| 2659 | 1 => { | 2599 | 1 => { |
| ... | @@ -2681,10 +2621,10 @@ fn renderBuiltinCall(c: *Context, builtin: []const u8, args: []const Node) !Node | ... | @@ -2681,10 +2621,10 @@ fn renderBuiltinCall(c: *Context, builtin: []const u8, args: []const Node) !Node |
| 2681 | return c.addNode(.{ | 2621 | return c.addNode(.{ |
| 2682 | .tag = .builtin_call_two, | 2622 | .tag = .builtin_call_two, |
| 2683 | .main_token = builtin_tok, | 2623 | .main_token = builtin_tok, |
| 2684 | .data = .{ | 2624 | .data = .{ .opt_node_and_opt_node = .{ |
| 2685 | .lhs = arg_1, | 2625 | if (args.len < 1) .none else arg_1.toOptional(), |
| 2686 | .rhs = arg_2, | 2626 | if (args.len < 2) .none else arg_2.toOptional(), |
| 2687 | }, | 2627 | } }, |
| 2688 | }); | 2628 | }); |
| 2689 | } else { | 2629 | } else { |
| 2690 | std.debug.assert(args.len == 4); | 2630 | std.debug.assert(args.len == 4); |
| ... | @@ -2693,10 +2633,7 @@ fn renderBuiltinCall(c: *Context, builtin: []const u8, args: []const Node) !Node | ... | @@ -2693,10 +2633,7 @@ fn renderBuiltinCall(c: *Context, builtin: []const u8, args: []const Node) !Node |
| 2693 | return c.addNode(.{ | 2633 | return c.addNode(.{ |
| 2694 | .tag = .builtin_call, | 2634 | .tag = .builtin_call, |
| 2695 | .main_token = builtin_tok, | 2635 | .main_token = builtin_tok, |
| 2696 | .data = .{ | 2636 | .data = .{ .extra_range = params }, |
| 2697 | .lhs = params.start, | ||
| 2698 | .rhs = params.end, | ||
| 2699 | }, | ||
| 2700 | }); | 2637 | }); |
| 2701 | } | 2638 | } |
| 2702 | } | 2639 | } |
| ... | @@ -2725,7 +2662,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex { | ... | @@ -2725,7 +2662,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex { |
| 2725 | }); | 2662 | }); |
| 2726 | _ = try c.addToken(.r_paren, ")"); | 2663 | _ = try c.addToken(.r_paren, ")"); |
| 2727 | break :blk res; | 2664 | break :blk res; |
| 2728 | } else 0; | 2665 | } else null; |
| 2729 | 2666 | ||
| 2730 | const section_node = if (payload.linksection_string) |some| blk: { | 2667 | const section_node = if (payload.linksection_string) |some| blk: { |
| 2731 | _ = try c.addToken(.keyword_linksection, "linksection"); | 2668 | _ = try c.addToken(.keyword_linksection, "linksection"); |
| ... | @@ -2737,50 +2674,50 @@ fn renderVar(c: *Context, node: Node) !NodeIndex { | ... | @@ -2737,50 +2674,50 @@ fn renderVar(c: *Context, node: Node) !NodeIndex { |
| 2737 | }); | 2674 | }); |
| 2738 | _ = try c.addToken(.r_paren, ")"); | 2675 | _ = try c.addToken(.r_paren, ")"); |
| 2739 | break :blk res; | 2676 | break :blk res; |
| 2740 | } else 0; | 2677 | } else null; |
| 2741 | 2678 | ||
| 2742 | const init_node = if (payload.init) |some| blk: { | 2679 | const init_node = if (payload.init) |some| blk: { |
| 2743 | _ = try c.addToken(.equal, "="); | 2680 | _ = try c.addToken(.equal, "="); |
| 2744 | break :blk try renderNode(c, some); | 2681 | break :blk try renderNode(c, some); |
| 2745 | } else 0; | 2682 | } else null; |
| 2746 | _ = try c.addToken(.semicolon, ";"); | 2683 | _ = try c.addToken(.semicolon, ";"); |
| 2747 | 2684 | ||
| 2748 | if (section_node == 0) { | 2685 | if (section_node == null) { |
| 2749 | if (align_node == 0) { | 2686 | if (align_node == null) { |
| 2750 | return c.addNode(.{ | 2687 | return c.addNode(.{ |
| 2751 | .tag = .simple_var_decl, | 2688 | .tag = .simple_var_decl, |
| 2752 | .main_token = mut_tok, | 2689 | .main_token = mut_tok, |
| 2753 | .data = .{ | 2690 | .data = .{ .opt_node_and_opt_node = .{ |
| 2754 | .lhs = type_node, | 2691 | type_node.toOptional(), |
| 2755 | .rhs = init_node, | 2692 | .fromOptional(init_node), |
| 2756 | }, | 2693 | } }, |
| 2757 | }); | 2694 | }); |
| 2758 | } else { | 2695 | } else { |
| 2759 | return c.addNode(.{ | 2696 | return c.addNode(.{ |
| 2760 | .tag = .local_var_decl, | 2697 | .tag = .local_var_decl, |
| 2761 | .main_token = mut_tok, | 2698 | .main_token = mut_tok, |
| 2762 | .data = .{ | 2699 | .data = .{ .extra_and_opt_node = .{ |
| 2763 | .lhs = try c.addExtra(std.zig.Ast.Node.LocalVarDecl{ | 2700 | try c.addExtra(std.zig.Ast.Node.LocalVarDecl{ |
| 2764 | .type_node = type_node, | 2701 | .type_node = type_node, |
| 2765 | .align_node = align_node, | 2702 | .align_node = align_node.?, |
| 2766 | }), | 2703 | }), |
| 2767 | .rhs = init_node, | 2704 | .fromOptional(init_node), |
| 2768 | }, | 2705 | } }, |
| 2769 | }); | 2706 | }); |
| 2770 | } | 2707 | } |
| 2771 | } else { | 2708 | } else { |
| 2772 | return c.addNode(.{ | 2709 | return c.addNode(.{ |
| 2773 | .tag = .global_var_decl, | 2710 | .tag = .global_var_decl, |
| 2774 | .main_token = mut_tok, | 2711 | .main_token = mut_tok, |
| 2775 | .data = .{ | 2712 | .data = .{ .extra_and_opt_node = .{ |
| 2776 | .lhs = try c.addExtra(std.zig.Ast.Node.GlobalVarDecl{ | 2713 | try c.addExtra(std.zig.Ast.Node.GlobalVarDecl{ |
| 2777 | .type_node = type_node, | 2714 | .type_node = type_node.toOptional(), |
| 2778 | .align_node = align_node, | 2715 | .align_node = .fromOptional(align_node), |
| 2779 | .section_node = section_node, | 2716 | .section_node = .fromOptional(section_node), |
| 2780 | .addrspace_node = 0, | 2717 | .addrspace_node = .none, |
| 2781 | }), | 2718 | }), |
| 2782 | .rhs = init_node, | 2719 | .fromOptional(init_node), |
| 2783 | }, | 2720 | } }, |
| 2784 | }); | 2721 | }); |
| 2785 | } | 2722 | } |
| 2786 | } | 2723 | } |
| ... | @@ -2809,7 +2746,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { | ... | @@ -2809,7 +2746,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { |
| 2809 | }); | 2746 | }); |
| 2810 | _ = try c.addToken(.r_paren, ")"); | 2747 | _ = try c.addToken(.r_paren, ")"); |
| 2811 | break :blk res; | 2748 | break :blk res; |
| 2812 | } else 0; | 2749 | } else null; |
| 2813 | 2750 | ||
| 2814 | const section_expr = if (payload.linksection_string) |some| blk: { | 2751 | const section_expr = if (payload.linksection_string) |some| blk: { |
| 2815 | _ = try c.addToken(.keyword_linksection, "linksection"); | 2752 | _ = try c.addToken(.keyword_linksection, "linksection"); |
| ... | @@ -2821,7 +2758,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { | ... | @@ -2821,7 +2758,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { |
| 2821 | }); | 2758 | }); |
| 2822 | _ = try c.addToken(.r_paren, ")"); | 2759 | _ = try c.addToken(.r_paren, ")"); |
| 2823 | break :blk res; | 2760 | break :blk res; |
| 2824 | } else 0; | 2761 | } else null; |
| 2825 | 2762 | ||
| 2826 | const callconv_expr = if (payload.explicit_callconv) |some| blk: { | 2763 | const callconv_expr = if (payload.explicit_callconv) |some| blk: { |
| 2827 | _ = try c.addToken(.keyword_callconv, "callconv"); | 2764 | _ = try c.addToken(.keyword_callconv, "callconv"); |
| ... | @@ -2856,48 +2793,52 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { | ... | @@ -2856,48 +2793,52 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { |
| 2856 | const inner_lbrace = try c.addToken(.l_brace, "{"); | 2793 | const inner_lbrace = try c.addToken(.l_brace, "{"); |
| 2857 | _ = try c.addToken(.r_brace, "}"); | 2794 | _ = try c.addToken(.r_brace, "}"); |
| 2858 | _ = try c.addToken(.r_brace, "}"); | 2795 | _ = try c.addToken(.r_brace, "}"); |
| 2796 | const inner_node = try c.addNode(.{ | ||
| 2797 | .tag = .struct_init_dot_two, | ||
| 2798 | .main_token = inner_lbrace, | ||
| 2799 | .data = .{ .opt_node_and_opt_node = .{ | ||
| 2800 | .none, | ||
| 2801 | .none, | ||
| 2802 | } }, | ||
| 2803 | }); | ||
| 2859 | break :cc_node try c.addNode(.{ | 2804 | break :cc_node try c.addNode(.{ |
| 2860 | .tag = .struct_init_dot_two, | 2805 | .tag = .struct_init_dot_two, |
| 2861 | .main_token = outer_lbrace, | 2806 | .main_token = outer_lbrace, |
| 2862 | .data = .{ | 2807 | .data = .{ .opt_node_and_opt_node = .{ |
| 2863 | .lhs = try c.addNode(.{ | 2808 | inner_node.toOptional(), |
| 2864 | .tag = .struct_init_dot_two, | 2809 | .none, |
| 2865 | .main_token = inner_lbrace, | 2810 | } }, |
| 2866 | .data = .{ .lhs = 0, .rhs = 0 }, | ||
| 2867 | }), | ||
| 2868 | .rhs = 0, | ||
| 2869 | }, | ||
| 2870 | }); | 2811 | }); |
| 2871 | }, | 2812 | }, |
| 2872 | }; | 2813 | }; |
| 2873 | _ = try c.addToken(.r_paren, ")"); | 2814 | _ = try c.addToken(.r_paren, ")"); |
| 2874 | break :blk cc_node; | 2815 | break :blk cc_node; |
| 2875 | } else 0; | 2816 | } else null; |
| 2876 | 2817 | ||
| 2877 | const return_type_expr = try renderNode(c, payload.return_type); | 2818 | const return_type_expr = try renderNode(c, payload.return_type); |
| 2878 | 2819 | ||
| 2879 | const fn_proto = try blk: { | 2820 | const fn_proto = try blk: { |
| 2880 | if (align_expr == 0 and section_expr == 0 and callconv_expr == 0) { | 2821 | if (align_expr == null and section_expr == null and callconv_expr == null) { |
| 2881 | if (params.items.len < 2) | 2822 | if (params.items.len < 2) |
| 2882 | break :blk c.addNode(.{ | 2823 | break :blk c.addNode(.{ |
| 2883 | .tag = .fn_proto_simple, | 2824 | .tag = .fn_proto_simple, |
| 2884 | .main_token = fn_token, | 2825 | .main_token = fn_token, |
| 2885 | .data = .{ | 2826 | .data = .{ .opt_node_and_opt_node = .{ |
| 2886 | .lhs = params.items[0], | 2827 | if (params.items.len == 0) .none else params.items[0].toOptional(), |
| 2887 | .rhs = return_type_expr, | 2828 | return_type_expr.toOptional(), |
| 2888 | }, | 2829 | } }, |
| 2889 | }) | 2830 | }) |
| 2890 | else | 2831 | else |
| 2891 | break :blk c.addNode(.{ | 2832 | break :blk c.addNode(.{ |
| 2892 | .tag = .fn_proto_multi, | 2833 | .tag = .fn_proto_multi, |
| 2893 | .main_token = fn_token, | 2834 | .main_token = fn_token, |
| 2894 | .data = .{ | 2835 | .data = .{ .extra_and_opt_node = .{ |
| 2895 | .lhs = try c.addExtra(NodeSubRange{ | 2836 | try c.addExtra(NodeSubRange{ |
| 2896 | .start = span.start, | 2837 | .start = span.start, |
| 2897 | .end = span.end, | 2838 | .end = span.end, |
| 2898 | }), | 2839 | }), |
| 2899 | .rhs = return_type_expr, | 2840 | return_type_expr.toOptional(), |
| 2900 | }, | 2841 | } }, |
| 2901 | }); | 2842 | }); |
| 2902 | } | 2843 | } |
| 2903 | if (params.items.len < 2) | 2844 | if (params.items.len < 2) |
| ... | @@ -2905,14 +2846,16 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { | ... | @@ -2905,14 +2846,16 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { |
| 2905 | .tag = .fn_proto_one, | 2846 | .tag = .fn_proto_one, |
| 2906 | .main_token = fn_token, | 2847 | .main_token = fn_token, |
| 2907 | .data = .{ | 2848 | .data = .{ |
| 2908 | .lhs = try c.addExtra(std.zig.Ast.Node.FnProtoOne{ | 2849 | .extra_and_opt_node = .{ |
| 2909 | .param = params.items[0], | 2850 | try c.addExtra(std.zig.Ast.Node.FnProtoOne{ |
| 2910 | .align_expr = align_expr, | 2851 | .param = if (params.items.len == 0) .none else params.items[0].toOptional(), |
| 2911 | .addrspace_expr = 0, // TODO | 2852 | .align_expr = .fromOptional(align_expr), |
| 2912 | .section_expr = section_expr, | 2853 | .addrspace_expr = .none, // TODO |
| 2913 | .callconv_expr = callconv_expr, | 2854 | .section_expr = .fromOptional(section_expr), |
| 2914 | }), | 2855 | .callconv_expr = .fromOptional(callconv_expr), |
| 2915 | .rhs = return_type_expr, | 2856 | }), |
| 2857 | return_type_expr.toOptional(), | ||
| 2858 | }, | ||
| 2916 | }, | 2859 | }, |
| 2917 | }) | 2860 | }) |
| 2918 | else | 2861 | else |
| ... | @@ -2920,15 +2863,17 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { | ... | @@ -2920,15 +2863,17 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { |
| 2920 | .tag = .fn_proto, | 2863 | .tag = .fn_proto, |
| 2921 | .main_token = fn_token, | 2864 | .main_token = fn_token, |
| 2922 | .data = .{ | 2865 | .data = .{ |
| 2923 | .lhs = try c.addExtra(std.zig.Ast.Node.FnProto{ | 2866 | .extra_and_opt_node = .{ |
| 2924 | .params_start = span.start, | 2867 | try c.addExtra(std.zig.Ast.Node.FnProto{ |
| 2925 | .params_end = span.end, | 2868 | .params_start = span.start, |
| 2926 | .align_expr = align_expr, | 2869 | .params_end = span.end, |
| 2927 | .addrspace_expr = 0, // TODO | 2870 | .align_expr = .fromOptional(align_expr), |
| 2928 | .section_expr = section_expr, | 2871 | .addrspace_expr = .none, // TODO |
| 2929 | .callconv_expr = callconv_expr, | 2872 | .section_expr = .fromOptional(section_expr), |
| 2930 | }), | 2873 | .callconv_expr = .fromOptional(callconv_expr), |
| 2931 | .rhs = return_type_expr, | 2874 | }), |
| 2875 | return_type_expr.toOptional(), | ||
| 2876 | }, | ||
| 2932 | }, | 2877 | }, |
| 2933 | }); | 2878 | }); |
| 2934 | }; | 2879 | }; |
| ... | @@ -2943,10 +2888,10 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { | ... | @@ -2943,10 +2888,10 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { |
| 2943 | return c.addNode(.{ | 2888 | return c.addNode(.{ |
| 2944 | .tag = .fn_decl, | 2889 | .tag = .fn_decl, |
| 2945 | .main_token = fn_token, | 2890 | .main_token = fn_token, |
| 2946 | .data = .{ | 2891 | .data = .{ .node_and_node = .{ |
| 2947 | .lhs = fn_proto, | 2892 | fn_proto, |
| 2948 | .rhs = body, | 2893 | body, |
| 2949 | }, | 2894 | } }, |
| 2950 | }); | 2895 | }); |
| 2951 | } | 2896 | } |
| 2952 | 2897 | ||
| ... | @@ -2959,8 +2904,6 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex { | ... | @@ -2959,8 +2904,6 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex { |
| 2959 | 2904 | ||
| 2960 | const params = try renderParams(c, payload.params, false); | 2905 | const params = try renderParams(c, payload.params, false); |
| 2961 | defer params.deinit(); | 2906 | defer params.deinit(); |
| 2962 | var span: NodeSubRange = undefined; | ||
| 2963 | if (params.items.len > 1) span = try c.listToSpan(params.items); | ||
| 2964 | 2907 | ||
| 2965 | const return_type_expr = try renderNodeGrouped(c, payload.return_type); | 2908 | const return_type_expr = try renderNodeGrouped(c, payload.return_type); |
| 2966 | 2909 | ||
| ... | @@ -2969,38 +2912,39 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex { | ... | @@ -2969,38 +2912,39 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex { |
| 2969 | break :blk try c.addNode(.{ | 2912 | break :blk try c.addNode(.{ |
| 2970 | .tag = .fn_proto_simple, | 2913 | .tag = .fn_proto_simple, |
| 2971 | .main_token = fn_token, | 2914 | .main_token = fn_token, |
| 2972 | .data = .{ | 2915 | .data = .{ .opt_node_and_opt_node = .{ |
| 2973 | .lhs = params.items[0], | 2916 | if (params.items.len == 0) .none else params.items[0].toOptional(), |
| 2974 | .rhs = return_type_expr, | 2917 | return_type_expr.toOptional(), |
| 2975 | }, | 2918 | } }, |
| 2976 | }); | 2919 | }); |
| 2977 | } else { | 2920 | } else { |
| 2921 | const span: NodeSubRange = try c.listToSpan(params.items); | ||
| 2978 | break :blk try c.addNode(.{ | 2922 | break :blk try c.addNode(.{ |
| 2979 | .tag = .fn_proto_multi, | 2923 | .tag = .fn_proto_multi, |
| 2980 | .main_token = fn_token, | 2924 | .main_token = fn_token, |
| 2981 | .data = .{ | 2925 | .data = .{ .extra_and_opt_node = .{ |
| 2982 | .lhs = try c.addExtra(std.zig.Ast.Node.SubRange{ | 2926 | try c.addExtra(std.zig.Ast.Node.SubRange{ |
| 2983 | .start = span.start, | 2927 | .start = span.start, |
| 2984 | .end = span.end, | 2928 | .end = span.end, |
| 2985 | }), | 2929 | }), |
| 2986 | .rhs = return_type_expr, | 2930 | return_type_expr.toOptional(), |
| 2987 | }, | 2931 | } }, |
| 2988 | }); | 2932 | }); |
| 2989 | } | 2933 | } |
| 2990 | }; | 2934 | }; |
| 2991 | return c.addNode(.{ | 2935 | return c.addNode(.{ |
| 2992 | .tag = .fn_decl, | 2936 | .tag = .fn_decl, |
| 2993 | .main_token = fn_token, | 2937 | .main_token = fn_token, |
| 2994 | .data = .{ | 2938 | .data = .{ .node_and_node = .{ |
| 2995 | .lhs = fn_proto, | 2939 | fn_proto, |
| 2996 | .rhs = try renderNode(c, payload.body), | 2940 | try renderNode(c, payload.body), |
| 2997 | }, | 2941 | } }, |
| 2998 | }); | 2942 | }); |
| 2999 | } | 2943 | } |
| 3000 | 2944 | ||
| 3001 | fn renderParams(c: *Context, params: []Payload.Param, is_var_args: bool) !std.ArrayList(NodeIndex) { | 2945 | fn renderParams(c: *Context, params: []Payload.Param, is_var_args: bool) !std.ArrayList(NodeIndex) { |
| 3002 | _ = try c.addToken(.l_paren, "("); | 2946 | _ = try c.addToken(.l_paren, "("); |
| 3003 | var rendered = try std.ArrayList(NodeIndex).initCapacity(c.gpa, @max(params.len, 1)); | 2947 | var rendered = try std.ArrayList(NodeIndex).initCapacity(c.gpa, params.len); |
| 3004 | errdefer rendered.deinit(); | 2948 | errdefer rendered.deinit(); |
| 3005 | 2949 | ||
| 3006 | for (params, 0..) |param, i| { | 2950 | for (params, 0..) |param, i| { |
| ... | @@ -3022,6 +2966,5 @@ fn renderParams(c: *Context, params: []Payload.Param, is_var_args: bool) !std.Ar | ... | @@ -3022,6 +2966,5 @@ fn renderParams(c: *Context, params: []Payload.Param, is_var_args: bool) !std.Ar |
| 3022 | } | 2966 | } |
| 3023 | _ = try c.addToken(.r_paren, ")"); | 2967 | _ = try c.addToken(.r_paren, ")"); |
| 3024 | 2968 | ||
| 3025 | if (rendered.items.len == 0) rendered.appendAssumeCapacity(0); | ||
| 3026 | return rendered; | 2969 | return rendered; |
| 3027 | } | 2970 | } |
lib/compiler/reduce.zig+1-1| ... | @@ -220,7 +220,7 @@ pub fn main() !void { | ... | @@ -220,7 +220,7 @@ pub fn main() !void { |
| 220 | mem.eql(u8, msg, "unused function parameter") or | 220 | mem.eql(u8, msg, "unused function parameter") or |
| 221 | mem.eql(u8, msg, "unused capture")) | 221 | mem.eql(u8, msg, "unused capture")) |
| 222 | { | 222 | { |
| 223 | const ident_token = item.data.token; | 223 | const ident_token = item.data.token.unwrap().?; |
| 224 | try more_fixups.unused_var_decls.put(gpa, ident_token, {}); | 224 | try more_fixups.unused_var_decls.put(gpa, ident_token, {}); |
| 225 | } else { | 225 | } else { |
| 226 | std.debug.print("found other ZIR error: '{s}'\n", .{msg}); | 226 | std.debug.print("found other ZIR error: '{s}'\n", .{msg}); |
lib/compiler/reduce/Walk.zig+144-207| ... | @@ -98,29 +98,26 @@ const ScanDeclsAction = enum { add, remove }; | ... | @@ -98,29 +98,26 @@ const ScanDeclsAction = enum { add, remove }; |
| 98 | fn scanDecls(w: *Walk, members: []const Ast.Node.Index, action: ScanDeclsAction) Error!void { | 98 | fn scanDecls(w: *Walk, members: []const Ast.Node.Index, action: ScanDeclsAction) Error!void { |
| 99 | const ast = w.ast; | 99 | const ast = w.ast; |
| 100 | const gpa = w.gpa; | 100 | const gpa = w.gpa; |
| 101 | const node_tags = ast.nodes.items(.tag); | ||
| 102 | const main_tokens = ast.nodes.items(.main_token); | ||
| 103 | const token_tags = ast.tokens.items(.tag); | ||
| 104 | 101 | ||
| 105 | for (members) |member_node| { | 102 | for (members) |member_node| { |
| 106 | const name_token = switch (node_tags[member_node]) { | 103 | const name_token = switch (ast.nodeTag(member_node)) { |
| 107 | .global_var_decl, | 104 | .global_var_decl, |
| 108 | .local_var_decl, | 105 | .local_var_decl, |
| 109 | .simple_var_decl, | 106 | .simple_var_decl, |
| 110 | .aligned_var_decl, | 107 | .aligned_var_decl, |
| 111 | => main_tokens[member_node] + 1, | 108 | => ast.nodeMainToken(member_node) + 1, |
| 112 | 109 | ||
| 113 | .fn_proto_simple, | 110 | .fn_proto_simple, |
| 114 | .fn_proto_multi, | 111 | .fn_proto_multi, |
| 115 | .fn_proto_one, | 112 | .fn_proto_one, |
| 116 | .fn_proto, | 113 | .fn_proto, |
| 117 | .fn_decl, | 114 | .fn_decl, |
| 118 | => main_tokens[member_node] + 1, | 115 | => ast.nodeMainToken(member_node) + 1, |
| 119 | 116 | ||
| 120 | else => continue, | 117 | else => continue, |
| 121 | }; | 118 | }; |
| 122 | 119 | ||
| 123 | assert(token_tags[name_token] == .identifier); | 120 | assert(ast.tokenTag(name_token) == .identifier); |
| 124 | const name_bytes = ast.tokenSlice(name_token); | 121 | const name_bytes = ast.tokenSlice(name_token); |
| 125 | 122 | ||
| 126 | switch (action) { | 123 | switch (action) { |
| ... | @@ -145,12 +142,10 @@ fn scanDecls(w: *Walk, members: []const Ast.Node.Index, action: ScanDeclsAction) | ... | @@ -145,12 +142,10 @@ fn scanDecls(w: *Walk, members: []const Ast.Node.Index, action: ScanDeclsAction) |
| 145 | 142 | ||
| 146 | fn walkMember(w: *Walk, decl: Ast.Node.Index) Error!void { | 143 | fn walkMember(w: *Walk, decl: Ast.Node.Index) Error!void { |
| 147 | const ast = w.ast; | 144 | const ast = w.ast; |
| 148 | const datas = ast.nodes.items(.data); | 145 | switch (ast.nodeTag(decl)) { |
| 149 | switch (ast.nodes.items(.tag)[decl]) { | ||
| 150 | .fn_decl => { | 146 | .fn_decl => { |
| 151 | const fn_proto = datas[decl].lhs; | 147 | const fn_proto, const body_node = ast.nodeData(decl).node_and_node; |
| 152 | try walkExpression(w, fn_proto); | 148 | try walkExpression(w, fn_proto); |
| 153 | const body_node = datas[decl].rhs; | ||
| 154 | if (!isFnBodyGutted(ast, body_node)) { | 149 | if (!isFnBodyGutted(ast, body_node)) { |
| 155 | w.replace_names.clearRetainingCapacity(); | 150 | w.replace_names.clearRetainingCapacity(); |
| 156 | try w.transformations.append(.{ .gut_function = decl }); | 151 | try w.transformations.append(.{ .gut_function = decl }); |
| ... | @@ -167,7 +162,7 @@ fn walkMember(w: *Walk, decl: Ast.Node.Index) Error!void { | ... | @@ -167,7 +162,7 @@ fn walkMember(w: *Walk, decl: Ast.Node.Index) Error!void { |
| 167 | 162 | ||
| 168 | .@"usingnamespace" => { | 163 | .@"usingnamespace" => { |
| 169 | try w.transformations.append(.{ .delete_node = decl }); | 164 | try w.transformations.append(.{ .delete_node = decl }); |
| 170 | const expr = datas[decl].lhs; | 165 | const expr = ast.nodeData(decl).node; |
| 171 | try walkExpression(w, expr); | 166 | try walkExpression(w, expr); |
| 172 | }, | 167 | }, |
| 173 | 168 | ||
| ... | @@ -179,7 +174,7 @@ fn walkMember(w: *Walk, decl: Ast.Node.Index) Error!void { | ... | @@ -179,7 +174,7 @@ fn walkMember(w: *Walk, decl: Ast.Node.Index) Error!void { |
| 179 | 174 | ||
| 180 | .test_decl => { | 175 | .test_decl => { |
| 181 | try w.transformations.append(.{ .delete_node = decl }); | 176 | try w.transformations.append(.{ .delete_node = decl }); |
| 182 | try walkExpression(w, datas[decl].rhs); | 177 | try walkExpression(w, ast.nodeData(decl).opt_token_and_node[1]); |
| 183 | }, | 178 | }, |
| 184 | 179 | ||
| 185 | .container_field_init, | 180 | .container_field_init, |
| ... | @@ -202,14 +197,10 @@ fn walkMember(w: *Walk, decl: Ast.Node.Index) Error!void { | ... | @@ -202,14 +197,10 @@ fn walkMember(w: *Walk, decl: Ast.Node.Index) Error!void { |
| 202 | 197 | ||
| 203 | fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | 198 | fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 204 | const ast = w.ast; | 199 | const ast = w.ast; |
| 205 | const token_tags = ast.tokens.items(.tag); | 200 | switch (ast.nodeTag(node)) { |
| 206 | const main_tokens = ast.nodes.items(.main_token); | ||
| 207 | const node_tags = ast.nodes.items(.tag); | ||
| 208 | const datas = ast.nodes.items(.data); | ||
| 209 | switch (node_tags[node]) { | ||
| 210 | .identifier => { | 201 | .identifier => { |
| 211 | const name_ident = main_tokens[node]; | 202 | const name_ident = ast.nodeMainToken(node); |
| 212 | assert(token_tags[name_ident] == .identifier); | 203 | assert(ast.tokenTag(name_ident) == .identifier); |
| 213 | const name_bytes = ast.tokenSlice(name_ident); | 204 | const name_bytes = ast.tokenSlice(name_ident); |
| 214 | _ = w.unreferenced_globals.swapRemove(name_bytes); | 205 | _ = w.unreferenced_globals.swapRemove(name_bytes); |
| 215 | if (w.replace_names.get(name_bytes)) |index| { | 206 | if (w.replace_names.get(name_bytes)) |index| { |
| ... | @@ -239,46 +230,27 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -239,46 +230,27 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 239 | }, | 230 | }, |
| 240 | 231 | ||
| 241 | .@"errdefer" => { | 232 | .@"errdefer" => { |
| 242 | const expr = datas[node].rhs; | 233 | const expr = ast.nodeData(node).opt_token_and_node[1]; |
| 243 | return walkExpression(w, expr); | 234 | return walkExpression(w, expr); |
| 244 | }, | 235 | }, |
| 245 | 236 | ||
| 246 | .@"defer" => { | 237 | .@"defer", |
| 247 | const expr = datas[node].rhs; | 238 | .@"comptime", |
| 248 | return walkExpression(w, expr); | 239 | .@"nosuspend", |
| 249 | }, | 240 | .@"suspend", |
| 250 | .@"comptime", .@"nosuspend" => { | 241 | => { |
| 251 | const block = datas[node].lhs; | 242 | return walkExpression(w, ast.nodeData(node).node); |
| 252 | return walkExpression(w, block); | ||
| 253 | }, | ||
| 254 | |||
| 255 | .@"suspend" => { | ||
| 256 | const body = datas[node].lhs; | ||
| 257 | return walkExpression(w, body); | ||
| 258 | }, | ||
| 259 | |||
| 260 | .@"catch" => { | ||
| 261 | try walkExpression(w, datas[node].lhs); // target | ||
| 262 | try walkExpression(w, datas[node].rhs); // fallback | ||
| 263 | }, | 243 | }, |
| 264 | 244 | ||
| 265 | .field_access => { | 245 | .field_access => { |
| 266 | const field_access = datas[node]; | 246 | try walkExpression(w, ast.nodeData(node).node_and_token[0]); |
| 267 | try walkExpression(w, field_access.lhs); | ||
| 268 | }, | 247 | }, |
| 269 | 248 | ||
| 270 | .error_union, | ||
| 271 | .switch_range, | ||
| 272 | => { | ||
| 273 | const infix = datas[node]; | ||
| 274 | try walkExpression(w, infix.lhs); | ||
| 275 | return walkExpression(w, infix.rhs); | ||
| 276 | }, | ||
| 277 | .for_range => { | 249 | .for_range => { |
| 278 | const infix = datas[node]; | 250 | const start, const opt_end = ast.nodeData(node).node_and_opt_node; |
| 279 | try walkExpression(w, infix.lhs); | 251 | try walkExpression(w, start); |
| 280 | if (infix.rhs != 0) { | 252 | if (opt_end.unwrap()) |end| { |
| 281 | return walkExpression(w, infix.rhs); | 253 | return walkExpression(w, end); |
| 282 | } | 254 | } |
| 283 | }, | 255 | }, |
| 284 | 256 | ||
| ... | @@ -328,17 +300,21 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -328,17 +300,21 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 328 | .sub, | 300 | .sub, |
| 329 | .sub_wrap, | 301 | .sub_wrap, |
| 330 | .sub_sat, | 302 | .sub_sat, |
| 303 | .@"catch", | ||
| 304 | .error_union, | ||
| 305 | .switch_range, | ||
| 331 | .@"orelse", | 306 | .@"orelse", |
| 307 | .array_access, | ||
| 332 | => { | 308 | => { |
| 333 | const infix = datas[node]; | 309 | const lhs, const rhs = ast.nodeData(node).node_and_node; |
| 334 | try walkExpression(w, infix.lhs); | 310 | try walkExpression(w, lhs); |
| 335 | try walkExpression(w, infix.rhs); | 311 | try walkExpression(w, rhs); |
| 336 | }, | 312 | }, |
| 337 | 313 | ||
| 338 | .assign_destructure => { | 314 | .assign_destructure => { |
| 339 | const full = ast.assignDestructure(node); | 315 | const full = ast.assignDestructure(node); |
| 340 | for (full.ast.variables) |variable_node| { | 316 | for (full.ast.variables) |variable_node| { |
| 341 | switch (node_tags[variable_node]) { | 317 | switch (ast.nodeTag(variable_node)) { |
| 342 | .global_var_decl, | 318 | .global_var_decl, |
| 343 | .local_var_decl, | 319 | .local_var_decl, |
| 344 | .simple_var_decl, | 320 | .simple_var_decl, |
| ... | @@ -357,15 +333,12 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -357,15 +333,12 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 357 | .negation_wrap, | 333 | .negation_wrap, |
| 358 | .optional_type, | 334 | .optional_type, |
| 359 | .address_of, | 335 | .address_of, |
| 360 | => { | ||
| 361 | return walkExpression(w, datas[node].lhs); | ||
| 362 | }, | ||
| 363 | |||
| 364 | .@"try", | 336 | .@"try", |
| 365 | .@"resume", | 337 | .@"resume", |
| 366 | .@"await", | 338 | .@"await", |
| 339 | .deref, | ||
| 367 | => { | 340 | => { |
| 368 | return walkExpression(w, datas[node].lhs); | 341 | return walkExpression(w, ast.nodeData(node).node); |
| 369 | }, | 342 | }, |
| 370 | 343 | ||
| 371 | .array_type, | 344 | .array_type, |
| ... | @@ -417,51 +390,40 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -417,51 +390,40 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 417 | return walkCall(w, ast.fullCall(&buf, node).?); | 390 | return walkCall(w, ast.fullCall(&buf, node).?); |
| 418 | }, | 391 | }, |
| 419 | 392 | ||
| 420 | .array_access => { | ||
| 421 | const suffix = datas[node]; | ||
| 422 | try walkExpression(w, suffix.lhs); | ||
| 423 | try walkExpression(w, suffix.rhs); | ||
| 424 | }, | ||
| 425 | |||
| 426 | .slice_open, .slice, .slice_sentinel => return walkSlice(w, node, ast.fullSlice(node).?), | 393 | .slice_open, .slice, .slice_sentinel => return walkSlice(w, node, ast.fullSlice(node).?), |
| 427 | 394 | ||
| 428 | .deref => { | ||
| 429 | try walkExpression(w, datas[node].lhs); | ||
| 430 | }, | ||
| 431 | |||
| 432 | .unwrap_optional => { | 395 | .unwrap_optional => { |
| 433 | try walkExpression(w, datas[node].lhs); | 396 | try walkExpression(w, ast.nodeData(node).node_and_token[0]); |
| 434 | }, | 397 | }, |
| 435 | 398 | ||
| 436 | .@"break" => { | 399 | .@"break" => { |
| 437 | const label_token = datas[node].lhs; | 400 | const label_token, const target = ast.nodeData(node).opt_token_and_opt_node; |
| 438 | const target = datas[node].rhs; | 401 | if (label_token == .none and target == .none) { |
| 439 | if (label_token == 0 and target == 0) { | ||
| 440 | // no expressions | 402 | // no expressions |
| 441 | } else if (label_token == 0 and target != 0) { | 403 | } else if (label_token == .none and target != .none) { |
| 442 | try walkExpression(w, target); | 404 | try walkExpression(w, target.unwrap().?); |
| 443 | } else if (label_token != 0 and target == 0) { | 405 | } else if (label_token != .none and target == .none) { |
| 444 | try walkIdentifier(w, label_token); | 406 | try walkIdentifier(w, label_token.unwrap().?); |
| 445 | } else if (label_token != 0 and target != 0) { | 407 | } else if (label_token != .none and target != .none) { |
| 446 | try walkExpression(w, target); | 408 | try walkExpression(w, target.unwrap().?); |
| 447 | } | 409 | } |
| 448 | }, | 410 | }, |
| 449 | 411 | ||
| 450 | .@"continue" => { | 412 | .@"continue" => { |
| 451 | const label = datas[node].lhs; | 413 | const opt_label = ast.nodeData(node).opt_token_and_opt_node[0]; |
| 452 | if (label != 0) { | 414 | if (opt_label.unwrap()) |label| { |
| 453 | return walkIdentifier(w, label); // label | 415 | return walkIdentifier(w, label); |
| 454 | } | 416 | } |
| 455 | }, | 417 | }, |
| 456 | 418 | ||
| 457 | .@"return" => { | 419 | .@"return" => { |
| 458 | if (datas[node].lhs != 0) { | 420 | if (ast.nodeData(node).opt_node.unwrap()) |lhs| { |
| 459 | try walkExpression(w, datas[node].lhs); | 421 | try walkExpression(w, lhs); |
| 460 | } | 422 | } |
| 461 | }, | 423 | }, |
| 462 | 424 | ||
| 463 | .grouped_expression => { | 425 | .grouped_expression => { |
| 464 | try walkExpression(w, datas[node].lhs); | 426 | try walkExpression(w, ast.nodeData(node).node_and_token[0]); |
| 465 | }, | 427 | }, |
| 466 | 428 | ||
| 467 | .container_decl, | 429 | .container_decl, |
| ... | @@ -482,13 +444,13 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -482,13 +444,13 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 482 | }, | 444 | }, |
| 483 | 445 | ||
| 484 | .error_set_decl => { | 446 | .error_set_decl => { |
| 485 | const error_token = main_tokens[node]; | 447 | const error_token = ast.nodeMainToken(node); |
| 486 | const lbrace = error_token + 1; | 448 | const lbrace = error_token + 1; |
| 487 | const rbrace = datas[node].rhs; | 449 | const rbrace = ast.nodeData(node).token; |
| 488 | 450 | ||
| 489 | var i = lbrace + 1; | 451 | var i = lbrace + 1; |
| 490 | while (i < rbrace) : (i += 1) { | 452 | while (i < rbrace) : (i += 1) { |
| 491 | switch (token_tags[i]) { | 453 | switch (ast.tokenTag(i)) { |
| 492 | .doc_comment => unreachable, // TODO | 454 | .doc_comment => unreachable, // TODO |
| 493 | .identifier => try walkIdentifier(w, i), | 455 | .identifier => try walkIdentifier(w, i), |
| 494 | .comma => {}, | 456 | .comma => {}, |
| ... | @@ -517,20 +479,16 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -517,20 +479,16 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 517 | }, | 479 | }, |
| 518 | 480 | ||
| 519 | .anyframe_type => { | 481 | .anyframe_type => { |
| 520 | if (datas[node].rhs != 0) { | 482 | _, const child_type = ast.nodeData(node).token_and_node; |
| 521 | return walkExpression(w, datas[node].rhs); | 483 | return walkExpression(w, child_type); |
| 522 | } | ||
| 523 | }, | 484 | }, |
| 524 | 485 | ||
| 525 | .@"switch", | 486 | .@"switch", |
| 526 | .switch_comma, | 487 | .switch_comma, |
| 527 | => { | 488 | => { |
| 528 | const condition = datas[node].lhs; | 489 | const full = ast.fullSwitch(node).?; |
| 529 | const extra = ast.extraData(datas[node].rhs, Ast.Node.SubRange); | 490 | try walkExpression(w, full.ast.condition); // condition expression |
| 530 | const cases = ast.extra_data[extra.start..extra.end]; | 491 | try walkExpressions(w, full.ast.cases); |
| 531 | |||
| 532 | try walkExpression(w, condition); // condition expression | ||
| 533 | try walkExpressions(w, cases); | ||
| 534 | }, | 492 | }, |
| 535 | 493 | ||
| 536 | .switch_case_one, | 494 | .switch_case_one, |
| ... | @@ -557,7 +515,7 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -557,7 +515,7 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 557 | => return walkAsm(w, ast.fullAsm(node).?), | 515 | => return walkAsm(w, ast.fullAsm(node).?), |
| 558 | 516 | ||
| 559 | .enum_literal => { | 517 | .enum_literal => { |
| 560 | return walkIdentifier(w, main_tokens[node]); // name | 518 | return walkIdentifier(w, ast.nodeMainToken(node)); // name |
| 561 | }, | 519 | }, |
| 562 | 520 | ||
| 563 | .fn_decl => unreachable, | 521 | .fn_decl => unreachable, |
| ... | @@ -579,66 +537,66 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -579,66 +537,66 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 579 | fn walkGlobalVarDecl(w: *Walk, decl_node: Ast.Node.Index, var_decl: Ast.full.VarDecl) Error!void { | 537 | fn walkGlobalVarDecl(w: *Walk, decl_node: Ast.Node.Index, var_decl: Ast.full.VarDecl) Error!void { |
| 580 | _ = decl_node; | 538 | _ = decl_node; |
| 581 | 539 | ||
| 582 | if (var_decl.ast.type_node != 0) { | 540 | if (var_decl.ast.type_node.unwrap()) |type_node| { |
| 583 | try walkExpression(w, var_decl.ast.type_node); | 541 | try walkExpression(w, type_node); |
| 584 | } | 542 | } |
| 585 | 543 | ||
| 586 | if (var_decl.ast.align_node != 0) { | 544 | if (var_decl.ast.align_node.unwrap()) |align_node| { |
| 587 | try walkExpression(w, var_decl.ast.align_node); | 545 | try walkExpression(w, align_node); |
| 588 | } | 546 | } |
| 589 | 547 | ||
| 590 | if (var_decl.ast.addrspace_node != 0) { | 548 | if (var_decl.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 591 | try walkExpression(w, var_decl.ast.addrspace_node); | 549 | try walkExpression(w, addrspace_node); |
| 592 | } | 550 | } |
| 593 | 551 | ||
| 594 | if (var_decl.ast.section_node != 0) { | 552 | if (var_decl.ast.section_node.unwrap()) |section_node| { |
| 595 | try walkExpression(w, var_decl.ast.section_node); | 553 | try walkExpression(w, section_node); |
| 596 | } | 554 | } |
| 597 | 555 | ||
| 598 | if (var_decl.ast.init_node != 0) { | 556 | if (var_decl.ast.init_node.unwrap()) |init_node| { |
| 599 | if (!isUndefinedIdent(w.ast, var_decl.ast.init_node)) { | 557 | if (!isUndefinedIdent(w.ast, init_node)) { |
| 600 | try w.transformations.append(.{ .replace_with_undef = var_decl.ast.init_node }); | 558 | try w.transformations.append(.{ .replace_with_undef = init_node }); |
| 601 | } | 559 | } |
| 602 | try walkExpression(w, var_decl.ast.init_node); | 560 | try walkExpression(w, init_node); |
| 603 | } | 561 | } |
| 604 | } | 562 | } |
| 605 | 563 | ||
| 606 | fn walkLocalVarDecl(w: *Walk, var_decl: Ast.full.VarDecl) Error!void { | 564 | fn walkLocalVarDecl(w: *Walk, var_decl: Ast.full.VarDecl) Error!void { |
| 607 | try walkIdentifierNew(w, var_decl.ast.mut_token + 1); // name | 565 | try walkIdentifierNew(w, var_decl.ast.mut_token + 1); // name |
| 608 | 566 | ||
| 609 | if (var_decl.ast.type_node != 0) { | 567 | if (var_decl.ast.type_node.unwrap()) |type_node| { |
| 610 | try walkExpression(w, var_decl.ast.type_node); | 568 | try walkExpression(w, type_node); |
| 611 | } | 569 | } |
| 612 | 570 | ||
| 613 | if (var_decl.ast.align_node != 0) { | 571 | if (var_decl.ast.align_node.unwrap()) |align_node| { |
| 614 | try walkExpression(w, var_decl.ast.align_node); | 572 | try walkExpression(w, align_node); |
| 615 | } | 573 | } |
| 616 | 574 | ||
| 617 | if (var_decl.ast.addrspace_node != 0) { | 575 | if (var_decl.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 618 | try walkExpression(w, var_decl.ast.addrspace_node); | 576 | try walkExpression(w, addrspace_node); |
| 619 | } | 577 | } |
| 620 | 578 | ||
| 621 | if (var_decl.ast.section_node != 0) { | 579 | if (var_decl.ast.section_node.unwrap()) |section_node| { |
| 622 | try walkExpression(w, var_decl.ast.section_node); | 580 | try walkExpression(w, section_node); |
| 623 | } | 581 | } |
| 624 | 582 | ||
| 625 | if (var_decl.ast.init_node != 0) { | 583 | if (var_decl.ast.init_node.unwrap()) |init_node| { |
| 626 | if (!isUndefinedIdent(w.ast, var_decl.ast.init_node)) { | 584 | if (!isUndefinedIdent(w.ast, init_node)) { |
| 627 | try w.transformations.append(.{ .replace_with_undef = var_decl.ast.init_node }); | 585 | try w.transformations.append(.{ .replace_with_undef = init_node }); |
| 628 | } | 586 | } |
| 629 | try walkExpression(w, var_decl.ast.init_node); | 587 | try walkExpression(w, init_node); |
| 630 | } | 588 | } |
| 631 | } | 589 | } |
| 632 | 590 | ||
| 633 | fn walkContainerField(w: *Walk, field: Ast.full.ContainerField) Error!void { | 591 | fn walkContainerField(w: *Walk, field: Ast.full.ContainerField) Error!void { |
| 634 | if (field.ast.type_expr != 0) { | 592 | if (field.ast.type_expr.unwrap()) |type_expr| { |
| 635 | try walkExpression(w, field.ast.type_expr); // type | 593 | try walkExpression(w, type_expr); // type |
| 636 | } | 594 | } |
| 637 | if (field.ast.align_expr != 0) { | 595 | if (field.ast.align_expr.unwrap()) |align_expr| { |
| 638 | try walkExpression(w, field.ast.align_expr); // alignment | 596 | try walkExpression(w, align_expr); // alignment |
| 639 | } | 597 | } |
| 640 | if (field.ast.value_expr != 0) { | 598 | if (field.ast.value_expr.unwrap()) |value_expr| { |
| 641 | try walkExpression(w, field.ast.value_expr); // value | 599 | try walkExpression(w, value_expr); // value |
| 642 | } | 600 | } |
| 643 | } | 601 | } |
| 644 | 602 | ||
| ... | @@ -649,18 +607,17 @@ fn walkBlock( | ... | @@ -649,18 +607,17 @@ fn walkBlock( |
| 649 | ) Error!void { | 607 | ) Error!void { |
| 650 | _ = block_node; | 608 | _ = block_node; |
| 651 | const ast = w.ast; | 609 | const ast = w.ast; |
| 652 | const node_tags = ast.nodes.items(.tag); | ||
| 653 | 610 | ||
| 654 | for (statements) |stmt| { | 611 | for (statements) |stmt| { |
| 655 | switch (node_tags[stmt]) { | 612 | switch (ast.nodeTag(stmt)) { |
| 656 | .global_var_decl, | 613 | .global_var_decl, |
| 657 | .local_var_decl, | 614 | .local_var_decl, |
| 658 | .simple_var_decl, | 615 | .simple_var_decl, |
| 659 | .aligned_var_decl, | 616 | .aligned_var_decl, |
| 660 | => { | 617 | => { |
| 661 | const var_decl = ast.fullVarDecl(stmt).?; | 618 | const var_decl = ast.fullVarDecl(stmt).?; |
| 662 | if (var_decl.ast.init_node != 0 and | 619 | if (var_decl.ast.init_node != .none and |
| 663 | isUndefinedIdent(w.ast, var_decl.ast.init_node)) | 620 | isUndefinedIdent(w.ast, var_decl.ast.init_node.unwrap().?)) |
| 664 | { | 621 | { |
| 665 | try w.transformations.append(.{ .delete_var_decl = .{ | 622 | try w.transformations.append(.{ .delete_var_decl = .{ |
| 666 | .var_decl_node = stmt, | 623 | .var_decl_node = stmt, |
| ... | @@ -691,15 +648,15 @@ fn walkBlock( | ... | @@ -691,15 +648,15 @@ fn walkBlock( |
| 691 | 648 | ||
| 692 | fn walkArrayType(w: *Walk, array_type: Ast.full.ArrayType) Error!void { | 649 | fn walkArrayType(w: *Walk, array_type: Ast.full.ArrayType) Error!void { |
| 693 | try walkExpression(w, array_type.ast.elem_count); | 650 | try walkExpression(w, array_type.ast.elem_count); |
| 694 | if (array_type.ast.sentinel != 0) { | 651 | if (array_type.ast.sentinel.unwrap()) |sentinel| { |
| 695 | try walkExpression(w, array_type.ast.sentinel); | 652 | try walkExpression(w, sentinel); |
| 696 | } | 653 | } |
| 697 | return walkExpression(w, array_type.ast.elem_type); | 654 | return walkExpression(w, array_type.ast.elem_type); |
| 698 | } | 655 | } |
| 699 | 656 | ||
| 700 | fn walkArrayInit(w: *Walk, array_init: Ast.full.ArrayInit) Error!void { | 657 | fn walkArrayInit(w: *Walk, array_init: Ast.full.ArrayInit) Error!void { |
| 701 | if (array_init.ast.type_expr != 0) { | 658 | if (array_init.ast.type_expr.unwrap()) |type_expr| { |
| 702 | try walkExpression(w, array_init.ast.type_expr); // T | 659 | try walkExpression(w, type_expr); // T |
| 703 | } | 660 | } |
| 704 | for (array_init.ast.elements) |elem_init| { | 661 | for (array_init.ast.elements) |elem_init| { |
| 705 | try walkExpression(w, elem_init); | 662 | try walkExpression(w, elem_init); |
| ... | @@ -712,8 +669,8 @@ fn walkStructInit( | ... | @@ -712,8 +669,8 @@ fn walkStructInit( |
| 712 | struct_init: Ast.full.StructInit, | 669 | struct_init: Ast.full.StructInit, |
| 713 | ) Error!void { | 670 | ) Error!void { |
| 714 | _ = struct_node; | 671 | _ = struct_node; |
| 715 | if (struct_init.ast.type_expr != 0) { | 672 | if (struct_init.ast.type_expr.unwrap()) |type_expr| { |
| 716 | try walkExpression(w, struct_init.ast.type_expr); // T | 673 | try walkExpression(w, type_expr); // T |
| 717 | } | 674 | } |
| 718 | for (struct_init.ast.fields) |field_init| { | 675 | for (struct_init.ast.fields) |field_init| { |
| 719 | try walkExpression(w, field_init); | 676 | try walkExpression(w, field_init); |
| ... | @@ -733,18 +690,17 @@ fn walkSlice( | ... | @@ -733,18 +690,17 @@ fn walkSlice( |
| 733 | _ = slice_node; | 690 | _ = slice_node; |
| 734 | try walkExpression(w, slice.ast.sliced); | 691 | try walkExpression(w, slice.ast.sliced); |
| 735 | try walkExpression(w, slice.ast.start); | 692 | try walkExpression(w, slice.ast.start); |
| 736 | if (slice.ast.end != 0) { | 693 | if (slice.ast.end.unwrap()) |end| { |
| 737 | try walkExpression(w, slice.ast.end); | 694 | try walkExpression(w, end); |
| 738 | } | 695 | } |
| 739 | if (slice.ast.sentinel != 0) { | 696 | if (slice.ast.sentinel.unwrap()) |sentinel| { |
| 740 | try walkExpression(w, slice.ast.sentinel); | 697 | try walkExpression(w, sentinel); |
| 741 | } | 698 | } |
| 742 | } | 699 | } |
| 743 | 700 | ||
| 744 | fn walkIdentifier(w: *Walk, name_ident: Ast.TokenIndex) Error!void { | 701 | fn walkIdentifier(w: *Walk, name_ident: Ast.TokenIndex) Error!void { |
| 745 | const ast = w.ast; | 702 | const ast = w.ast; |
| 746 | const token_tags = ast.tokens.items(.tag); | 703 | assert(ast.tokenTag(name_ident) == .identifier); |
| 747 | assert(token_tags[name_ident] == .identifier); | ||
| 748 | const name_bytes = ast.tokenSlice(name_ident); | 704 | const name_bytes = ast.tokenSlice(name_ident); |
| 749 | _ = w.unreferenced_globals.swapRemove(name_bytes); | 705 | _ = w.unreferenced_globals.swapRemove(name_bytes); |
| 750 | } | 706 | } |
| ... | @@ -760,8 +716,8 @@ fn walkContainerDecl( | ... | @@ -760,8 +716,8 @@ fn walkContainerDecl( |
| 760 | container_decl: Ast.full.ContainerDecl, | 716 | container_decl: Ast.full.ContainerDecl, |
| 761 | ) Error!void { | 717 | ) Error!void { |
| 762 | _ = container_decl_node; | 718 | _ = container_decl_node; |
| 763 | if (container_decl.ast.arg != 0) { | 719 | if (container_decl.ast.arg.unwrap()) |arg| { |
| 764 | try walkExpression(w, container_decl.ast.arg); | 720 | try walkExpression(w, arg); |
| 765 | } | 721 | } |
| 766 | try walkMembers(w, container_decl.ast.members); | 722 | try walkMembers(w, container_decl.ast.members); |
| 767 | } | 723 | } |
| ... | @@ -772,14 +728,13 @@ fn walkBuiltinCall( | ... | @@ -772,14 +728,13 @@ fn walkBuiltinCall( |
| 772 | params: []const Ast.Node.Index, | 728 | params: []const Ast.Node.Index, |
| 773 | ) Error!void { | 729 | ) Error!void { |
| 774 | const ast = w.ast; | 730 | const ast = w.ast; |
| 775 | const main_tokens = ast.nodes.items(.main_token); | 731 | const builtin_token = ast.nodeMainToken(call_node); |
| 776 | const builtin_token = main_tokens[call_node]; | ||
| 777 | const builtin_name = ast.tokenSlice(builtin_token); | 732 | const builtin_name = ast.tokenSlice(builtin_token); |
| 778 | const info = BuiltinFn.list.get(builtin_name).?; | 733 | const info = BuiltinFn.list.get(builtin_name).?; |
| 779 | switch (info.tag) { | 734 | switch (info.tag) { |
| 780 | .import => { | 735 | .import => { |
| 781 | const operand_node = params[0]; | 736 | const operand_node = params[0]; |
| 782 | const str_lit_token = main_tokens[operand_node]; | 737 | const str_lit_token = ast.nodeMainToken(operand_node); |
| 783 | const token_bytes = ast.tokenSlice(str_lit_token); | 738 | const token_bytes = ast.tokenSlice(str_lit_token); |
| 784 | if (std.mem.endsWith(u8, token_bytes, ".zig\"")) { | 739 | if (std.mem.endsWith(u8, token_bytes, ".zig\"")) { |
| 785 | const imported_string = std.zig.string_literal.parseAlloc(w.arena, token_bytes) catch | 740 | const imported_string = std.zig.string_literal.parseAlloc(w.arena, token_bytes) catch |
| ... | @@ -808,29 +763,30 @@ fn walkFnProto(w: *Walk, fn_proto: Ast.full.FnProto) Error!void { | ... | @@ -808,29 +763,30 @@ fn walkFnProto(w: *Walk, fn_proto: Ast.full.FnProto) Error!void { |
| 808 | { | 763 | { |
| 809 | var it = fn_proto.iterate(ast); | 764 | var it = fn_proto.iterate(ast); |
| 810 | while (it.next()) |param| { | 765 | while (it.next()) |param| { |
| 811 | if (param.type_expr != 0) { | 766 | if (param.type_expr) |type_expr| { |
| 812 | try walkExpression(w, param.type_expr); | 767 | try walkExpression(w, type_expr); |
| 813 | } | 768 | } |
| 814 | } | 769 | } |
| 815 | } | 770 | } |
| 816 | 771 | ||
| 817 | if (fn_proto.ast.align_expr != 0) { | 772 | if (fn_proto.ast.align_expr.unwrap()) |align_expr| { |
| 818 | try walkExpression(w, fn_proto.ast.align_expr); | 773 | try walkExpression(w, align_expr); |
| 819 | } | 774 | } |
| 820 | 775 | ||
| 821 | if (fn_proto.ast.addrspace_expr != 0) { | 776 | if (fn_proto.ast.addrspace_expr.unwrap()) |addrspace_expr| { |
| 822 | try walkExpression(w, fn_proto.ast.addrspace_expr); | 777 | try walkExpression(w, addrspace_expr); |
| 823 | } | 778 | } |
| 824 | 779 | ||
| 825 | if (fn_proto.ast.section_expr != 0) { | 780 | if (fn_proto.ast.section_expr.unwrap()) |section_expr| { |
| 826 | try walkExpression(w, fn_proto.ast.section_expr); | 781 | try walkExpression(w, section_expr); |
| 827 | } | 782 | } |
| 828 | 783 | ||
| 829 | if (fn_proto.ast.callconv_expr != 0) { | 784 | if (fn_proto.ast.callconv_expr.unwrap()) |callconv_expr| { |
| 830 | try walkExpression(w, fn_proto.ast.callconv_expr); | 785 | try walkExpression(w, callconv_expr); |
| 831 | } | 786 | } |
| 832 | 787 | ||
| 833 | try walkExpression(w, fn_proto.ast.return_type); | 788 | const return_type = fn_proto.ast.return_type.unwrap().?; |
| 789 | try walkExpression(w, return_type); | ||
| 834 | } | 790 | } |
| 835 | 791 | ||
| 836 | fn walkExpressions(w: *Walk, expressions: []const Ast.Node.Index) Error!void { | 792 | fn walkExpressions(w: *Walk, expressions: []const Ast.Node.Index) Error!void { |
| ... | @@ -847,16 +803,13 @@ fn walkSwitchCase(w: *Walk, switch_case: Ast.full.SwitchCase) Error!void { | ... | @@ -847,16 +803,13 @@ fn walkSwitchCase(w: *Walk, switch_case: Ast.full.SwitchCase) Error!void { |
| 847 | } | 803 | } |
| 848 | 804 | ||
| 849 | fn walkWhile(w: *Walk, node_index: Ast.Node.Index, while_node: Ast.full.While) Error!void { | 805 | fn walkWhile(w: *Walk, node_index: Ast.Node.Index, while_node: Ast.full.While) Error!void { |
| 850 | assert(while_node.ast.cond_expr != 0); | ||
| 851 | assert(while_node.ast.then_expr != 0); | ||
| 852 | |||
| 853 | // Perform these transformations in this priority order: | 806 | // Perform these transformations in this priority order: |
| 854 | // 1. If the `else` expression is missing or an empty block, replace the condition with `if (true)` if it is not already. | 807 | // 1. If the `else` expression is missing or an empty block, replace the condition with `if (true)` if it is not already. |
| 855 | // 2. If the `then` block is empty, replace the condition with `if (false)` if it is not already. | 808 | // 2. If the `then` block is empty, replace the condition with `if (false)` if it is not already. |
| 856 | // 3. If the condition is `if (true)`, replace the `if` expression with the contents of the `then` expression. | 809 | // 3. If the condition is `if (true)`, replace the `if` expression with the contents of the `then` expression. |
| 857 | // 4. If the condition is `if (false)`, replace the `if` expression with the contents of the `else` expression. | 810 | // 4. If the condition is `if (false)`, replace the `if` expression with the contents of the `else` expression. |
| 858 | if (!isTrueIdent(w.ast, while_node.ast.cond_expr) and | 811 | if (!isTrueIdent(w.ast, while_node.ast.cond_expr) and |
| 859 | (while_node.ast.else_expr == 0 or isEmptyBlock(w.ast, while_node.ast.else_expr))) | 812 | (while_node.ast.else_expr == .none or isEmptyBlock(w.ast, while_node.ast.else_expr.unwrap().?))) |
| 860 | { | 813 | { |
| 861 | try w.transformations.ensureUnusedCapacity(1); | 814 | try w.transformations.ensureUnusedCapacity(1); |
| 862 | w.transformations.appendAssumeCapacity(.{ .replace_with_true = while_node.ast.cond_expr }); | 815 | w.transformations.appendAssumeCapacity(.{ .replace_with_true = while_node.ast.cond_expr }); |
| ... | @@ -873,45 +826,39 @@ fn walkWhile(w: *Walk, node_index: Ast.Node.Index, while_node: Ast.full.While) E | ... | @@ -873,45 +826,39 @@ fn walkWhile(w: *Walk, node_index: Ast.Node.Index, while_node: Ast.full.While) E |
| 873 | try w.transformations.ensureUnusedCapacity(1); | 826 | try w.transformations.ensureUnusedCapacity(1); |
| 874 | w.transformations.appendAssumeCapacity(.{ .replace_node = .{ | 827 | w.transformations.appendAssumeCapacity(.{ .replace_node = .{ |
| 875 | .to_replace = node_index, | 828 | .to_replace = node_index, |
| 876 | .replacement = while_node.ast.else_expr, | 829 | .replacement = while_node.ast.else_expr.unwrap().?, |
| 877 | } }); | 830 | } }); |
| 878 | } | 831 | } |
| 879 | 832 | ||
| 880 | try walkExpression(w, while_node.ast.cond_expr); // condition | 833 | try walkExpression(w, while_node.ast.cond_expr); // condition |
| 881 | 834 | ||
| 882 | if (while_node.ast.cont_expr != 0) { | 835 | if (while_node.ast.cont_expr.unwrap()) |cont_expr| { |
| 883 | try walkExpression(w, while_node.ast.cont_expr); | 836 | try walkExpression(w, cont_expr); |
| 884 | } | 837 | } |
| 885 | 838 | ||
| 886 | if (while_node.ast.then_expr != 0) { | 839 | try walkExpression(w, while_node.ast.then_expr); |
| 887 | try walkExpression(w, while_node.ast.then_expr); | 840 | |
| 888 | } | 841 | if (while_node.ast.else_expr.unwrap()) |else_expr| { |
| 889 | if (while_node.ast.else_expr != 0) { | 842 | try walkExpression(w, else_expr); |
| 890 | try walkExpression(w, while_node.ast.else_expr); | ||
| 891 | } | 843 | } |
| 892 | } | 844 | } |
| 893 | 845 | ||
| 894 | fn walkFor(w: *Walk, for_node: Ast.full.For) Error!void { | 846 | fn walkFor(w: *Walk, for_node: Ast.full.For) Error!void { |
| 895 | try walkParamList(w, for_node.ast.inputs); | 847 | try walkParamList(w, for_node.ast.inputs); |
| 896 | if (for_node.ast.then_expr != 0) { | 848 | try walkExpression(w, for_node.ast.then_expr); |
| 897 | try walkExpression(w, for_node.ast.then_expr); | 849 | if (for_node.ast.else_expr.unwrap()) |else_expr| { |
| 898 | } | 850 | try walkExpression(w, else_expr); |
| 899 | if (for_node.ast.else_expr != 0) { | ||
| 900 | try walkExpression(w, for_node.ast.else_expr); | ||
| 901 | } | 851 | } |
| 902 | } | 852 | } |
| 903 | 853 | ||
| 904 | fn walkIf(w: *Walk, node_index: Ast.Node.Index, if_node: Ast.full.If) Error!void { | 854 | fn walkIf(w: *Walk, node_index: Ast.Node.Index, if_node: Ast.full.If) Error!void { |
| 905 | assert(if_node.ast.cond_expr != 0); | ||
| 906 | assert(if_node.ast.then_expr != 0); | ||
| 907 | |||
| 908 | // Perform these transformations in this priority order: | 855 | // Perform these transformations in this priority order: |
| 909 | // 1. If the `else` expression is missing or an empty block, replace the condition with `if (true)` if it is not already. | 856 | // 1. If the `else` expression is missing or an empty block, replace the condition with `if (true)` if it is not already. |
| 910 | // 2. If the `then` block is empty, replace the condition with `if (false)` if it is not already. | 857 | // 2. If the `then` block is empty, replace the condition with `if (false)` if it is not already. |
| 911 | // 3. If the condition is `if (true)`, replace the `if` expression with the contents of the `then` expression. | 858 | // 3. If the condition is `if (true)`, replace the `if` expression with the contents of the `then` expression. |
| 912 | // 4. If the condition is `if (false)`, replace the `if` expression with the contents of the `else` expression. | 859 | // 4. If the condition is `if (false)`, replace the `if` expression with the contents of the `else` expression. |
| 913 | if (!isTrueIdent(w.ast, if_node.ast.cond_expr) and | 860 | if (!isTrueIdent(w.ast, if_node.ast.cond_expr) and |
| 914 | (if_node.ast.else_expr == 0 or isEmptyBlock(w.ast, if_node.ast.else_expr))) | 861 | (if_node.ast.else_expr == .none or isEmptyBlock(w.ast, if_node.ast.else_expr.unwrap().?))) |
| 915 | { | 862 | { |
| 916 | try w.transformations.ensureUnusedCapacity(1); | 863 | try w.transformations.ensureUnusedCapacity(1); |
| 917 | w.transformations.appendAssumeCapacity(.{ .replace_with_true = if_node.ast.cond_expr }); | 864 | w.transformations.appendAssumeCapacity(.{ .replace_with_true = if_node.ast.cond_expr }); |
| ... | @@ -928,17 +875,14 @@ fn walkIf(w: *Walk, node_index: Ast.Node.Index, if_node: Ast.full.If) Error!void | ... | @@ -928,17 +875,14 @@ fn walkIf(w: *Walk, node_index: Ast.Node.Index, if_node: Ast.full.If) Error!void |
| 928 | try w.transformations.ensureUnusedCapacity(1); | 875 | try w.transformations.ensureUnusedCapacity(1); |
| 929 | w.transformations.appendAssumeCapacity(.{ .replace_node = .{ | 876 | w.transformations.appendAssumeCapacity(.{ .replace_node = .{ |
| 930 | .to_replace = node_index, | 877 | .to_replace = node_index, |
| 931 | .replacement = if_node.ast.else_expr, | 878 | .replacement = if_node.ast.else_expr.unwrap().?, |
| 932 | } }); | 879 | } }); |
| 933 | } | 880 | } |
| 934 | 881 | ||
| 935 | try walkExpression(w, if_node.ast.cond_expr); // condition | 882 | try walkExpression(w, if_node.ast.cond_expr); // condition |
| 936 | 883 | try walkExpression(w, if_node.ast.then_expr); | |
| 937 | if (if_node.ast.then_expr != 0) { | 884 | if (if_node.ast.else_expr.unwrap()) |else_expr| { |
| 938 | try walkExpression(w, if_node.ast.then_expr); | 885 | try walkExpression(w, else_expr); |
| 939 | } | ||
| 940 | if (if_node.ast.else_expr != 0) { | ||
| 941 | try walkExpression(w, if_node.ast.else_expr); | ||
| 942 | } | 886 | } |
| 943 | } | 887 | } |
| 944 | 888 | ||
| ... | @@ -958,9 +902,8 @@ fn walkParamList(w: *Walk, params: []const Ast.Node.Index) Error!void { | ... | @@ -958,9 +902,8 @@ fn walkParamList(w: *Walk, params: []const Ast.Node.Index) Error!void { |
| 958 | /// Check if it is already gutted (i.e. its body replaced with `@trap()`). | 902 | /// Check if it is already gutted (i.e. its body replaced with `@trap()`). |
| 959 | fn isFnBodyGutted(ast: *const Ast, body_node: Ast.Node.Index) bool { | 903 | fn isFnBodyGutted(ast: *const Ast, body_node: Ast.Node.Index) bool { |
| 960 | // skip over discards | 904 | // skip over discards |
| 961 | const node_tags = ast.nodes.items(.tag); | ||
| 962 | var statements_buf: [2]Ast.Node.Index = undefined; | 905 | var statements_buf: [2]Ast.Node.Index = undefined; |
| 963 | const statements = switch (node_tags[body_node]) { | 906 | const statements = switch (ast.nodeTag(body_node)) { |
| 964 | .block_two, | 907 | .block_two, |
| 965 | .block_two_semicolon, | 908 | .block_two_semicolon, |
| 966 | .block, | 909 | .block, |
| ... | @@ -988,10 +931,7 @@ const StmtCategory = enum { | ... | @@ -988,10 +931,7 @@ const StmtCategory = enum { |
| 988 | }; | 931 | }; |
| 989 | 932 | ||
| 990 | fn categorizeStmt(ast: *const Ast, stmt: Ast.Node.Index) StmtCategory { | 933 | fn categorizeStmt(ast: *const Ast, stmt: Ast.Node.Index) StmtCategory { |
| 991 | const node_tags = ast.nodes.items(.tag); | 934 | switch (ast.nodeTag(stmt)) { |
| 992 | const datas = ast.nodes.items(.data); | ||
| 993 | const main_tokens = ast.nodes.items(.main_token); | ||
| 994 | switch (node_tags[stmt]) { | ||
| 995 | .builtin_call_two, | 935 | .builtin_call_two, |
| 996 | .builtin_call_two_comma, | 936 | .builtin_call_two_comma, |
| 997 | .builtin_call, | 937 | .builtin_call, |
| ... | @@ -999,12 +939,12 @@ fn categorizeStmt(ast: *const Ast, stmt: Ast.Node.Index) StmtCategory { | ... | @@ -999,12 +939,12 @@ fn categorizeStmt(ast: *const Ast, stmt: Ast.Node.Index) StmtCategory { |
| 999 | => { | 939 | => { |
| 1000 | var buf: [2]Ast.Node.Index = undefined; | 940 | var buf: [2]Ast.Node.Index = undefined; |
| 1001 | const params = ast.builtinCallParams(&buf, stmt).?; | 941 | const params = ast.builtinCallParams(&buf, stmt).?; |
| 1002 | return categorizeBuiltinCall(ast, main_tokens[stmt], params); | 942 | return categorizeBuiltinCall(ast, ast.nodeMainToken(stmt), params); |
| 1003 | }, | 943 | }, |
| 1004 | .assign => { | 944 | .assign => { |
| 1005 | const infix = datas[stmt]; | 945 | const lhs, const rhs = ast.nodeData(stmt).node_and_node; |
| 1006 | if (isDiscardIdent(ast, infix.lhs) and node_tags[infix.rhs] == .identifier) { | 946 | if (isDiscardIdent(ast, lhs) and ast.nodeTag(rhs) == .identifier) { |
| 1007 | const name_bytes = ast.tokenSlice(main_tokens[infix.rhs]); | 947 | const name_bytes = ast.tokenSlice(ast.nodeMainToken(rhs)); |
| 1008 | if (std.mem.eql(u8, name_bytes, "undefined")) { | 948 | if (std.mem.eql(u8, name_bytes, "undefined")) { |
| 1009 | return .discard_undefined; | 949 | return .discard_undefined; |
| 1010 | } else { | 950 | } else { |
| ... | @@ -1046,11 +986,9 @@ fn isFalseIdent(ast: *const Ast, node: Ast.Node.Index) bool { | ... | @@ -1046,11 +986,9 @@ fn isFalseIdent(ast: *const Ast, node: Ast.Node.Index) bool { |
| 1046 | } | 986 | } |
| 1047 | 987 | ||
| 1048 | fn isMatchingIdent(ast: *const Ast, node: Ast.Node.Index, string: []const u8) bool { | 988 | fn isMatchingIdent(ast: *const Ast, node: Ast.Node.Index, string: []const u8) bool { |
| 1049 | const node_tags = ast.nodes.items(.tag); | 989 | switch (ast.nodeTag(node)) { |
| 1050 | const main_tokens = ast.nodes.items(.main_token); | ||
| 1051 | switch (node_tags[node]) { | ||
| 1052 | .identifier => { | 990 | .identifier => { |
| 1053 | const token_index = main_tokens[node]; | 991 | const token_index = ast.nodeMainToken(node); |
| 1054 | const name_bytes = ast.tokenSlice(token_index); | 992 | const name_bytes = ast.tokenSlice(token_index); |
| 1055 | return std.mem.eql(u8, name_bytes, string); | 993 | return std.mem.eql(u8, name_bytes, string); |
| 1056 | }, | 994 | }, |
| ... | @@ -1059,11 +997,10 @@ fn isMatchingIdent(ast: *const Ast, node: Ast.Node.Index, string: []const u8) bo | ... | @@ -1059,11 +997,10 @@ fn isMatchingIdent(ast: *const Ast, node: Ast.Node.Index, string: []const u8) bo |
| 1059 | } | 997 | } |
| 1060 | 998 | ||
| 1061 | fn isEmptyBlock(ast: *const Ast, node: Ast.Node.Index) bool { | 999 | fn isEmptyBlock(ast: *const Ast, node: Ast.Node.Index) bool { |
| 1062 | const node_tags = ast.nodes.items(.tag); | 1000 | switch (ast.nodeTag(node)) { |
| 1063 | const node_data = ast.nodes.items(.data); | ||
| 1064 | switch (node_tags[node]) { | ||
| 1065 | .block_two => { | 1001 | .block_two => { |
| 1066 | return node_data[node].lhs == 0 and node_data[node].rhs == 0; | 1002 | const opt_lhs, const opt_rhs = ast.nodeData(node).opt_node_and_opt_node; |
| 1003 | return opt_lhs == .none and opt_rhs == .none; | ||
| 1067 | }, | 1004 | }, |
| 1068 | else => return false, | 1005 | else => return false, |
| 1069 | } | 1006 | } |
lib/docs/wasm/Decl.zig+30-60| ... | @@ -15,8 +15,7 @@ parent: Index, | ... | @@ -15,8 +15,7 @@ parent: Index, |
| 15 | pub const ExtraInfo = struct { | 15 | pub const ExtraInfo = struct { |
| 16 | is_pub: bool, | 16 | is_pub: bool, |
| 17 | name: []const u8, | 17 | name: []const u8, |
| 18 | /// This might not be a doc_comment token in which case there are no doc comments. | 18 | first_doc_comment: Ast.OptionalTokenIndex, |
| 19 | first_doc_comment: Ast.TokenIndex, | ||
| 20 | }; | 19 | }; |
| 21 | 20 | ||
| 22 | pub const Index = enum(u32) { | 21 | pub const Index = enum(u32) { |
| ... | @@ -34,16 +33,14 @@ pub fn is_pub(d: *const Decl) bool { | ... | @@ -34,16 +33,14 @@ pub fn is_pub(d: *const Decl) bool { |
| 34 | 33 | ||
| 35 | pub fn extra_info(d: *const Decl) ExtraInfo { | 34 | pub fn extra_info(d: *const Decl) ExtraInfo { |
| 36 | const ast = d.file.get_ast(); | 35 | const ast = d.file.get_ast(); |
| 37 | const token_tags = ast.tokens.items(.tag); | 36 | switch (ast.nodeTag(d.ast_node)) { |
| 38 | const node_tags = ast.nodes.items(.tag); | ||
| 39 | switch (node_tags[d.ast_node]) { | ||
| 40 | .root => return .{ | 37 | .root => return .{ |
| 41 | .name = "", | 38 | .name = "", |
| 42 | .is_pub = true, | 39 | .is_pub = true, |
| 43 | .first_doc_comment = if (token_tags[0] == .container_doc_comment) | 40 | .first_doc_comment = if (ast.tokenTag(0) == .container_doc_comment) |
| 44 | 0 | 41 | .fromToken(0) |
| 45 | else | 42 | else |
| 46 | token_tags.len - 1, | 43 | .none, |
| 47 | }, | 44 | }, |
| 48 | 45 | ||
| 49 | .global_var_decl, | 46 | .global_var_decl, |
| ... | @@ -53,7 +50,7 @@ pub fn extra_info(d: *const Decl) ExtraInfo { | ... | @@ -53,7 +50,7 @@ pub fn extra_info(d: *const Decl) ExtraInfo { |
| 53 | => { | 50 | => { |
| 54 | const var_decl = ast.fullVarDecl(d.ast_node).?; | 51 | const var_decl = ast.fullVarDecl(d.ast_node).?; |
| 55 | const name_token = var_decl.ast.mut_token + 1; | 52 | const name_token = var_decl.ast.mut_token + 1; |
| 56 | assert(token_tags[name_token] == .identifier); | 53 | assert(ast.tokenTag(name_token) == .identifier); |
| 57 | const ident_name = ast.tokenSlice(name_token); | 54 | const ident_name = ast.tokenSlice(name_token); |
| 58 | return .{ | 55 | return .{ |
| 59 | .name = ident_name, | 56 | .name = ident_name, |
| ... | @@ -71,7 +68,7 @@ pub fn extra_info(d: *const Decl) ExtraInfo { | ... | @@ -71,7 +68,7 @@ pub fn extra_info(d: *const Decl) ExtraInfo { |
| 71 | var buf: [1]Ast.Node.Index = undefined; | 68 | var buf: [1]Ast.Node.Index = undefined; |
| 72 | const fn_proto = ast.fullFnProto(&buf, d.ast_node).?; | 69 | const fn_proto = ast.fullFnProto(&buf, d.ast_node).?; |
| 73 | const name_token = fn_proto.name_token.?; | 70 | const name_token = fn_proto.name_token.?; |
| 74 | assert(token_tags[name_token] == .identifier); | 71 | assert(ast.tokenTag(name_token) == .identifier); |
| 75 | const ident_name = ast.tokenSlice(name_token); | 72 | const ident_name = ast.tokenSlice(name_token); |
| 76 | return .{ | 73 | return .{ |
| 77 | .name = ident_name, | 74 | .name = ident_name, |
| ... | @@ -89,9 +86,7 @@ pub fn extra_info(d: *const Decl) ExtraInfo { | ... | @@ -89,9 +86,7 @@ pub fn extra_info(d: *const Decl) ExtraInfo { |
| 89 | 86 | ||
| 90 | pub fn value_node(d: *const Decl) ?Ast.Node.Index { | 87 | pub fn value_node(d: *const Decl) ?Ast.Node.Index { |
| 91 | const ast = d.file.get_ast(); | 88 | const ast = d.file.get_ast(); |
| 92 | const node_tags = ast.nodes.items(.tag); | 89 | return switch (ast.nodeTag(d.ast_node)) { |
| 93 | const token_tags = ast.tokens.items(.tag); | ||
| 94 | return switch (node_tags[d.ast_node]) { | ||
| 95 | .fn_proto, | 90 | .fn_proto, |
| 96 | .fn_proto_multi, | 91 | .fn_proto_multi, |
| 97 | .fn_proto_one, | 92 | .fn_proto_one, |
| ... | @@ -106,8 +101,8 @@ pub fn value_node(d: *const Decl) ?Ast.Node.Index { | ... | @@ -106,8 +101,8 @@ pub fn value_node(d: *const Decl) ?Ast.Node.Index { |
| 106 | .aligned_var_decl, | 101 | .aligned_var_decl, |
| 107 | => { | 102 | => { |
| 108 | const var_decl = ast.fullVarDecl(d.ast_node).?; | 103 | const var_decl = ast.fullVarDecl(d.ast_node).?; |
| 109 | if (token_tags[var_decl.ast.mut_token] == .keyword_const) | 104 | if (ast.tokenTag(var_decl.ast.mut_token) == .keyword_const) |
| 110 | return var_decl.ast.init_node; | 105 | return var_decl.ast.init_node.unwrap(); |
| 111 | 106 | ||
| 112 | return null; | 107 | return null; |
| 113 | }, | 108 | }, |
| ... | @@ -148,19 +143,12 @@ pub fn get_child(decl: *const Decl, name: []const u8) ?Decl.Index { | ... | @@ -148,19 +143,12 @@ pub fn get_child(decl: *const Decl, name: []const u8) ?Decl.Index { |
| 148 | pub fn get_type_fn_return_type_fn(decl: *const Decl) ?Decl.Index { | 143 | pub fn get_type_fn_return_type_fn(decl: *const Decl) ?Decl.Index { |
| 149 | if (decl.get_type_fn_return_expr()) |return_expr| { | 144 | if (decl.get_type_fn_return_expr()) |return_expr| { |
| 150 | const ast = decl.file.get_ast(); | 145 | const ast = decl.file.get_ast(); |
| 151 | const node_tags = ast.nodes.items(.tag); | 146 | var buffer: [1]Ast.Node.Index = undefined; |
| 152 | 147 | const call = ast.fullCall(&buffer, return_expr) orelse return null; | |
| 153 | switch (node_tags[return_expr]) { | 148 | const token = ast.nodeMainToken(call.ast.fn_expr); |
| 154 | .call, .call_comma, .call_one, .call_one_comma => { | 149 | const name = ast.tokenSlice(token); |
| 155 | const node_data = ast.nodes.items(.data); | 150 | if (decl.lookup(name)) |function_decl| { |
| 156 | const function = node_data[return_expr].lhs; | 151 | return function_decl; |
| 157 | const token = ast.nodes.items(.main_token)[function]; | ||
| 158 | const name = ast.tokenSlice(token); | ||
| 159 | if (decl.lookup(name)) |function_decl| { | ||
| 160 | return function_decl; | ||
| 161 | } | ||
| 162 | }, | ||
| 163 | else => {}, | ||
| 164 | } | 152 | } |
| 165 | } | 153 | } |
| 166 | return null; | 154 | return null; |
| ... | @@ -171,35 +159,18 @@ pub fn get_type_fn_return_expr(decl: *const Decl) ?Ast.Node.Index { | ... | @@ -171,35 +159,18 @@ pub fn get_type_fn_return_expr(decl: *const Decl) ?Ast.Node.Index { |
| 171 | switch (decl.categorize()) { | 159 | switch (decl.categorize()) { |
| 172 | .type_function => { | 160 | .type_function => { |
| 173 | const ast = decl.file.get_ast(); | 161 | const ast = decl.file.get_ast(); |
| 174 | const node_tags = ast.nodes.items(.tag); | ||
| 175 | const node_data = ast.nodes.items(.data); | ||
| 176 | const body_node = node_data[decl.ast_node].rhs; | ||
| 177 | if (body_node == 0) return null; | ||
| 178 | 162 | ||
| 179 | switch (node_tags[body_node]) { | 163 | const body_node = ast.nodeData(decl.ast_node).node_and_node[1]; |
| 180 | .block, .block_semicolon => { | 164 | |
| 181 | const statements = ast.extra_data[node_data[body_node].lhs..node_data[body_node].rhs]; | 165 | var buf: [2]Ast.Node.Index = undefined; |
| 182 | // Look for the return statement | 166 | const statements = ast.blockStatements(&buf, body_node) orelse return null; |
| 183 | for (statements) |stmt| { | 167 | |
| 184 | if (node_tags[stmt] == .@"return") { | 168 | for (statements) |stmt| { |
| 185 | return node_data[stmt].lhs; | 169 | if (ast.nodeTag(stmt) == .@"return") { |
| 186 | } | 170 | return ast.nodeData(stmt).node; |
| 187 | } | 171 | } |
| 188 | return null; | ||
| 189 | }, | ||
| 190 | .block_two, .block_two_semicolon => { | ||
| 191 | if (node_tags[node_data[body_node].lhs] == .@"return") { | ||
| 192 | return node_data[node_data[body_node].lhs].lhs; | ||
| 193 | } | ||
| 194 | if (node_data[body_node].rhs != 0 and | ||
| 195 | node_tags[node_data[body_node].rhs] == .@"return") | ||
| 196 | { | ||
| 197 | return node_data[node_data[body_node].rhs].lhs; | ||
| 198 | } | ||
| 199 | return null; | ||
| 200 | }, | ||
| 201 | else => return null, | ||
| 202 | } | 172 | } |
| 173 | return null; | ||
| 203 | }, | 174 | }, |
| 204 | else => return null, | 175 | else => return null, |
| 205 | } | 176 | } |
| ... | @@ -269,16 +240,15 @@ pub fn append_parent_ns(list: *std.ArrayListUnmanaged(u8), parent: Decl.Index) O | ... | @@ -269,16 +240,15 @@ pub fn append_parent_ns(list: *std.ArrayListUnmanaged(u8), parent: Decl.Index) O |
| 269 | } | 240 | } |
| 270 | } | 241 | } |
| 271 | 242 | ||
| 272 | pub fn findFirstDocComment(ast: *const Ast, token: Ast.TokenIndex) Ast.TokenIndex { | 243 | pub fn findFirstDocComment(ast: *const Ast, token: Ast.TokenIndex) Ast.OptionalTokenIndex { |
| 273 | const token_tags = ast.tokens.items(.tag); | ||
| 274 | var it = token; | 244 | var it = token; |
| 275 | while (it > 0) { | 245 | while (it > 0) { |
| 276 | it -= 1; | 246 | it -= 1; |
| 277 | if (token_tags[it] != .doc_comment) { | 247 | if (ast.tokenTag(it) != .doc_comment) { |
| 278 | return it + 1; | 248 | return .fromToken(it + 1); |
| 279 | } | 249 | } |
| 280 | } | 250 | } |
| 281 | return it; | 251 | return .none; |
| 282 | } | 252 | } |
| 283 | 253 | ||
| 284 | /// Successively looks up each component. | 254 | /// Successively looks up each component. |
lib/docs/wasm/Walk.zig+71-94| ... | @@ -91,12 +91,10 @@ pub const File = struct { | ... | @@ -91,12 +91,10 @@ pub const File = struct { |
| 91 | 91 | ||
| 92 | pub fn categorize_decl(file_index: File.Index, node: Ast.Node.Index) Category { | 92 | pub fn categorize_decl(file_index: File.Index, node: Ast.Node.Index) Category { |
| 93 | const ast = file_index.get_ast(); | 93 | const ast = file_index.get_ast(); |
| 94 | const node_tags = ast.nodes.items(.tag); | 94 | switch (ast.nodeTag(node)) { |
| 95 | const token_tags = ast.tokens.items(.tag); | ||
| 96 | switch (node_tags[node]) { | ||
| 97 | .root => { | 95 | .root => { |
| 98 | for (ast.rootDecls()) |member| { | 96 | for (ast.rootDecls()) |member| { |
| 99 | switch (node_tags[member]) { | 97 | switch (ast.nodeTag(member)) { |
| 100 | .container_field_init, | 98 | .container_field_init, |
| 101 | .container_field_align, | 99 | .container_field_align, |
| 102 | .container_field, | 100 | .container_field, |
| ... | @@ -113,10 +111,12 @@ pub const File = struct { | ... | @@ -113,10 +111,12 @@ pub const File = struct { |
| 113 | .aligned_var_decl, | 111 | .aligned_var_decl, |
| 114 | => { | 112 | => { |
| 115 | const var_decl = ast.fullVarDecl(node).?; | 113 | const var_decl = ast.fullVarDecl(node).?; |
| 116 | if (token_tags[var_decl.ast.mut_token] == .keyword_var) | 114 | if (ast.tokenTag(var_decl.ast.mut_token) == .keyword_var) |
| 117 | return .{ .global_variable = node }; | 115 | return .{ .global_variable = node }; |
| 116 | const init_node = var_decl.ast.init_node.unwrap() orelse | ||
| 117 | return .{ .global_const = node }; | ||
| 118 | 118 | ||
| 119 | return categorize_expr(file_index, var_decl.ast.init_node); | 119 | return categorize_expr(file_index, init_node); |
| 120 | }, | 120 | }, |
| 121 | 121 | ||
| 122 | .fn_proto, | 122 | .fn_proto, |
| ... | @@ -139,7 +139,7 @@ pub const File = struct { | ... | @@ -139,7 +139,7 @@ pub const File = struct { |
| 139 | node: Ast.Node.Index, | 139 | node: Ast.Node.Index, |
| 140 | full: Ast.full.FnProto, | 140 | full: Ast.full.FnProto, |
| 141 | ) Category { | 141 | ) Category { |
| 142 | return switch (categorize_expr(file_index, full.ast.return_type)) { | 142 | return switch (categorize_expr(file_index, full.ast.return_type.unwrap().?)) { |
| 143 | .namespace, .container, .error_set, .type_type => .{ .type_function = node }, | 143 | .namespace, .container, .error_set, .type_type => .{ .type_function = node }, |
| 144 | else => .{ .function = node }, | 144 | else => .{ .function = node }, |
| 145 | }; | 145 | }; |
| ... | @@ -155,12 +155,8 @@ pub const File = struct { | ... | @@ -155,12 +155,8 @@ pub const File = struct { |
| 155 | pub fn categorize_expr(file_index: File.Index, node: Ast.Node.Index) Category { | 155 | pub fn categorize_expr(file_index: File.Index, node: Ast.Node.Index) Category { |
| 156 | const file = file_index.get(); | 156 | const file = file_index.get(); |
| 157 | const ast = file_index.get_ast(); | 157 | const ast = file_index.get_ast(); |
| 158 | const node_tags = ast.nodes.items(.tag); | 158 | //log.debug("categorize_expr tag {s}", .{@tagName(ast.nodeTag(node))}); |
| 159 | const node_datas = ast.nodes.items(.data); | 159 | return switch (ast.nodeTag(node)) { |
| 160 | const main_tokens = ast.nodes.items(.main_token); | ||
| 161 | const token_tags = ast.tokens.items(.tag); | ||
| 162 | //log.debug("categorize_expr tag {s}", .{@tagName(node_tags[node])}); | ||
| 163 | return switch (node_tags[node]) { | ||
| 164 | .container_decl, | 160 | .container_decl, |
| 165 | .container_decl_trailing, | 161 | .container_decl_trailing, |
| 166 | .container_decl_arg, | 162 | .container_decl_arg, |
| ... | @@ -176,11 +172,11 @@ pub const File = struct { | ... | @@ -176,11 +172,11 @@ pub const File = struct { |
| 176 | => { | 172 | => { |
| 177 | var buf: [2]Ast.Node.Index = undefined; | 173 | var buf: [2]Ast.Node.Index = undefined; |
| 178 | const container_decl = ast.fullContainerDecl(&buf, node).?; | 174 | const container_decl = ast.fullContainerDecl(&buf, node).?; |
| 179 | if (token_tags[container_decl.ast.main_token] != .keyword_struct) { | 175 | if (ast.tokenTag(container_decl.ast.main_token) != .keyword_struct) { |
| 180 | return .{ .container = node }; | 176 | return .{ .container = node }; |
| 181 | } | 177 | } |
| 182 | for (container_decl.ast.members) |member| { | 178 | for (container_decl.ast.members) |member| { |
| 183 | switch (node_tags[member]) { | 179 | switch (ast.nodeTag(member)) { |
| 184 | .container_field_init, | 180 | .container_field_init, |
| 185 | .container_field_align, | 181 | .container_field_align, |
| 186 | .container_field, | 182 | .container_field, |
| ... | @@ -196,7 +192,7 @@ pub const File = struct { | ... | @@ -196,7 +192,7 @@ pub const File = struct { |
| 196 | => .{ .error_set = node }, | 192 | => .{ .error_set = node }, |
| 197 | 193 | ||
| 198 | .identifier => { | 194 | .identifier => { |
| 199 | const name_token = ast.nodes.items(.main_token)[node]; | 195 | const name_token = ast.nodeMainToken(node); |
| 200 | const ident_name = ast.tokenSlice(name_token); | 196 | const ident_name = ast.tokenSlice(name_token); |
| 201 | if (std.mem.eql(u8, ident_name, "type")) | 197 | if (std.mem.eql(u8, ident_name, "type")) |
| 202 | return .type_type; | 198 | return .type_type; |
| ... | @@ -217,9 +213,7 @@ pub const File = struct { | ... | @@ -217,9 +213,7 @@ pub const File = struct { |
| 217 | }, | 213 | }, |
| 218 | 214 | ||
| 219 | .field_access => { | 215 | .field_access => { |
| 220 | const object_node = node_datas[node].lhs; | 216 | const object_node, const field_ident = ast.nodeData(node).node_and_token; |
| 221 | const dot_token = main_tokens[node]; | ||
| 222 | const field_ident = dot_token + 1; | ||
| 223 | const field_name = ast.tokenSlice(field_ident); | 217 | const field_name = ast.tokenSlice(field_ident); |
| 224 | 218 | ||
| 225 | switch (categorize_expr(file_index, object_node)) { | 219 | switch (categorize_expr(file_index, object_node)) { |
| ... | @@ -259,9 +253,9 @@ pub const File = struct { | ... | @@ -259,9 +253,9 @@ pub const File = struct { |
| 259 | .@"if", | 253 | .@"if", |
| 260 | => { | 254 | => { |
| 261 | const if_full = ast.fullIf(node).?; | 255 | const if_full = ast.fullIf(node).?; |
| 262 | if (if_full.ast.else_expr != 0) { | 256 | if (if_full.ast.else_expr.unwrap()) |else_expr| { |
| 263 | const then_cat = categorize_expr_deep(file_index, if_full.ast.then_expr); | 257 | const then_cat = categorize_expr_deep(file_index, if_full.ast.then_expr); |
| 264 | const else_cat = categorize_expr_deep(file_index, if_full.ast.else_expr); | 258 | const else_cat = categorize_expr_deep(file_index, else_expr); |
| 265 | if (then_cat == .type_type and else_cat == .type_type) { | 259 | if (then_cat == .type_type and else_cat == .type_type) { |
| 266 | return .type_type; | 260 | return .type_type; |
| 267 | } else if (then_cat == .error_set and else_cat == .error_set) { | 261 | } else if (then_cat == .error_set and else_cat == .error_set) { |
| ... | @@ -320,11 +314,10 @@ pub const File = struct { | ... | @@ -320,11 +314,10 @@ pub const File = struct { |
| 320 | params: []const Ast.Node.Index, | 314 | params: []const Ast.Node.Index, |
| 321 | ) Category { | 315 | ) Category { |
| 322 | const ast = file_index.get_ast(); | 316 | const ast = file_index.get_ast(); |
| 323 | const main_tokens = ast.nodes.items(.main_token); | 317 | const builtin_token = ast.nodeMainToken(node); |
| 324 | const builtin_token = main_tokens[node]; | ||
| 325 | const builtin_name = ast.tokenSlice(builtin_token); | 318 | const builtin_name = ast.tokenSlice(builtin_token); |
| 326 | if (std.mem.eql(u8, builtin_name, "@import")) { | 319 | if (std.mem.eql(u8, builtin_name, "@import")) { |
| 327 | const str_lit_token = main_tokens[params[0]]; | 320 | const str_lit_token = ast.nodeMainToken(params[0]); |
| 328 | const str_bytes = ast.tokenSlice(str_lit_token); | 321 | const str_bytes = ast.tokenSlice(str_lit_token); |
| 329 | const file_path = std.zig.string_literal.parseAlloc(gpa, str_bytes) catch @panic("OOM"); | 322 | const file_path = std.zig.string_literal.parseAlloc(gpa, str_bytes) catch @panic("OOM"); |
| 330 | defer gpa.free(file_path); | 323 | defer gpa.free(file_path); |
| ... | @@ -357,14 +350,12 @@ pub const File = struct { | ... | @@ -357,14 +350,12 @@ pub const File = struct { |
| 357 | 350 | ||
| 358 | fn categorize_switch(file_index: File.Index, node: Ast.Node.Index) Category { | 351 | fn categorize_switch(file_index: File.Index, node: Ast.Node.Index) Category { |
| 359 | const ast = file_index.get_ast(); | 352 | const ast = file_index.get_ast(); |
| 360 | const node_datas = ast.nodes.items(.data); | 353 | const full = ast.fullSwitch(node).?; |
| 361 | const extra = ast.extraData(node_datas[node].rhs, Ast.Node.SubRange); | ||
| 362 | const case_nodes = ast.extra_data[extra.start..extra.end]; | ||
| 363 | var all_type_type = true; | 354 | var all_type_type = true; |
| 364 | var all_error_set = true; | 355 | var all_error_set = true; |
| 365 | var any_type = false; | 356 | var any_type = false; |
| 366 | if (case_nodes.len == 0) return .{ .global_const = node }; | 357 | if (full.ast.cases.len == 0) return .{ .global_const = node }; |
| 367 | for (case_nodes) |case_node| { | 358 | for (full.ast.cases) |case_node| { |
| 368 | const case = ast.fullSwitchCase(case_node).?; | 359 | const case = ast.fullSwitchCase(case_node).?; |
| 369 | switch (categorize_expr_deep(file_index, case.ast.target_expr)) { | 360 | switch (categorize_expr_deep(file_index, case.ast.target_expr)) { |
| 370 | .type_type => { | 361 | .type_type => { |
| ... | @@ -410,8 +401,8 @@ pub fn add_file(file_name: []const u8, bytes: []u8) !File.Index { | ... | @@ -410,8 +401,8 @@ pub fn add_file(file_name: []const u8, bytes: []u8) !File.Index { |
| 410 | const scope = try gpa.create(Scope); | 401 | const scope = try gpa.create(Scope); |
| 411 | scope.* = .{ .tag = .top }; | 402 | scope.* = .{ .tag = .top }; |
| 412 | 403 | ||
| 413 | const decl_index = try file_index.add_decl(0, .none); | 404 | const decl_index = try file_index.add_decl(.root, .none); |
| 414 | try struct_decl(&w, scope, decl_index, 0, ast.containerDeclRoot()); | 405 | try struct_decl(&w, scope, decl_index, .root, ast.containerDeclRoot()); |
| 415 | 406 | ||
| 416 | const file = file_index.get(); | 407 | const file = file_index.get(); |
| 417 | shrinkToFit(&file.ident_decls); | 408 | shrinkToFit(&file.ident_decls); |
| ... | @@ -505,13 +496,12 @@ pub const Scope = struct { | ... | @@ -505,13 +496,12 @@ pub const Scope = struct { |
| 505 | } | 496 | } |
| 506 | 497 | ||
| 507 | pub fn lookup(start_scope: *Scope, ast: *const Ast, name: []const u8) ?Ast.Node.Index { | 498 | pub fn lookup(start_scope: *Scope, ast: *const Ast, name: []const u8) ?Ast.Node.Index { |
| 508 | const main_tokens = ast.nodes.items(.main_token); | ||
| 509 | var it: *Scope = start_scope; | 499 | var it: *Scope = start_scope; |
| 510 | while (true) switch (it.tag) { | 500 | while (true) switch (it.tag) { |
| 511 | .top => break, | 501 | .top => break, |
| 512 | .local => { | 502 | .local => { |
| 513 | const local: *Local = @alignCast(@fieldParentPtr("base", it)); | 503 | const local: *Local = @alignCast(@fieldParentPtr("base", it)); |
| 514 | const name_token = main_tokens[local.var_node] + 1; | 504 | const name_token = ast.nodeMainToken(local.var_node) + 1; |
| 515 | const ident_name = ast.tokenSlice(name_token); | 505 | const ident_name = ast.tokenSlice(name_token); |
| 516 | if (std.mem.eql(u8, ident_name, name)) { | 506 | if (std.mem.eql(u8, ident_name, name)) { |
| 517 | return local.var_node; | 507 | return local.var_node; |
| ... | @@ -538,8 +528,6 @@ fn struct_decl( | ... | @@ -538,8 +528,6 @@ fn struct_decl( |
| 538 | container_decl: Ast.full.ContainerDecl, | 528 | container_decl: Ast.full.ContainerDecl, |
| 539 | ) Oom!void { | 529 | ) Oom!void { |
| 540 | const ast = w.file.get_ast(); | 530 | const ast = w.file.get_ast(); |
| 541 | const node_tags = ast.nodes.items(.tag); | ||
| 542 | const node_datas = ast.nodes.items(.data); | ||
| 543 | 531 | ||
| 544 | const namespace = try gpa.create(Scope.Namespace); | 532 | const namespace = try gpa.create(Scope.Namespace); |
| 545 | namespace.* = .{ | 533 | namespace.* = .{ |
| ... | @@ -549,7 +537,7 @@ fn struct_decl( | ... | @@ -549,7 +537,7 @@ fn struct_decl( |
| 549 | try w.file.get().scopes.putNoClobber(gpa, node, &namespace.base); | 537 | try w.file.get().scopes.putNoClobber(gpa, node, &namespace.base); |
| 550 | try w.scanDecls(namespace, container_decl.ast.members); | 538 | try w.scanDecls(namespace, container_decl.ast.members); |
| 551 | 539 | ||
| 552 | for (container_decl.ast.members) |member| switch (node_tags[member]) { | 540 | for (container_decl.ast.members) |member| switch (ast.nodeTag(member)) { |
| 553 | .container_field_init, | 541 | .container_field_init, |
| 554 | .container_field_align, | 542 | .container_field_align, |
| 555 | .container_field, | 543 | .container_field, |
| ... | @@ -569,7 +557,7 @@ fn struct_decl( | ... | @@ -569,7 +557,7 @@ fn struct_decl( |
| 569 | try w.file.get().doctests.put(gpa, member, doctest_node); | 557 | try w.file.get().doctests.put(gpa, member, doctest_node); |
| 570 | } | 558 | } |
| 571 | const decl_index = try w.file.add_decl(member, parent_decl); | 559 | const decl_index = try w.file.add_decl(member, parent_decl); |
| 572 | const body = if (node_tags[member] == .fn_decl) node_datas[member].rhs else 0; | 560 | const body = if (ast.nodeTag(member) == .fn_decl) ast.nodeData(member).node_and_node[1].toOptional() else .none; |
| 573 | try w.fn_decl(&namespace.base, decl_index, body, full); | 561 | try w.fn_decl(&namespace.base, decl_index, body, full); |
| 574 | }, | 562 | }, |
| 575 | 563 | ||
| ... | @@ -584,9 +572,9 @@ fn struct_decl( | ... | @@ -584,9 +572,9 @@ fn struct_decl( |
| 584 | 572 | ||
| 585 | .@"comptime", | 573 | .@"comptime", |
| 586 | .@"usingnamespace", | 574 | .@"usingnamespace", |
| 587 | => try w.expr(&namespace.base, parent_decl, node_datas[member].lhs), | 575 | => try w.expr(&namespace.base, parent_decl, ast.nodeData(member).node), |
| 588 | 576 | ||
| 589 | .test_decl => try w.expr(&namespace.base, parent_decl, node_datas[member].rhs), | 577 | .test_decl => try w.expr(&namespace.base, parent_decl, ast.nodeData(member).opt_token_and_node[1]), |
| 590 | 578 | ||
| 591 | else => unreachable, | 579 | else => unreachable, |
| 592 | }; | 580 | }; |
| ... | @@ -633,13 +621,13 @@ fn fn_decl( | ... | @@ -633,13 +621,13 @@ fn fn_decl( |
| 633 | w: *Walk, | 621 | w: *Walk, |
| 634 | scope: *Scope, | 622 | scope: *Scope, |
| 635 | parent_decl: Decl.Index, | 623 | parent_decl: Decl.Index, |
| 636 | body: Ast.Node.Index, | 624 | body: Ast.Node.OptionalIndex, |
| 637 | full: Ast.full.FnProto, | 625 | full: Ast.full.FnProto, |
| 638 | ) Oom!void { | 626 | ) Oom!void { |
| 639 | for (full.ast.params) |param| { | 627 | for (full.ast.params) |param| { |
| 640 | try expr(w, scope, parent_decl, param); | 628 | try expr(w, scope, parent_decl, param); |
| 641 | } | 629 | } |
| 642 | try expr(w, scope, parent_decl, full.ast.return_type); | 630 | try expr(w, scope, parent_decl, full.ast.return_type.unwrap().?); |
| 643 | try maybe_expr(w, scope, parent_decl, full.ast.align_expr); | 631 | try maybe_expr(w, scope, parent_decl, full.ast.align_expr); |
| 644 | try maybe_expr(w, scope, parent_decl, full.ast.addrspace_expr); | 632 | try maybe_expr(w, scope, parent_decl, full.ast.addrspace_expr); |
| 645 | try maybe_expr(w, scope, parent_decl, full.ast.section_expr); | 633 | try maybe_expr(w, scope, parent_decl, full.ast.section_expr); |
| ... | @@ -647,17 +635,13 @@ fn fn_decl( | ... | @@ -647,17 +635,13 @@ fn fn_decl( |
| 647 | try maybe_expr(w, scope, parent_decl, body); | 635 | try maybe_expr(w, scope, parent_decl, body); |
| 648 | } | 636 | } |
| 649 | 637 | ||
| 650 | fn maybe_expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) Oom!void { | 638 | fn maybe_expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.OptionalIndex) Oom!void { |
| 651 | if (node != 0) return expr(w, scope, parent_decl, node); | 639 | if (node.unwrap()) |n| return expr(w, scope, parent_decl, n); |
| 652 | } | 640 | } |
| 653 | 641 | ||
| 654 | fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) Oom!void { | 642 | fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) Oom!void { |
| 655 | assert(node != 0); | ||
| 656 | const ast = w.file.get_ast(); | 643 | const ast = w.file.get_ast(); |
| 657 | const node_tags = ast.nodes.items(.tag); | 644 | switch (ast.nodeTag(node)) { |
| 658 | const node_datas = ast.nodes.items(.data); | ||
| 659 | const main_tokens = ast.nodes.items(.main_token); | ||
| 660 | switch (node_tags[node]) { | ||
| 661 | .root => unreachable, // Top-level declaration. | 645 | .root => unreachable, // Top-level declaration. |
| 662 | .@"usingnamespace" => unreachable, // Top-level declaration. | 646 | .@"usingnamespace" => unreachable, // Top-level declaration. |
| 663 | .test_decl => unreachable, // Top-level declaration. | 647 | .test_decl => unreachable, // Top-level declaration. |
| ... | @@ -738,8 +722,9 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) | ... | @@ -738,8 +722,9 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) |
| 738 | .array_access, | 722 | .array_access, |
| 739 | .switch_range, | 723 | .switch_range, |
| 740 | => { | 724 | => { |
| 741 | try expr(w, scope, parent_decl, node_datas[node].lhs); | 725 | const lhs, const rhs = ast.nodeData(node).node_and_node; |
| 742 | try expr(w, scope, parent_decl, node_datas[node].rhs); | 726 | try expr(w, scope, parent_decl, lhs); |
| 727 | try expr(w, scope, parent_decl, rhs); | ||
| 743 | }, | 728 | }, |
| 744 | 729 | ||
| 745 | .assign_destructure => { | 730 | .assign_destructure => { |
| ... | @@ -752,35 +737,33 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) | ... | @@ -752,35 +737,33 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) |
| 752 | .bit_not, | 737 | .bit_not, |
| 753 | .negation, | 738 | .negation, |
| 754 | .negation_wrap, | 739 | .negation_wrap, |
| 755 | .@"return", | ||
| 756 | .deref, | 740 | .deref, |
| 757 | .address_of, | 741 | .address_of, |
| 758 | .optional_type, | 742 | .optional_type, |
| 759 | .unwrap_optional, | ||
| 760 | .grouped_expression, | ||
| 761 | .@"comptime", | 743 | .@"comptime", |
| 762 | .@"nosuspend", | 744 | .@"nosuspend", |
| 763 | .@"suspend", | 745 | .@"suspend", |
| 764 | .@"await", | 746 | .@"await", |
| 765 | .@"resume", | 747 | .@"resume", |
| 766 | .@"try", | 748 | .@"try", |
| 767 | => try maybe_expr(w, scope, parent_decl, node_datas[node].lhs), | 749 | => try expr(w, scope, parent_decl, ast.nodeData(node).node), |
| 750 | .unwrap_optional, | ||
| 751 | .grouped_expression, | ||
| 752 | => try expr(w, scope, parent_decl, ast.nodeData(node).node_and_token[0]), | ||
| 753 | .@"return" => try maybe_expr(w, scope, parent_decl, ast.nodeData(node).opt_node), | ||
| 768 | 754 | ||
| 769 | .anyframe_type, | 755 | .anyframe_type => try expr(w, scope, parent_decl, ast.nodeData(node).token_and_node[1]), |
| 770 | .@"break", | 756 | .@"break" => try maybe_expr(w, scope, parent_decl, ast.nodeData(node).opt_token_and_opt_node[1]), |
| 771 | => try maybe_expr(w, scope, parent_decl, node_datas[node].rhs), | ||
| 772 | 757 | ||
| 773 | .identifier => { | 758 | .identifier => { |
| 774 | const ident_token = main_tokens[node]; | 759 | const ident_token = ast.nodeMainToken(node); |
| 775 | const ident_name = ast.tokenSlice(ident_token); | 760 | const ident_name = ast.tokenSlice(ident_token); |
| 776 | if (scope.lookup(ast, ident_name)) |var_node| { | 761 | if (scope.lookup(ast, ident_name)) |var_node| { |
| 777 | try w.file.get().ident_decls.put(gpa, ident_token, var_node); | 762 | try w.file.get().ident_decls.put(gpa, ident_token, var_node); |
| 778 | } | 763 | } |
| 779 | }, | 764 | }, |
| 780 | .field_access => { | 765 | .field_access => { |
| 781 | const object_node = node_datas[node].lhs; | 766 | const object_node, const field_ident = ast.nodeData(node).node_and_token; |
| 782 | const dot_token = main_tokens[node]; | ||
| 783 | const field_ident = dot_token + 1; | ||
| 784 | try w.file.get().token_parents.put(gpa, field_ident, node); | 767 | try w.file.get().token_parents.put(gpa, field_ident, node); |
| 785 | // This will populate the left-most field object if it is an | 768 | // This will populate the left-most field object if it is an |
| 786 | // identifier, allowing rendering code to piece together the link. | 769 | // identifier, allowing rendering code to piece together the link. |
| ... | @@ -857,9 +840,10 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) | ... | @@ -857,9 +840,10 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) |
| 857 | .for_simple, .@"for" => { | 840 | .for_simple, .@"for" => { |
| 858 | const full = ast.fullFor(node).?; | 841 | const full = ast.fullFor(node).?; |
| 859 | for (full.ast.inputs) |input| { | 842 | for (full.ast.inputs) |input| { |
| 860 | if (node_tags[input] == .for_range) { | 843 | if (ast.nodeTag(input) == .for_range) { |
| 861 | try expr(w, scope, parent_decl, node_datas[input].lhs); | 844 | const start, const end = ast.nodeData(input).node_and_opt_node; |
| 862 | try maybe_expr(w, scope, parent_decl, node_datas[input].rhs); | 845 | try expr(w, scope, parent_decl, start); |
| 846 | try maybe_expr(w, scope, parent_decl, end); | ||
| 863 | } else { | 847 | } else { |
| 864 | try expr(w, scope, parent_decl, input); | 848 | try expr(w, scope, parent_decl, input); |
| 865 | } | 849 | } |
| ... | @@ -914,17 +898,16 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) | ... | @@ -914,17 +898,16 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) |
| 914 | }, | 898 | }, |
| 915 | 899 | ||
| 916 | .array_type_sentinel => { | 900 | .array_type_sentinel => { |
| 917 | const extra = ast.extraData(node_datas[node].rhs, Ast.Node.ArrayTypeSentinel); | 901 | const len_expr, const extra_index = ast.nodeData(node).node_and_extra; |
| 918 | try expr(w, scope, parent_decl, node_datas[node].lhs); | 902 | const extra = ast.extraData(extra_index, Ast.Node.ArrayTypeSentinel); |
| 903 | try expr(w, scope, parent_decl, len_expr); | ||
| 919 | try expr(w, scope, parent_decl, extra.elem_type); | 904 | try expr(w, scope, parent_decl, extra.elem_type); |
| 920 | try expr(w, scope, parent_decl, extra.sentinel); | 905 | try expr(w, scope, parent_decl, extra.sentinel); |
| 921 | }, | 906 | }, |
| 922 | .@"switch", .switch_comma => { | 907 | .@"switch", .switch_comma => { |
| 923 | const operand_node = node_datas[node].lhs; | 908 | const full = ast.fullSwitch(node).?; |
| 924 | try expr(w, scope, parent_decl, operand_node); | 909 | try expr(w, scope, parent_decl, full.ast.condition); |
| 925 | const extra = ast.extraData(node_datas[node].rhs, Ast.Node.SubRange); | 910 | for (full.ast.cases) |case_node| { |
| 926 | const case_nodes = ast.extra_data[extra.start..extra.end]; | ||
| 927 | for (case_nodes) |case_node| { | ||
| 928 | const case = ast.fullSwitchCase(case_node).?; | 911 | const case = ast.fullSwitchCase(case_node).?; |
| 929 | for (case.ast.values) |value_node| { | 912 | for (case.ast.values) |value_node| { |
| 930 | try expr(w, scope, parent_decl, value_node); | 913 | try expr(w, scope, parent_decl, value_node); |
| ... | @@ -973,7 +956,7 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) | ... | @@ -973,7 +956,7 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) |
| 973 | .fn_proto, | 956 | .fn_proto, |
| 974 | => { | 957 | => { |
| 975 | var buf: [1]Ast.Node.Index = undefined; | 958 | var buf: [1]Ast.Node.Index = undefined; |
| 976 | return fn_decl(w, scope, parent_decl, 0, ast.fullFnProto(&buf, node).?); | 959 | return fn_decl(w, scope, parent_decl, .none, ast.fullFnProto(&buf, node).?); |
| 977 | }, | 960 | }, |
| 978 | } | 961 | } |
| 979 | } | 962 | } |
| ... | @@ -993,8 +976,7 @@ fn builtin_call( | ... | @@ -993,8 +976,7 @@ fn builtin_call( |
| 993 | params: []const Ast.Node.Index, | 976 | params: []const Ast.Node.Index, |
| 994 | ) Oom!void { | 977 | ) Oom!void { |
| 995 | const ast = w.file.get_ast(); | 978 | const ast = w.file.get_ast(); |
| 996 | const main_tokens = ast.nodes.items(.main_token); | 979 | const builtin_token = ast.nodeMainToken(node); |
| 997 | const builtin_token = main_tokens[node]; | ||
| 998 | const builtin_name = ast.tokenSlice(builtin_token); | 980 | const builtin_name = ast.tokenSlice(builtin_token); |
| 999 | if (std.mem.eql(u8, builtin_name, "@This")) { | 981 | if (std.mem.eql(u8, builtin_name, "@This")) { |
| 1000 | try w.file.get().node_decls.put(gpa, node, scope.getNamespaceDecl()); | 982 | try w.file.get().node_decls.put(gpa, node, scope.getNamespaceDecl()); |
| ... | @@ -1012,13 +994,11 @@ fn block( | ... | @@ -1012,13 +994,11 @@ fn block( |
| 1012 | statements: []const Ast.Node.Index, | 994 | statements: []const Ast.Node.Index, |
| 1013 | ) Oom!void { | 995 | ) Oom!void { |
| 1014 | const ast = w.file.get_ast(); | 996 | const ast = w.file.get_ast(); |
| 1015 | const node_tags = ast.nodes.items(.tag); | ||
| 1016 | const node_datas = ast.nodes.items(.data); | ||
| 1017 | 997 | ||
| 1018 | var scope = parent_scope; | 998 | var scope = parent_scope; |
| 1019 | 999 | ||
| 1020 | for (statements) |node| { | 1000 | for (statements) |node| { |
| 1021 | switch (node_tags[node]) { | 1001 | switch (ast.nodeTag(node)) { |
| 1022 | .global_var_decl, | 1002 | .global_var_decl, |
| 1023 | .local_var_decl, | 1003 | .local_var_decl, |
| 1024 | .simple_var_decl, | 1004 | .simple_var_decl, |
| ... | @@ -1039,11 +1019,10 @@ fn block( | ... | @@ -1039,11 +1019,10 @@ fn block( |
| 1039 | log.debug("walk assign_destructure not implemented yet", .{}); | 1019 | log.debug("walk assign_destructure not implemented yet", .{}); |
| 1040 | }, | 1020 | }, |
| 1041 | 1021 | ||
| 1042 | .grouped_expression => try expr(w, scope, parent_decl, node_datas[node].lhs), | 1022 | .grouped_expression => try expr(w, scope, parent_decl, ast.nodeData(node).node_and_token[0]), |
| 1043 | 1023 | ||
| 1044 | .@"defer", | 1024 | .@"defer" => try expr(w, scope, parent_decl, ast.nodeData(node).node), |
| 1045 | .@"errdefer", | 1025 | .@"errdefer" => try expr(w, scope, parent_decl, ast.nodeData(node).opt_token_and_node[1]), |
| 1046 | => try expr(w, scope, parent_decl, node_datas[node].rhs), | ||
| 1047 | 1026 | ||
| 1048 | else => try expr(w, scope, parent_decl, node), | 1027 | else => try expr(w, scope, parent_decl, node), |
| 1049 | } | 1028 | } |
| ... | @@ -1059,18 +1038,14 @@ fn while_expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, full: Ast.full.W | ... | @@ -1059,18 +1038,14 @@ fn while_expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, full: Ast.full.W |
| 1059 | 1038 | ||
| 1060 | fn scanDecls(w: *Walk, namespace: *Scope.Namespace, members: []const Ast.Node.Index) Oom!void { | 1039 | fn scanDecls(w: *Walk, namespace: *Scope.Namespace, members: []const Ast.Node.Index) Oom!void { |
| 1061 | const ast = w.file.get_ast(); | 1040 | const ast = w.file.get_ast(); |
| 1062 | const node_tags = ast.nodes.items(.tag); | ||
| 1063 | const main_tokens = ast.nodes.items(.main_token); | ||
| 1064 | const token_tags = ast.tokens.items(.tag); | ||
| 1065 | const node_datas = ast.nodes.items(.data); | ||
| 1066 | 1041 | ||
| 1067 | for (members) |member_node| { | 1042 | for (members) |member_node| { |
| 1068 | const name_token = switch (node_tags[member_node]) { | 1043 | const name_token = switch (ast.nodeTag(member_node)) { |
| 1069 | .global_var_decl, | 1044 | .global_var_decl, |
| 1070 | .local_var_decl, | 1045 | .local_var_decl, |
| 1071 | .simple_var_decl, | 1046 | .simple_var_decl, |
| 1072 | .aligned_var_decl, | 1047 | .aligned_var_decl, |
| 1073 | => main_tokens[member_node] + 1, | 1048 | => ast.nodeMainToken(member_node) + 1, |
| 1074 | 1049 | ||
| 1075 | .fn_proto_simple, | 1050 | .fn_proto_simple, |
| 1076 | .fn_proto_multi, | 1051 | .fn_proto_multi, |
| ... | @@ -1078,17 +1053,19 @@ fn scanDecls(w: *Walk, namespace: *Scope.Namespace, members: []const Ast.Node.In | ... | @@ -1078,17 +1053,19 @@ fn scanDecls(w: *Walk, namespace: *Scope.Namespace, members: []const Ast.Node.In |
| 1078 | .fn_proto, | 1053 | .fn_proto, |
| 1079 | .fn_decl, | 1054 | .fn_decl, |
| 1080 | => blk: { | 1055 | => blk: { |
| 1081 | const ident = main_tokens[member_node] + 1; | 1056 | const ident = ast.nodeMainToken(member_node) + 1; |
| 1082 | if (token_tags[ident] != .identifier) continue; | 1057 | if (ast.tokenTag(ident) != .identifier) continue; |
| 1083 | break :blk ident; | 1058 | break :blk ident; |
| 1084 | }, | 1059 | }, |
| 1085 | 1060 | ||
| 1086 | .test_decl => { | 1061 | .test_decl => { |
| 1087 | const ident_token = node_datas[member_node].lhs; | 1062 | const opt_ident_token = ast.nodeData(member_node).opt_token_and_node[0]; |
| 1088 | const is_doctest = token_tags[ident_token] == .identifier; | 1063 | if (opt_ident_token.unwrap()) |ident_token| { |
| 1089 | if (is_doctest) { | 1064 | const is_doctest = ast.tokenTag(ident_token) == .identifier; |
| 1090 | const token_bytes = ast.tokenSlice(ident_token); | 1065 | if (is_doctest) { |
| 1091 | try namespace.doctests.put(gpa, token_bytes, member_node); | 1066 | const token_bytes = ast.tokenSlice(ident_token); |
| 1067 | try namespace.doctests.put(gpa, token_bytes, member_node); | ||
| 1068 | } | ||
| 1092 | } | 1069 | } |
| 1093 | continue; | 1070 | continue; |
| 1094 | }, | 1071 | }, |
lib/docs/wasm/html_render.zig+9-18| ... | @@ -41,14 +41,10 @@ pub fn fileSourceHtml( | ... | @@ -41,14 +41,10 @@ pub fn fileSourceHtml( |
| 41 | var field_access_buffer: std.ArrayListUnmanaged(u8) = .empty; | 41 | var field_access_buffer: std.ArrayListUnmanaged(u8) = .empty; |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | const token_tags = ast.tokens.items(.tag); | ||
| 45 | const token_starts = ast.tokens.items(.start); | ||
| 46 | const main_tokens = ast.nodes.items(.main_token); | ||
| 47 | |||
| 48 | const start_token = ast.firstToken(root_node); | 44 | const start_token = ast.firstToken(root_node); |
| 49 | const end_token = ast.lastToken(root_node) + 1; | 45 | const end_token = ast.lastToken(root_node) + 1; |
| 50 | 46 | ||
| 51 | var cursor: usize = token_starts[start_token]; | 47 | var cursor: usize = ast.tokenStart(start_token); |
| 52 | 48 | ||
| 53 | var indent: usize = 0; | 49 | var indent: usize = 0; |
| 54 | if (std.mem.lastIndexOf(u8, ast.source[0..cursor], "\n")) |newline_index| { | 50 | if (std.mem.lastIndexOf(u8, ast.source[0..cursor], "\n")) |newline_index| { |
| ... | @@ -64,8 +60,8 @@ pub fn fileSourceHtml( | ... | @@ -64,8 +60,8 @@ pub fn fileSourceHtml( |
| 64 | var next_annotate_index: usize = 0; | 60 | var next_annotate_index: usize = 0; |
| 65 | 61 | ||
| 66 | for ( | 62 | for ( |
| 67 | token_tags[start_token..end_token], | 63 | ast.tokens.items(.tag)[start_token..end_token], |
| 68 | token_starts[start_token..end_token], | 64 | ast.tokens.items(.start)[start_token..end_token], |
| 69 | start_token.., | 65 | start_token.., |
| 70 | ) |tag, start, token_index| { | 66 | ) |tag, start, token_index| { |
| 71 | const between = ast.source[cursor..start]; | 67 | const between = ast.source[cursor..start]; |
| ... | @@ -184,7 +180,7 @@ pub fn fileSourceHtml( | ... | @@ -184,7 +180,7 @@ pub fn fileSourceHtml( |
| 184 | .identifier => i: { | 180 | .identifier => i: { |
| 185 | if (options.fn_link != .none) { | 181 | if (options.fn_link != .none) { |
| 186 | const fn_link = options.fn_link.get(); | 182 | const fn_link = options.fn_link.get(); |
| 187 | const fn_token = main_tokens[fn_link.ast_node]; | 183 | const fn_token = ast.nodeMainToken(fn_link.ast_node); |
| 188 | if (token_index == fn_token + 1) { | 184 | if (token_index == fn_token + 1) { |
| 189 | try out.appendSlice(gpa, "<a class=\"tok-fn\" href=\"#"); | 185 | try out.appendSlice(gpa, "<a class=\"tok-fn\" href=\"#"); |
| 190 | _ = missing_feature_url_escape; | 186 | _ = missing_feature_url_escape; |
| ... | @@ -196,7 +192,7 @@ pub fn fileSourceHtml( | ... | @@ -196,7 +192,7 @@ pub fn fileSourceHtml( |
| 196 | } | 192 | } |
| 197 | } | 193 | } |
| 198 | 194 | ||
| 199 | if (token_index > 0 and token_tags[token_index - 1] == .keyword_fn) { | 195 | if (token_index > 0 and ast.tokenTag(token_index - 1) == .keyword_fn) { |
| 200 | try out.appendSlice(gpa, "<span class=\"tok-fn\">"); | 196 | try out.appendSlice(gpa, "<span class=\"tok-fn\">"); |
| 201 | try appendEscaped(out, slice); | 197 | try appendEscaped(out, slice); |
| 202 | try out.appendSlice(gpa, "</span>"); | 198 | try out.appendSlice(gpa, "</span>"); |
| ... | @@ -358,16 +354,11 @@ fn walkFieldAccesses( | ... | @@ -358,16 +354,11 @@ fn walkFieldAccesses( |
| 358 | node: Ast.Node.Index, | 354 | node: Ast.Node.Index, |
| 359 | ) Oom!void { | 355 | ) Oom!void { |
| 360 | const ast = file_index.get_ast(); | 356 | const ast = file_index.get_ast(); |
| 361 | const node_tags = ast.nodes.items(.tag); | 357 | assert(ast.nodeTag(node) == .field_access); |
| 362 | assert(node_tags[node] == .field_access); | 358 | const object_node, const field_ident = ast.nodeData(node).node_and_token; |
| 363 | const node_datas = ast.nodes.items(.data); | 359 | switch (ast.nodeTag(object_node)) { |
| 364 | const main_tokens = ast.nodes.items(.main_token); | ||
| 365 | const object_node = node_datas[node].lhs; | ||
| 366 | const dot_token = main_tokens[node]; | ||
| 367 | const field_ident = dot_token + 1; | ||
| 368 | switch (node_tags[object_node]) { | ||
| 369 | .identifier => { | 360 | .identifier => { |
| 370 | const lhs_ident = main_tokens[object_node]; | 361 | const lhs_ident = ast.nodeMainToken(object_node); |
| 371 | try resolveIdentLink(file_index, out, lhs_ident); | 362 | try resolveIdentLink(file_index, out, lhs_ident); |
| 372 | }, | 363 | }, |
| 373 | .field_access => { | 364 | .field_access => { |
lib/docs/wasm/main.zig+34-48| ... | @@ -124,7 +124,9 @@ fn query_exec_fallible(query: []const u8, ignore_case: bool) !void { | ... | @@ -124,7 +124,9 @@ fn query_exec_fallible(query: []const u8, ignore_case: bool) !void { |
| 124 | @memcpy(g.full_path_search_text_lower.items, g.full_path_search_text.items); | 124 | @memcpy(g.full_path_search_text_lower.items, g.full_path_search_text.items); |
| 125 | 125 | ||
| 126 | const ast = decl.file.get_ast(); | 126 | const ast = decl.file.get_ast(); |
| 127 | try collect_docs(&g.doc_search_text, ast, info.first_doc_comment); | 127 | if (info.first_doc_comment.unwrap()) |first_doc_comment| { |
| 128 | try collect_docs(&g.doc_search_text, ast, first_doc_comment); | ||
| 129 | } | ||
| 128 | 130 | ||
| 129 | if (ignore_case) { | 131 | if (ignore_case) { |
| 130 | ascii_lower(g.full_path_search_text_lower.items); | 132 | ascii_lower(g.full_path_search_text_lower.items); |
| ... | @@ -227,18 +229,15 @@ const ErrorIdentifier = packed struct(u64) { | ... | @@ -227,18 +229,15 @@ const ErrorIdentifier = packed struct(u64) { |
| 227 | fn hasDocs(ei: ErrorIdentifier) bool { | 229 | fn hasDocs(ei: ErrorIdentifier) bool { |
| 228 | const decl_index = ei.decl_index; | 230 | const decl_index = ei.decl_index; |
| 229 | const ast = decl_index.get().file.get_ast(); | 231 | const ast = decl_index.get().file.get_ast(); |
| 230 | const token_tags = ast.tokens.items(.tag); | ||
| 231 | const token_index = ei.token_index; | 232 | const token_index = ei.token_index; |
| 232 | if (token_index == 0) return false; | 233 | if (token_index == 0) return false; |
| 233 | return token_tags[token_index - 1] == .doc_comment; | 234 | return ast.tokenTag(token_index - 1) == .doc_comment; |
| 234 | } | 235 | } |
| 235 | 236 | ||
| 236 | fn html(ei: ErrorIdentifier, base_decl: Decl.Index, out: *std.ArrayListUnmanaged(u8)) Oom!void { | 237 | fn html(ei: ErrorIdentifier, base_decl: Decl.Index, out: *std.ArrayListUnmanaged(u8)) Oom!void { |
| 237 | const decl_index = ei.decl_index; | 238 | const decl_index = ei.decl_index; |
| 238 | const ast = decl_index.get().file.get_ast(); | 239 | const ast = decl_index.get().file.get_ast(); |
| 239 | const name = ast.tokenSlice(ei.token_index); | 240 | const name = ast.tokenSlice(ei.token_index); |
| 240 | const first_doc_comment = Decl.findFirstDocComment(ast, ei.token_index); | ||
| 241 | const has_docs = ast.tokens.items(.tag)[first_doc_comment] == .doc_comment; | ||
| 242 | const has_link = base_decl != decl_index; | 241 | const has_link = base_decl != decl_index; |
| 243 | 242 | ||
| 244 | try out.appendSlice(gpa, "<dt>"); | 243 | try out.appendSlice(gpa, "<dt>"); |
| ... | @@ -253,7 +252,7 @@ const ErrorIdentifier = packed struct(u64) { | ... | @@ -253,7 +252,7 @@ const ErrorIdentifier = packed struct(u64) { |
| 253 | } | 252 | } |
| 254 | try out.appendSlice(gpa, "</dt>"); | 253 | try out.appendSlice(gpa, "</dt>"); |
| 255 | 254 | ||
| 256 | if (has_docs) { | 255 | if (Decl.findFirstDocComment(ast, ei.token_index).unwrap()) |first_doc_comment| { |
| 257 | try out.appendSlice(gpa, "<dd>"); | 256 | try out.appendSlice(gpa, "<dd>"); |
| 258 | try render_docs(out, decl_index, first_doc_comment, false); | 257 | try render_docs(out, decl_index, first_doc_comment, false); |
| 259 | try out.appendSlice(gpa, "</dd>"); | 258 | try out.appendSlice(gpa, "</dd>"); |
| ... | @@ -319,17 +318,16 @@ fn addErrorsFromExpr( | ... | @@ -319,17 +318,16 @@ fn addErrorsFromExpr( |
| 319 | ) Oom!void { | 318 | ) Oom!void { |
| 320 | const decl = decl_index.get(); | 319 | const decl = decl_index.get(); |
| 321 | const ast = decl.file.get_ast(); | 320 | const ast = decl.file.get_ast(); |
| 322 | const node_tags = ast.nodes.items(.tag); | ||
| 323 | const node_datas = ast.nodes.items(.data); | ||
| 324 | 321 | ||
| 325 | switch (decl.file.categorize_expr(node)) { | 322 | switch (decl.file.categorize_expr(node)) { |
| 326 | .error_set => |n| switch (node_tags[n]) { | 323 | .error_set => |n| switch (ast.nodeTag(n)) { |
| 327 | .error_set_decl => { | 324 | .error_set_decl => { |
| 328 | try addErrorsFromNode(decl_index, out, node); | 325 | try addErrorsFromNode(decl_index, out, node); |
| 329 | }, | 326 | }, |
| 330 | .merge_error_sets => { | 327 | .merge_error_sets => { |
| 331 | try addErrorsFromExpr(decl_index, out, node_datas[node].lhs); | 328 | const lhs, const rhs = ast.nodeData(n).node_and_node; |
| 332 | try addErrorsFromExpr(decl_index, out, node_datas[node].rhs); | 329 | try addErrorsFromExpr(decl_index, out, lhs); |
| 330 | try addErrorsFromExpr(decl_index, out, rhs); | ||
| 333 | }, | 331 | }, |
| 334 | else => unreachable, | 332 | else => unreachable, |
| 335 | }, | 333 | }, |
| ... | @@ -347,11 +345,9 @@ fn addErrorsFromNode( | ... | @@ -347,11 +345,9 @@ fn addErrorsFromNode( |
| 347 | ) Oom!void { | 345 | ) Oom!void { |
| 348 | const decl = decl_index.get(); | 346 | const decl = decl_index.get(); |
| 349 | const ast = decl.file.get_ast(); | 347 | const ast = decl.file.get_ast(); |
| 350 | const main_tokens = ast.nodes.items(.main_token); | 348 | const error_token = ast.nodeMainToken(node); |
| 351 | const token_tags = ast.tokens.items(.tag); | ||
| 352 | const error_token = main_tokens[node]; | ||
| 353 | var tok_i = error_token + 2; | 349 | var tok_i = error_token + 2; |
| 354 | while (true) : (tok_i += 1) switch (token_tags[tok_i]) { | 350 | while (true) : (tok_i += 1) switch (ast.tokenTag(tok_i)) { |
| 355 | .doc_comment, .comma => {}, | 351 | .doc_comment, .comma => {}, |
| 356 | .identifier => { | 352 | .identifier => { |
| 357 | const name = ast.tokenSlice(tok_i); | 353 | const name = ast.tokenSlice(tok_i); |
| ... | @@ -391,15 +387,13 @@ fn decl_fields_fallible(decl_index: Decl.Index) ![]Ast.Node.Index { | ... | @@ -391,15 +387,13 @@ fn decl_fields_fallible(decl_index: Decl.Index) ![]Ast.Node.Index { |
| 391 | 387 | ||
| 392 | switch (decl.categorize()) { | 388 | switch (decl.categorize()) { |
| 393 | .type_function => { | 389 | .type_function => { |
| 394 | const node_tags = ast.nodes.items(.tag); | ||
| 395 | |||
| 396 | // If the type function returns a reference to another type function, get the fields from there | 390 | // If the type function returns a reference to another type function, get the fields from there |
| 397 | if (decl.get_type_fn_return_type_fn()) |function_decl| { | 391 | if (decl.get_type_fn_return_type_fn()) |function_decl| { |
| 398 | return decl_fields_fallible(function_decl); | 392 | return decl_fields_fallible(function_decl); |
| 399 | } | 393 | } |
| 400 | // If the type function returns a container, such as a `struct`, read that container's fields | 394 | // If the type function returns a container, such as a `struct`, read that container's fields |
| 401 | if (decl.get_type_fn_return_expr()) |return_expr| { | 395 | if (decl.get_type_fn_return_expr()) |return_expr| { |
| 402 | switch (node_tags[return_expr]) { | 396 | switch (ast.nodeTag(return_expr)) { |
| 403 | .container_decl, .container_decl_trailing, .container_decl_two, .container_decl_two_trailing, .container_decl_arg, .container_decl_arg_trailing => { | 397 | .container_decl, .container_decl_trailing, .container_decl_two, .container_decl_two_trailing, .container_decl_arg, .container_decl_arg_trailing => { |
| 404 | return ast_decl_fields_fallible(ast, return_expr); | 398 | return ast_decl_fields_fallible(ast, return_expr); |
| 405 | }, | 399 | }, |
| ... | @@ -420,10 +414,9 @@ fn ast_decl_fields_fallible(ast: *Ast, ast_index: Ast.Node.Index) ![]Ast.Node.In | ... | @@ -420,10 +414,9 @@ fn ast_decl_fields_fallible(ast: *Ast, ast_index: Ast.Node.Index) ![]Ast.Node.In |
| 420 | var result: std.ArrayListUnmanaged(Ast.Node.Index) = .empty; | 414 | var result: std.ArrayListUnmanaged(Ast.Node.Index) = .empty; |
| 421 | }; | 415 | }; |
| 422 | g.result.clearRetainingCapacity(); | 416 | g.result.clearRetainingCapacity(); |
| 423 | const node_tags = ast.nodes.items(.tag); | ||
| 424 | var buf: [2]Ast.Node.Index = undefined; | 417 | var buf: [2]Ast.Node.Index = undefined; |
| 425 | const container_decl = ast.fullContainerDecl(&buf, ast_index) orelse return &.{}; | 418 | const container_decl = ast.fullContainerDecl(&buf, ast_index) orelse return &.{}; |
| 426 | for (container_decl.ast.members) |member_node| switch (node_tags[member_node]) { | 419 | for (container_decl.ast.members) |member_node| switch (ast.nodeTag(member_node)) { |
| 427 | .container_field_init, | 420 | .container_field_init, |
| 428 | .container_field_align, | 421 | .container_field_align, |
| 429 | .container_field, | 422 | .container_field, |
| ... | @@ -478,9 +471,8 @@ fn decl_field_html_fallible( | ... | @@ -478,9 +471,8 @@ fn decl_field_html_fallible( |
| 478 | try out.appendSlice(gpa, "</code></pre>"); | 471 | try out.appendSlice(gpa, "</code></pre>"); |
| 479 | 472 | ||
| 480 | const field = ast.fullContainerField(field_node).?; | 473 | const field = ast.fullContainerField(field_node).?; |
| 481 | const first_doc_comment = Decl.findFirstDocComment(ast, field.firstToken()); | ||
| 482 | 474 | ||
| 483 | if (ast.tokens.items(.tag)[first_doc_comment] == .doc_comment) { | 475 | if (Decl.findFirstDocComment(ast, field.firstToken()).unwrap()) |first_doc_comment| { |
| 484 | try out.appendSlice(gpa, "<div class=\"fieldDocs\">"); | 476 | try out.appendSlice(gpa, "<div class=\"fieldDocs\">"); |
| 485 | try render_docs(out, decl_index, first_doc_comment, false); | 477 | try render_docs(out, decl_index, first_doc_comment, false); |
| 486 | try out.appendSlice(gpa, "</div>"); | 478 | try out.appendSlice(gpa, "</div>"); |
| ... | @@ -494,14 +486,13 @@ fn decl_param_html_fallible( | ... | @@ -494,14 +486,13 @@ fn decl_param_html_fallible( |
| 494 | ) !void { | 486 | ) !void { |
| 495 | const decl = decl_index.get(); | 487 | const decl = decl_index.get(); |
| 496 | const ast = decl.file.get_ast(); | 488 | const ast = decl.file.get_ast(); |
| 497 | const token_tags = ast.tokens.items(.tag); | ||
| 498 | const colon = ast.firstToken(param_node) - 1; | 489 | const colon = ast.firstToken(param_node) - 1; |
| 499 | const name_token = colon - 1; | 490 | const name_token = colon - 1; |
| 500 | const first_doc_comment = f: { | 491 | const first_doc_comment = f: { |
| 501 | var it = ast.firstToken(param_node); | 492 | var it = ast.firstToken(param_node); |
| 502 | while (it > 0) { | 493 | while (it > 0) { |
| 503 | it -= 1; | 494 | it -= 1; |
| 504 | switch (token_tags[it]) { | 495 | switch (ast.tokenTag(it)) { |
| 505 | .doc_comment, .colon, .identifier, .keyword_comptime, .keyword_noalias => {}, | 496 | .doc_comment, .colon, .identifier, .keyword_comptime, .keyword_noalias => {}, |
| 506 | else => break, | 497 | else => break, |
| 507 | } | 498 | } |
| ... | @@ -516,7 +507,7 @@ fn decl_param_html_fallible( | ... | @@ -516,7 +507,7 @@ fn decl_param_html_fallible( |
| 516 | try fileSourceHtml(decl.file, out, param_node, .{}); | 507 | try fileSourceHtml(decl.file, out, param_node, .{}); |
| 517 | try out.appendSlice(gpa, "</code></pre>"); | 508 | try out.appendSlice(gpa, "</code></pre>"); |
| 518 | 509 | ||
| 519 | if (ast.tokens.items(.tag)[first_doc_comment] == .doc_comment) { | 510 | if (ast.tokenTag(first_doc_comment) == .doc_comment) { |
| 520 | try out.appendSlice(gpa, "<div class=\"fieldDocs\">"); | 511 | try out.appendSlice(gpa, "<div class=\"fieldDocs\">"); |
| 521 | try render_docs(out, decl_index, first_doc_comment, false); | 512 | try render_docs(out, decl_index, first_doc_comment, false); |
| 522 | try out.appendSlice(gpa, "</div>"); | 513 | try out.appendSlice(gpa, "</div>"); |
| ... | @@ -526,10 +517,8 @@ fn decl_param_html_fallible( | ... | @@ -526,10 +517,8 @@ fn decl_param_html_fallible( |
| 526 | export fn decl_fn_proto_html(decl_index: Decl.Index, linkify_fn_name: bool) String { | 517 | export fn decl_fn_proto_html(decl_index: Decl.Index, linkify_fn_name: bool) String { |
| 527 | const decl = decl_index.get(); | 518 | const decl = decl_index.get(); |
| 528 | const ast = decl.file.get_ast(); | 519 | const ast = decl.file.get_ast(); |
| 529 | const node_tags = ast.nodes.items(.tag); | 520 | const proto_node = switch (ast.nodeTag(decl.ast_node)) { |
| 530 | const node_datas = ast.nodes.items(.data); | 521 | .fn_decl => ast.nodeData(decl.ast_node).node_and_node[0], |
| 531 | const proto_node = switch (node_tags[decl.ast_node]) { | ||
| 532 | .fn_decl => node_datas[decl.ast_node].lhs, | ||
| 533 | 522 | ||
| 534 | .fn_proto, | 523 | .fn_proto, |
| 535 | .fn_proto_one, | 524 | .fn_proto_one, |
| ... | @@ -586,17 +575,16 @@ export fn decl_parent(decl_index: Decl.Index) Decl.Index { | ... | @@ -586,17 +575,16 @@ export fn decl_parent(decl_index: Decl.Index) Decl.Index { |
| 586 | return decl.parent; | 575 | return decl.parent; |
| 587 | } | 576 | } |
| 588 | 577 | ||
| 589 | export fn fn_error_set(decl_index: Decl.Index) Ast.Node.Index { | 578 | export fn fn_error_set(decl_index: Decl.Index) Ast.Node.OptionalIndex { |
| 590 | const decl = decl_index.get(); | 579 | const decl = decl_index.get(); |
| 591 | const ast = decl.file.get_ast(); | 580 | const ast = decl.file.get_ast(); |
| 592 | var buf: [1]Ast.Node.Index = undefined; | 581 | var buf: [1]Ast.Node.Index = undefined; |
| 593 | const full = ast.fullFnProto(&buf, decl.ast_node).?; | 582 | const full = ast.fullFnProto(&buf, decl.ast_node).?; |
| 594 | const node_tags = ast.nodes.items(.tag); | 583 | const return_type = full.ast.return_type.unwrap().?; |
| 595 | const node_datas = ast.nodes.items(.data); | 584 | return switch (ast.nodeTag(return_type)) { |
| 596 | return switch (node_tags[full.ast.return_type]) { | 585 | .error_set_decl => return_type.toOptional(), |
| 597 | .error_set_decl => full.ast.return_type, | 586 | .error_union => ast.nodeData(return_type).node_and_node[0].toOptional(), |
| 598 | .error_union => node_datas[full.ast.return_type].lhs, | 587 | else => .none, |
| 599 | else => 0, | ||
| 600 | }; | 588 | }; |
| 601 | } | 589 | } |
| 602 | 590 | ||
| ... | @@ -609,21 +597,19 @@ export fn decl_file_path(decl_index: Decl.Index) String { | ... | @@ -609,21 +597,19 @@ export fn decl_file_path(decl_index: Decl.Index) String { |
| 609 | export fn decl_category_name(decl_index: Decl.Index) String { | 597 | export fn decl_category_name(decl_index: Decl.Index) String { |
| 610 | const decl = decl_index.get(); | 598 | const decl = decl_index.get(); |
| 611 | const ast = decl.file.get_ast(); | 599 | const ast = decl.file.get_ast(); |
| 612 | const token_tags = ast.tokens.items(.tag); | ||
| 613 | const name = switch (decl.categorize()) { | 600 | const name = switch (decl.categorize()) { |
| 614 | .namespace, .container => |node| { | 601 | .namespace, .container => |node| { |
| 615 | const node_tags = ast.nodes.items(.tag); | 602 | if (ast.nodeTag(decl.ast_node) == .root) |
| 616 | if (node_tags[decl.ast_node] == .root) | ||
| 617 | return String.init("struct"); | 603 | return String.init("struct"); |
| 618 | string_result.clearRetainingCapacity(); | 604 | string_result.clearRetainingCapacity(); |
| 619 | var buf: [2]Ast.Node.Index = undefined; | 605 | var buf: [2]Ast.Node.Index = undefined; |
| 620 | const container_decl = ast.fullContainerDecl(&buf, node).?; | 606 | const container_decl = ast.fullContainerDecl(&buf, node).?; |
| 621 | if (container_decl.layout_token) |t| { | 607 | if (container_decl.layout_token) |t| { |
| 622 | if (token_tags[t] == .keyword_extern) { | 608 | if (ast.tokenTag(t) == .keyword_extern) { |
| 623 | string_result.appendSlice(gpa, "extern ") catch @panic("OOM"); | 609 | string_result.appendSlice(gpa, "extern ") catch @panic("OOM"); |
| 624 | } | 610 | } |
| 625 | } | 611 | } |
| 626 | const main_token_tag = token_tags[container_decl.ast.main_token]; | 612 | const main_token_tag = ast.tokenTag(container_decl.ast.main_token); |
| 627 | string_result.appendSlice(gpa, main_token_tag.lexeme().?) catch @panic("OOM"); | 613 | string_result.appendSlice(gpa, main_token_tag.lexeme().?) catch @panic("OOM"); |
| 628 | return String.init(string_result.items); | 614 | return String.init(string_result.items); |
| 629 | }, | 615 | }, |
| ... | @@ -656,7 +642,9 @@ export fn decl_name(decl_index: Decl.Index) String { | ... | @@ -656,7 +642,9 @@ export fn decl_name(decl_index: Decl.Index) String { |
| 656 | export fn decl_docs_html(decl_index: Decl.Index, short: bool) String { | 642 | export fn decl_docs_html(decl_index: Decl.Index, short: bool) String { |
| 657 | const decl = decl_index.get(); | 643 | const decl = decl_index.get(); |
| 658 | string_result.clearRetainingCapacity(); | 644 | string_result.clearRetainingCapacity(); |
| 659 | render_docs(&string_result, decl_index, decl.extra_info().first_doc_comment, short) catch @panic("OOM"); | 645 | if (decl.extra_info().first_doc_comment.unwrap()) |first_doc_comment| { |
| 646 | render_docs(&string_result, decl_index, first_doc_comment, short) catch @panic("OOM"); | ||
| 647 | } | ||
| 660 | return String.init(string_result.items); | 648 | return String.init(string_result.items); |
| 661 | } | 649 | } |
| 662 | 650 | ||
| ... | @@ -665,10 +653,9 @@ fn collect_docs( | ... | @@ -665,10 +653,9 @@ fn collect_docs( |
| 665 | ast: *const Ast, | 653 | ast: *const Ast, |
| 666 | first_doc_comment: Ast.TokenIndex, | 654 | first_doc_comment: Ast.TokenIndex, |
| 667 | ) Oom!void { | 655 | ) Oom!void { |
| 668 | const token_tags = ast.tokens.items(.tag); | ||
| 669 | list.clearRetainingCapacity(); | 656 | list.clearRetainingCapacity(); |
| 670 | var it = first_doc_comment; | 657 | var it = first_doc_comment; |
| 671 | while (true) : (it += 1) switch (token_tags[it]) { | 658 | while (true) : (it += 1) switch (ast.tokenTag(it)) { |
| 672 | .doc_comment, .container_doc_comment => { | 659 | .doc_comment, .container_doc_comment => { |
| 673 | // It is tempting to trim this string but think carefully about how | 660 | // It is tempting to trim this string but think carefully about how |
| 674 | // that will affect the markdown parser. | 661 | // that will affect the markdown parser. |
| ... | @@ -687,12 +674,11 @@ fn render_docs( | ... | @@ -687,12 +674,11 @@ fn render_docs( |
| 687 | ) Oom!void { | 674 | ) Oom!void { |
| 688 | const decl = decl_index.get(); | 675 | const decl = decl_index.get(); |
| 689 | const ast = decl.file.get_ast(); | 676 | const ast = decl.file.get_ast(); |
| 690 | const token_tags = ast.tokens.items(.tag); | ||
| 691 | 677 | ||
| 692 | var parser = try markdown.Parser.init(gpa); | 678 | var parser = try markdown.Parser.init(gpa); |
| 693 | defer parser.deinit(); | 679 | defer parser.deinit(); |
| 694 | var it = first_doc_comment; | 680 | var it = first_doc_comment; |
| 695 | while (true) : (it += 1) switch (token_tags[it]) { | 681 | while (true) : (it += 1) switch (ast.tokenTag(it)) { |
| 696 | .doc_comment, .container_doc_comment => { | 682 | .doc_comment, .container_doc_comment => { |
| 697 | const line = ast.tokenSlice(it)[3..]; | 683 | const line = ast.tokenSlice(it)[3..]; |
| 698 | if (short and line.len == 0) break; | 684 | if (short and line.len == 0) break; |
| ... | @@ -767,9 +753,9 @@ export fn decl_type_html(decl_index: Decl.Index) String { | ... | @@ -767,9 +753,9 @@ export fn decl_type_html(decl_index: Decl.Index) String { |
| 767 | t: { | 753 | t: { |
| 768 | // If there is an explicit type, use it. | 754 | // If there is an explicit type, use it. |
| 769 | if (ast.fullVarDecl(decl.ast_node)) |var_decl| { | 755 | if (ast.fullVarDecl(decl.ast_node)) |var_decl| { |
| 770 | if (var_decl.ast.type_node != 0) { | 756 | if (var_decl.ast.type_node.unwrap()) |type_node| { |
| 771 | string_result.appendSlice(gpa, "<code>") catch @panic("OOM"); | 757 | string_result.appendSlice(gpa, "<code>") catch @panic("OOM"); |
| 772 | fileSourceHtml(decl.file, &string_result, var_decl.ast.type_node, .{ | 758 | fileSourceHtml(decl.file, &string_result, type_node, .{ |
| 773 | .skip_comments = true, | 759 | .skip_comments = true, |
| 774 | .collapse_whitespace = true, | 760 | .collapse_whitespace = true, |
| 775 | }) catch |e| { | 761 | }) catch |e| { |
lib/std/zig/Ast.zig+965-844| ... | @@ -8,15 +8,12 @@ | ... | @@ -8,15 +8,12 @@ |
| 8 | source: [:0]const u8, | 8 | source: [:0]const u8, |
| 9 | 9 | ||
| 10 | tokens: TokenList.Slice, | 10 | tokens: TokenList.Slice, |
| 11 | /// The root AST node is assumed to be index 0. Since there can be no | ||
| 12 | /// references to the root node, this means 0 is available to indicate null. | ||
| 13 | nodes: NodeList.Slice, | 11 | nodes: NodeList.Slice, |
| 14 | extra_data: []Node.Index, | 12 | extra_data: []u32, |
| 15 | mode: Mode = .zig, | 13 | mode: Mode = .zig, |
| 16 | 14 | ||
| 17 | errors: []const Error, | 15 | errors: []const Error, |
| 18 | 16 | ||
| 19 | pub const TokenIndex = u32; | ||
| 20 | pub const ByteOffset = u32; | 17 | pub const ByteOffset = u32; |
| 21 | 18 | ||
| 22 | pub const TokenList = std.MultiArrayList(struct { | 19 | pub const TokenList = std.MultiArrayList(struct { |
| ... | @@ -25,6 +22,91 @@ pub const TokenList = std.MultiArrayList(struct { | ... | @@ -25,6 +22,91 @@ pub const TokenList = std.MultiArrayList(struct { |
| 25 | }); | 22 | }); |
| 26 | pub const NodeList = std.MultiArrayList(Node); | 23 | pub const NodeList = std.MultiArrayList(Node); |
| 27 | 24 | ||
| 25 | /// Index into `tokens`. | ||
| 26 | pub const TokenIndex = u32; | ||
| 27 | |||
| 28 | /// Index into `tokens`, or null. | ||
| 29 | pub const OptionalTokenIndex = enum(u32) { | ||
| 30 | none = std.math.maxInt(u32), | ||
| 31 | _, | ||
| 32 | |||
| 33 | pub fn unwrap(oti: OptionalTokenIndex) ?TokenIndex { | ||
| 34 | return if (oti == .none) null else @intFromEnum(oti); | ||
| 35 | } | ||
| 36 | |||
| 37 | pub fn fromToken(ti: TokenIndex) OptionalTokenIndex { | ||
| 38 | return @enumFromInt(ti); | ||
| 39 | } | ||
| 40 | |||
| 41 | pub fn fromOptional(oti: ?TokenIndex) OptionalTokenIndex { | ||
| 42 | return if (oti) |ti| @enumFromInt(ti) else .none; | ||
| 43 | } | ||
| 44 | }; | ||
| 45 | |||
| 46 | /// A relative token index. | ||
| 47 | pub const TokenOffset = enum(i32) { | ||
| 48 | zero = 0, | ||
| 49 | _, | ||
| 50 | |||
| 51 | pub fn init(base: TokenIndex, destination: TokenIndex) TokenOffset { | ||
| 52 | const base_i64: i64 = base; | ||
| 53 | const destination_i64: i64 = destination; | ||
| 54 | return @enumFromInt(destination_i64 - base_i64); | ||
| 55 | } | ||
| 56 | |||
| 57 | pub fn toOptional(to: TokenOffset) OptionalTokenOffset { | ||
| 58 | const result: OptionalTokenOffset = @enumFromInt(@intFromEnum(to)); | ||
| 59 | assert(result != .none); | ||
| 60 | return result; | ||
| 61 | } | ||
| 62 | |||
| 63 | pub fn toAbsolute(offset: TokenOffset, base: TokenIndex) TokenIndex { | ||
| 64 | return @intCast(@as(i64, base) + @intFromEnum(offset)); | ||
| 65 | } | ||
| 66 | }; | ||
| 67 | |||
| 68 | /// A relative token index, or null. | ||
| 69 | pub const OptionalTokenOffset = enum(i32) { | ||
| 70 | none = std.math.maxInt(i32), | ||
| 71 | _, | ||
| 72 | |||
| 73 | pub fn unwrap(oto: OptionalTokenOffset) ?TokenOffset { | ||
| 74 | return if (oto == .none) null else @enumFromInt(@intFromEnum(oto)); | ||
| 75 | } | ||
| 76 | }; | ||
| 77 | |||
| 78 | pub fn tokenTag(tree: *const Ast, token_index: TokenIndex) Token.Tag { | ||
| 79 | return tree.tokens.items(.tag)[token_index]; | ||
| 80 | } | ||
| 81 | |||
| 82 | pub fn tokenStart(tree: *const Ast, token_index: TokenIndex) ByteOffset { | ||
| 83 | return tree.tokens.items(.start)[token_index]; | ||
| 84 | } | ||
| 85 | |||
| 86 | pub fn nodeTag(tree: *const Ast, node: Node.Index) Node.Tag { | ||
| 87 | return tree.nodes.items(.tag)[@intFromEnum(node)]; | ||
| 88 | } | ||
| 89 | |||
| 90 | pub fn nodeMainToken(tree: *const Ast, node: Node.Index) TokenIndex { | ||
| 91 | return tree.nodes.items(.main_token)[@intFromEnum(node)]; | ||
| 92 | } | ||
| 93 | |||
| 94 | pub fn nodeData(tree: *const Ast, node: Node.Index) Node.Data { | ||
| 95 | return tree.nodes.items(.data)[@intFromEnum(node)]; | ||
| 96 | } | ||
| 97 | |||
| 98 | pub fn isTokenPrecededByTags( | ||
| 99 | tree: *const Ast, | ||
| 100 | ti: TokenIndex, | ||
| 101 | expected_token_tags: []const Token.Tag, | ||
| 102 | ) bool { | ||
| 103 | return std.mem.endsWith( | ||
| 104 | Token.Tag, | ||
| 105 | tree.tokens.items(.tag)[0..ti], | ||
| 106 | expected_token_tags, | ||
| 107 | ); | ||
| 108 | } | ||
| 109 | |||
| 28 | pub const Location = struct { | 110 | pub const Location = struct { |
| 29 | line: usize, | 111 | line: usize, |
| 30 | column: usize, | 112 | column: usize, |
| ... | @@ -77,8 +159,7 @@ pub fn parse(gpa: Allocator, source: [:0]const u8, mode: Mode) Allocator.Error!A | ... | @@ -77,8 +159,7 @@ pub fn parse(gpa: Allocator, source: [:0]const u8, mode: Mode) Allocator.Error!A |
| 77 | var parser: Parse = .{ | 159 | var parser: Parse = .{ |
| 78 | .source = source, | 160 | .source = source, |
| 79 | .gpa = gpa, | 161 | .gpa = gpa, |
| 80 | .token_tags = tokens.items(.tag), | 162 | .tokens = tokens.slice(), |
| 81 | .token_starts = tokens.items(.start), | ||
| 82 | .errors = .{}, | 163 | .errors = .{}, |
| 83 | .nodes = .{}, | 164 | .nodes = .{}, |
| 84 | .extra_data = .{}, | 165 | .extra_data = .{}, |
| ... | @@ -143,7 +224,7 @@ pub fn tokenLocation(self: Ast, start_offset: ByteOffset, token_index: TokenInde | ... | @@ -143,7 +224,7 @@ pub fn tokenLocation(self: Ast, start_offset: ByteOffset, token_index: TokenInde |
| 143 | .line_start = start_offset, | 224 | .line_start = start_offset, |
| 144 | .line_end = self.source.len, | 225 | .line_end = self.source.len, |
| 145 | }; | 226 | }; |
| 146 | const token_start = self.tokens.items(.start)[token_index]; | 227 | const token_start = self.tokenStart(token_index); |
| 147 | 228 | ||
| 148 | // Scan to by line until we go past the token start | 229 | // Scan to by line until we go past the token start |
| 149 | while (std.mem.indexOfScalarPos(u8, self.source, loc.line_start, '\n')) |i| { | 230 | while (std.mem.indexOfScalarPos(u8, self.source, loc.line_start, '\n')) |i| { |
| ... | @@ -175,9 +256,7 @@ pub fn tokenLocation(self: Ast, start_offset: ByteOffset, token_index: TokenInde | ... | @@ -175,9 +256,7 @@ pub fn tokenLocation(self: Ast, start_offset: ByteOffset, token_index: TokenInde |
| 175 | } | 256 | } |
| 176 | 257 | ||
| 177 | pub fn tokenSlice(tree: Ast, token_index: TokenIndex) []const u8 { | 258 | pub fn tokenSlice(tree: Ast, token_index: TokenIndex) []const u8 { |
| 178 | const token_starts = tree.tokens.items(.start); | 259 | const token_tag = tree.tokenTag(token_index); |
| 179 | const token_tags = tree.tokens.items(.tag); | ||
| 180 | const token_tag = token_tags[token_index]; | ||
| 181 | 260 | ||
| 182 | // Many tokens can be determined entirely by their tag. | 261 | // Many tokens can be determined entirely by their tag. |
| 183 | if (token_tag.lexeme()) |lexeme| { | 262 | if (token_tag.lexeme()) |lexeme| { |
| ... | @@ -187,33 +266,54 @@ pub fn tokenSlice(tree: Ast, token_index: TokenIndex) []const u8 { | ... | @@ -187,33 +266,54 @@ pub fn tokenSlice(tree: Ast, token_index: TokenIndex) []const u8 { |
| 187 | // For some tokens, re-tokenization is needed to find the end. | 266 | // For some tokens, re-tokenization is needed to find the end. |
| 188 | var tokenizer: std.zig.Tokenizer = .{ | 267 | var tokenizer: std.zig.Tokenizer = .{ |
| 189 | .buffer = tree.source, | 268 | .buffer = tree.source, |
| 190 | .index = token_starts[token_index], | 269 | .index = tree.tokenStart(token_index), |
| 191 | }; | 270 | }; |
| 192 | const token = tokenizer.next(); | 271 | const token = tokenizer.next(); |
| 193 | assert(token.tag == token_tag); | 272 | assert(token.tag == token_tag); |
| 194 | return tree.source[token.loc.start..token.loc.end]; | 273 | return tree.source[token.loc.start..token.loc.end]; |
| 195 | } | 274 | } |
| 196 | 275 | ||
| 197 | pub fn extraData(tree: Ast, index: usize, comptime T: type) T { | 276 | pub fn extraDataSlice(tree: Ast, range: Node.SubRange, comptime T: type) []const T { |
| 277 | return @ptrCast(tree.extra_data[@intFromEnum(range.start)..@intFromEnum(range.end)]); | ||
| 278 | } | ||
| 279 | |||
| 280 | pub fn extraDataSliceWithLen(tree: Ast, start: ExtraIndex, len: u32, comptime T: type) []const T { | ||
| 281 | return @ptrCast(tree.extra_data[@intFromEnum(start)..][0..len]); | ||
| 282 | } | ||
| 283 | |||
| 284 | pub fn extraData(tree: Ast, index: ExtraIndex, comptime T: type) T { | ||
| 198 | const fields = std.meta.fields(T); | 285 | const fields = std.meta.fields(T); |
| 199 | var result: T = undefined; | 286 | var result: T = undefined; |
| 200 | inline for (fields, 0..) |field, i| { | 287 | inline for (fields, 0..) |field, i| { |
| 201 | comptime assert(field.type == Node.Index); | 288 | @field(result, field.name) = switch (field.type) { |
| 202 | @field(result, field.name) = tree.extra_data[index + i]; | 289 | Node.Index, |
| 290 | Node.OptionalIndex, | ||
| 291 | OptionalTokenIndex, | ||
| 292 | ExtraIndex, | ||
| 293 | => @enumFromInt(tree.extra_data[@intFromEnum(index) + i]), | ||
| 294 | TokenIndex => tree.extra_data[@intFromEnum(index) + i], | ||
| 295 | else => @compileError("unexpected field type: " ++ @typeName(field.type)), | ||
| 296 | }; | ||
| 203 | } | 297 | } |
| 204 | return result; | 298 | return result; |
| 205 | } | 299 | } |
| 206 | 300 | ||
| 301 | fn loadOptionalNodesIntoBuffer(comptime size: usize, buffer: *[size]Node.Index, items: [size]Node.OptionalIndex) []Node.Index { | ||
| 302 | for (buffer, items, 0..) |*node, opt_node, i| { | ||
| 303 | node.* = opt_node.unwrap() orelse return buffer[0..i]; | ||
| 304 | } | ||
| 305 | return buffer[0..]; | ||
| 306 | } | ||
| 307 | |||
| 207 | pub fn rootDecls(tree: Ast) []const Node.Index { | 308 | pub fn rootDecls(tree: Ast) []const Node.Index { |
| 208 | const nodes_data = tree.nodes.items(.data); | 309 | switch (tree.mode) { |
| 209 | return switch (tree.mode) { | 310 | .zig => return tree.extraDataSlice(tree.nodeData(.root).extra_range, Node.Index), |
| 210 | .zig => tree.extra_data[nodes_data[0].lhs..nodes_data[0].rhs], | 311 | // Ensure that the returned slice points into the existing memory of the Ast |
| 211 | .zon => (&nodes_data[0].lhs)[0..1], | 312 | .zon => return (&tree.nodes.items(.data)[@intFromEnum(Node.Index.root)].node)[0..1], |
| 212 | }; | 313 | } |
| 213 | } | 314 | } |
| 214 | 315 | ||
| 215 | pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { | 316 | pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { |
| 216 | const token_tags = tree.tokens.items(.tag); | ||
| 217 | switch (parse_error.tag) { | 317 | switch (parse_error.tag) { |
| 218 | .asterisk_after_ptr_deref => { | 318 | .asterisk_after_ptr_deref => { |
| 219 | // Note that the token will point at the `.*` but ideally the source | 319 | // Note that the token will point at the `.*` but ideally the source |
| ... | @@ -228,72 +328,72 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { | ... | @@ -228,72 +328,72 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { |
| 228 | }, | 328 | }, |
| 229 | .expected_block => { | 329 | .expected_block => { |
| 230 | return stream.print("expected block, found '{s}'", .{ | 330 | return stream.print("expected block, found '{s}'", .{ |
| 231 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 331 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 232 | }); | 332 | }); |
| 233 | }, | 333 | }, |
| 234 | .expected_block_or_assignment => { | 334 | .expected_block_or_assignment => { |
| 235 | return stream.print("expected block or assignment, found '{s}'", .{ | 335 | return stream.print("expected block or assignment, found '{s}'", .{ |
| 236 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 336 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 237 | }); | 337 | }); |
| 238 | }, | 338 | }, |
| 239 | .expected_block_or_expr => { | 339 | .expected_block_or_expr => { |
| 240 | return stream.print("expected block or expression, found '{s}'", .{ | 340 | return stream.print("expected block or expression, found '{s}'", .{ |
| 241 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 341 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 242 | }); | 342 | }); |
| 243 | }, | 343 | }, |
| 244 | .expected_block_or_field => { | 344 | .expected_block_or_field => { |
| 245 | return stream.print("expected block or field, found '{s}'", .{ | 345 | return stream.print("expected block or field, found '{s}'", .{ |
| 246 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 346 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 247 | }); | 347 | }); |
| 248 | }, | 348 | }, |
| 249 | .expected_container_members => { | 349 | .expected_container_members => { |
| 250 | return stream.print("expected test, comptime, var decl, or container field, found '{s}'", .{ | 350 | return stream.print("expected test, comptime, var decl, or container field, found '{s}'", .{ |
| 251 | token_tags[parse_error.token].symbol(), | 351 | tree.tokenTag(parse_error.token).symbol(), |
| 252 | }); | 352 | }); |
| 253 | }, | 353 | }, |
| 254 | .expected_expr => { | 354 | .expected_expr => { |
| 255 | return stream.print("expected expression, found '{s}'", .{ | 355 | return stream.print("expected expression, found '{s}'", .{ |
| 256 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 356 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 257 | }); | 357 | }); |
| 258 | }, | 358 | }, |
| 259 | .expected_expr_or_assignment => { | 359 | .expected_expr_or_assignment => { |
| 260 | return stream.print("expected expression or assignment, found '{s}'", .{ | 360 | return stream.print("expected expression or assignment, found '{s}'", .{ |
| 261 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 361 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 262 | }); | 362 | }); |
| 263 | }, | 363 | }, |
| 264 | .expected_expr_or_var_decl => { | 364 | .expected_expr_or_var_decl => { |
| 265 | return stream.print("expected expression or var decl, found '{s}'", .{ | 365 | return stream.print("expected expression or var decl, found '{s}'", .{ |
| 266 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 366 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 267 | }); | 367 | }); |
| 268 | }, | 368 | }, |
| 269 | .expected_fn => { | 369 | .expected_fn => { |
| 270 | return stream.print("expected function, found '{s}'", .{ | 370 | return stream.print("expected function, found '{s}'", .{ |
| 271 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 371 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 272 | }); | 372 | }); |
| 273 | }, | 373 | }, |
| 274 | .expected_inlinable => { | 374 | .expected_inlinable => { |
| 275 | return stream.print("expected 'while' or 'for', found '{s}'", .{ | 375 | return stream.print("expected 'while' or 'for', found '{s}'", .{ |
| 276 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 376 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 277 | }); | 377 | }); |
| 278 | }, | 378 | }, |
| 279 | .expected_labelable => { | 379 | .expected_labelable => { |
| 280 | return stream.print("expected 'while', 'for', 'inline', or '{{', found '{s}'", .{ | 380 | return stream.print("expected 'while', 'for', 'inline', or '{{', found '{s}'", .{ |
| 281 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 381 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 282 | }); | 382 | }); |
| 283 | }, | 383 | }, |
| 284 | .expected_param_list => { | 384 | .expected_param_list => { |
| 285 | return stream.print("expected parameter list, found '{s}'", .{ | 385 | return stream.print("expected parameter list, found '{s}'", .{ |
| 286 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 386 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 287 | }); | 387 | }); |
| 288 | }, | 388 | }, |
| 289 | .expected_prefix_expr => { | 389 | .expected_prefix_expr => { |
| 290 | return stream.print("expected prefix expression, found '{s}'", .{ | 390 | return stream.print("expected prefix expression, found '{s}'", .{ |
| 291 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 391 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 292 | }); | 392 | }); |
| 293 | }, | 393 | }, |
| 294 | .expected_primary_type_expr => { | 394 | .expected_primary_type_expr => { |
| 295 | return stream.print("expected primary type expression, found '{s}'", .{ | 395 | return stream.print("expected primary type expression, found '{s}'", .{ |
| 296 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 396 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 297 | }); | 397 | }); |
| 298 | }, | 398 | }, |
| 299 | .expected_pub_item => { | 399 | .expected_pub_item => { |
| ... | @@ -301,7 +401,7 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { | ... | @@ -301,7 +401,7 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { |
| 301 | }, | 401 | }, |
| 302 | .expected_return_type => { | 402 | .expected_return_type => { |
| 303 | return stream.print("expected return type expression, found '{s}'", .{ | 403 | return stream.print("expected return type expression, found '{s}'", .{ |
| 304 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 404 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 305 | }); | 405 | }); |
| 306 | }, | 406 | }, |
| 307 | .expected_semi_or_else => { | 407 | .expected_semi_or_else => { |
| ... | @@ -312,37 +412,37 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { | ... | @@ -312,37 +412,37 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { |
| 312 | }, | 412 | }, |
| 313 | .expected_statement => { | 413 | .expected_statement => { |
| 314 | return stream.print("expected statement, found '{s}'", .{ | 414 | return stream.print("expected statement, found '{s}'", .{ |
| 315 | token_tags[parse_error.token].symbol(), | 415 | tree.tokenTag(parse_error.token).symbol(), |
| 316 | }); | 416 | }); |
| 317 | }, | 417 | }, |
| 318 | .expected_suffix_op => { | 418 | .expected_suffix_op => { |
| 319 | return stream.print("expected pointer dereference, optional unwrap, or field access, found '{s}'", .{ | 419 | return stream.print("expected pointer dereference, optional unwrap, or field access, found '{s}'", .{ |
| 320 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 420 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 321 | }); | 421 | }); |
| 322 | }, | 422 | }, |
| 323 | .expected_type_expr => { | 423 | .expected_type_expr => { |
| 324 | return stream.print("expected type expression, found '{s}'", .{ | 424 | return stream.print("expected type expression, found '{s}'", .{ |
| 325 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 425 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 326 | }); | 426 | }); |
| 327 | }, | 427 | }, |
| 328 | .expected_var_decl => { | 428 | .expected_var_decl => { |
| 329 | return stream.print("expected variable declaration, found '{s}'", .{ | 429 | return stream.print("expected variable declaration, found '{s}'", .{ |
| 330 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 430 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 331 | }); | 431 | }); |
| 332 | }, | 432 | }, |
| 333 | .expected_var_decl_or_fn => { | 433 | .expected_var_decl_or_fn => { |
| 334 | return stream.print("expected variable declaration or function, found '{s}'", .{ | 434 | return stream.print("expected variable declaration or function, found '{s}'", .{ |
| 335 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 435 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 336 | }); | 436 | }); |
| 337 | }, | 437 | }, |
| 338 | .expected_loop_payload => { | 438 | .expected_loop_payload => { |
| 339 | return stream.print("expected loop payload, found '{s}'", .{ | 439 | return stream.print("expected loop payload, found '{s}'", .{ |
| 340 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 440 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 341 | }); | 441 | }); |
| 342 | }, | 442 | }, |
| 343 | .expected_container => { | 443 | .expected_container => { |
| 344 | return stream.print("expected a struct, enum or union, found '{s}'", .{ | 444 | return stream.print("expected a struct, enum or union, found '{s}'", .{ |
| 345 | token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)].symbol(), | 445 | tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), |
| 346 | }); | 446 | }); |
| 347 | }, | 447 | }, |
| 348 | .extern_fn_body => { | 448 | .extern_fn_body => { |
| ... | @@ -365,7 +465,7 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { | ... | @@ -365,7 +465,7 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { |
| 365 | }, | 465 | }, |
| 366 | .ptr_mod_on_array_child_type => { | 466 | .ptr_mod_on_array_child_type => { |
| 367 | return stream.print("pointer modifier '{s}' not allowed on array child type", .{ | 467 | return stream.print("pointer modifier '{s}' not allowed on array child type", .{ |
| 368 | token_tags[parse_error.token].symbol(), | 468 | tree.tokenTag(parse_error.token).symbol(), |
| 369 | }); | 469 | }); |
| 370 | }, | 470 | }, |
| 371 | .invalid_bit_range => { | 471 | .invalid_bit_range => { |
| ... | @@ -421,7 +521,7 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { | ... | @@ -421,7 +521,7 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { |
| 421 | return stream.writeAll("expected field initializer"); | 521 | return stream.writeAll("expected field initializer"); |
| 422 | }, | 522 | }, |
| 423 | .mismatched_binary_op_whitespace => { | 523 | .mismatched_binary_op_whitespace => { |
| 424 | return stream.print("binary operator `{s}` has whitespace on one side, but not the other.", .{token_tags[parse_error.token].lexeme().?}); | 524 | return stream.print("binary operator `{s}` has whitespace on one side, but not the other.", .{tree.tokenTag(parse_error.token).lexeme().?}); |
| 425 | }, | 525 | }, |
| 426 | .invalid_ampersand_ampersand => { | 526 | .invalid_ampersand_ampersand => { |
| 427 | return stream.writeAll("ambiguous use of '&&'; use 'and' for logical AND, or change whitespace to ' & &' for bitwise AND"); | 527 | return stream.writeAll("ambiguous use of '&&'; use 'and' for logical AND, or change whitespace to ' & &' for bitwise AND"); |
| ... | @@ -472,7 +572,7 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { | ... | @@ -472,7 +572,7 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { |
| 472 | }, | 572 | }, |
| 473 | 573 | ||
| 474 | .expected_token => { | 574 | .expected_token => { |
| 475 | const found_tag = token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)]; | 575 | const found_tag = tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)); |
| 476 | const expected_symbol = parse_error.extra.expected_tag.symbol(); | 576 | const expected_symbol = parse_error.extra.expected_tag.symbol(); |
| 477 | switch (found_tag) { | 577 | switch (found_tag) { |
| 478 | .invalid => return stream.print("expected '{s}', found invalid bytes", .{ | 578 | .invalid => return stream.print("expected '{s}', found invalid bytes", .{ |
| ... | @@ -487,13 +587,9 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { | ... | @@ -487,13 +587,9 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { |
| 487 | } | 587 | } |
| 488 | 588 | ||
| 489 | pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { | 589 | pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { |
| 490 | const tags = tree.nodes.items(.tag); | 590 | var end_offset: u32 = 0; |
| 491 | const datas = tree.nodes.items(.data); | ||
| 492 | const main_tokens = tree.nodes.items(.main_token); | ||
| 493 | const token_tags = tree.tokens.items(.tag); | ||
| 494 | var end_offset: TokenIndex = 0; | ||
| 495 | var n = node; | 591 | var n = node; |
| 496 | while (true) switch (tags[n]) { | 592 | while (true) switch (tree.nodeTag(n)) { |
| 497 | .root => return 0, | 593 | .root => return 0, |
| 498 | 594 | ||
| 499 | .test_decl, | 595 | .test_decl, |
| ... | @@ -537,7 +633,7 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -537,7 +633,7 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { |
| 537 | .array_type, | 633 | .array_type, |
| 538 | .array_type_sentinel, | 634 | .array_type_sentinel, |
| 539 | .error_value, | 635 | .error_value, |
| 540 | => return main_tokens[n] - end_offset, | 636 | => return tree.nodeMainToken(n) - end_offset, |
| 541 | 637 | ||
| 542 | .array_init_dot, | 638 | .array_init_dot, |
| 543 | .array_init_dot_comma, | 639 | .array_init_dot_comma, |
| ... | @@ -548,11 +644,9 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -548,11 +644,9 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { |
| 548 | .struct_init_dot_two, | 644 | .struct_init_dot_two, |
| 549 | .struct_init_dot_two_comma, | 645 | .struct_init_dot_two_comma, |
| 550 | .enum_literal, | 646 | .enum_literal, |
| 551 | => return main_tokens[n] - 1 - end_offset, | 647 | => return tree.nodeMainToken(n) - 1 - end_offset, |
| 552 | 648 | ||
| 553 | .@"catch", | 649 | .@"catch", |
| 554 | .field_access, | ||
| 555 | .unwrap_optional, | ||
| 556 | .equal_equal, | 650 | .equal_equal, |
| 557 | .bang_equal, | 651 | .bang_equal, |
| 558 | .less_than, | 652 | .less_than, |
| ... | @@ -601,33 +695,37 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -601,33 +695,37 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { |
| 601 | .bool_and, | 695 | .bool_and, |
| 602 | .bool_or, | 696 | .bool_or, |
| 603 | .slice_open, | 697 | .slice_open, |
| 604 | .slice, | ||
| 605 | .slice_sentinel, | ||
| 606 | .deref, | ||
| 607 | .array_access, | 698 | .array_access, |
| 608 | .array_init_one, | 699 | .array_init_one, |
| 609 | .array_init_one_comma, | 700 | .array_init_one_comma, |
| 610 | .array_init, | 701 | .switch_range, |
| 611 | .array_init_comma, | 702 | .error_union, |
| 703 | => n = tree.nodeData(n).node_and_node[0], | ||
| 704 | |||
| 705 | .for_range, | ||
| 706 | .call_one, | ||
| 707 | .call_one_comma, | ||
| 612 | .struct_init_one, | 708 | .struct_init_one, |
| 613 | .struct_init_one_comma, | 709 | .struct_init_one_comma, |
| 710 | => n = tree.nodeData(n).node_and_opt_node[0], | ||
| 711 | |||
| 712 | .field_access, | ||
| 713 | .unwrap_optional, | ||
| 714 | => n = tree.nodeData(n).node_and_token[0], | ||
| 715 | |||
| 716 | .slice, | ||
| 717 | .slice_sentinel, | ||
| 718 | .array_init, | ||
| 719 | .array_init_comma, | ||
| 614 | .struct_init, | 720 | .struct_init, |
| 615 | .struct_init_comma, | 721 | .struct_init_comma, |
| 616 | .call_one, | ||
| 617 | .call_one_comma, | ||
| 618 | .call, | 722 | .call, |
| 619 | .call_comma, | 723 | .call_comma, |
| 620 | .switch_range, | 724 | => n = tree.nodeData(n).node_and_extra[0], |
| 621 | .for_range, | ||
| 622 | .error_union, | ||
| 623 | => n = datas[n].lhs, | ||
| 624 | 725 | ||
| 625 | .assign_destructure => { | 726 | .deref => n = tree.nodeData(n).node, |
| 626 | const extra_idx = datas[n].lhs; | 727 | |
| 627 | const lhs_len = tree.extra_data[extra_idx]; | 728 | .assign_destructure => n = tree.assignDestructure(n).ast.variables[0], |
| 628 | assert(lhs_len > 0); | ||
| 629 | n = tree.extra_data[extra_idx + 1]; | ||
| 630 | }, | ||
| 631 | 729 | ||
| 632 | .fn_decl, | 730 | .fn_decl, |
| 633 | .fn_proto_simple, | 731 | .fn_proto_simple, |
| ... | @@ -635,10 +733,10 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -635,10 +733,10 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { |
| 635 | .fn_proto_one, | 733 | .fn_proto_one, |
| 636 | .fn_proto, | 734 | .fn_proto, |
| 637 | => { | 735 | => { |
| 638 | var i = main_tokens[n]; // fn token | 736 | var i = tree.nodeMainToken(n); // fn token |
| 639 | while (i > 0) { | 737 | while (i > 0) { |
| 640 | i -= 1; | 738 | i -= 1; |
| 641 | switch (token_tags[i]) { | 739 | switch (tree.tokenTag(i)) { |
| 642 | .keyword_extern, | 740 | .keyword_extern, |
| 643 | .keyword_export, | 741 | .keyword_export, |
| 644 | .keyword_pub, | 742 | .keyword_pub, |
| ... | @@ -654,30 +752,33 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -654,30 +752,33 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { |
| 654 | }, | 752 | }, |
| 655 | 753 | ||
| 656 | .@"usingnamespace" => { | 754 | .@"usingnamespace" => { |
| 657 | const main_token = main_tokens[n]; | 755 | const main_token: TokenIndex = tree.nodeMainToken(n); |
| 658 | if (main_token > 0 and token_tags[main_token - 1] == .keyword_pub) { | 756 | const has_visib_token = tree.isTokenPrecededByTags(main_token, &.{.keyword_pub}); |
| 659 | end_offset += 1; | 757 | end_offset += @intFromBool(has_visib_token); |
| 660 | } | ||
| 661 | return main_token - end_offset; | 758 | return main_token - end_offset; |
| 662 | }, | 759 | }, |
| 663 | 760 | ||
| 664 | .async_call_one, | 761 | .async_call_one, |
| 665 | .async_call_one_comma, | 762 | .async_call_one_comma, |
| 763 | => { | ||
| 764 | end_offset += 1; // async token | ||
| 765 | n = tree.nodeData(n).node_and_opt_node[0]; | ||
| 766 | }, | ||
| 767 | |||
| 666 | .async_call, | 768 | .async_call, |
| 667 | .async_call_comma, | 769 | .async_call_comma, |
| 668 | => { | 770 | => { |
| 669 | end_offset += 1; // async token | 771 | end_offset += 1; // async token |
| 670 | n = datas[n].lhs; | 772 | n = tree.nodeData(n).node_and_extra[0]; |
| 671 | }, | 773 | }, |
| 672 | 774 | ||
| 673 | .container_field_init, | 775 | .container_field_init, |
| 674 | .container_field_align, | 776 | .container_field_align, |
| 675 | .container_field, | 777 | .container_field, |
| 676 | => { | 778 | => { |
| 677 | const name_token = main_tokens[n]; | 779 | const name_token = tree.nodeMainToken(n); |
| 678 | if (name_token > 0 and token_tags[name_token - 1] == .keyword_comptime) { | 780 | const has_comptime_token = tree.isTokenPrecededByTags(name_token, &.{.keyword_comptime}); |
| 679 | end_offset += 1; | 781 | end_offset += @intFromBool(has_comptime_token); |
| 680 | } | ||
| 681 | return name_token - end_offset; | 782 | return name_token - end_offset; |
| 682 | }, | 783 | }, |
| 683 | 784 | ||
| ... | @@ -686,10 +787,10 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -686,10 +787,10 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { |
| 686 | .simple_var_decl, | 787 | .simple_var_decl, |
| 687 | .aligned_var_decl, | 788 | .aligned_var_decl, |
| 688 | => { | 789 | => { |
| 689 | var i = main_tokens[n]; // mut token | 790 | var i = tree.nodeMainToken(n); // mut token |
| 690 | while (i > 0) { | 791 | while (i > 0) { |
| 691 | i -= 1; | 792 | i -= 1; |
| 692 | switch (token_tags[i]) { | 793 | switch (tree.tokenTag(i)) { |
| 693 | .keyword_extern, | 794 | .keyword_extern, |
| 694 | .keyword_export, | 795 | .keyword_export, |
| 695 | .keyword_comptime, | 796 | .keyword_comptime, |
| ... | @@ -710,10 +811,8 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -710,10 +811,8 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { |
| 710 | .block_two_semicolon, | 811 | .block_two_semicolon, |
| 711 | => { | 812 | => { |
| 712 | // Look for a label. | 813 | // Look for a label. |
| 713 | const lbrace = main_tokens[n]; | 814 | const lbrace = tree.nodeMainToken(n); |
| 714 | if (token_tags[lbrace - 1] == .colon and | 815 | if (tree.isTokenPrecededByTags(lbrace, &.{ .identifier, .colon })) { |
| 715 | token_tags[lbrace - 2] == .identifier) | ||
| 716 | { | ||
| 717 | end_offset += 2; | 816 | end_offset += 2; |
| 718 | } | 817 | } |
| 719 | return lbrace - end_offset; | 818 | return lbrace - end_offset; |
| ... | @@ -732,8 +831,8 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -732,8 +831,8 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { |
| 732 | .tagged_union_enum_tag, | 831 | .tagged_union_enum_tag, |
| 733 | .tagged_union_enum_tag_trailing, | 832 | .tagged_union_enum_tag_trailing, |
| 734 | => { | 833 | => { |
| 735 | const main_token = main_tokens[n]; | 834 | const main_token = tree.nodeMainToken(n); |
| 736 | switch (token_tags[main_token -| 1]) { | 835 | switch (tree.tokenTag(main_token -| 1)) { |
| 737 | .keyword_packed, .keyword_extern => end_offset += 1, | 836 | .keyword_packed, .keyword_extern => end_offset += 1, |
| 738 | else => {}, | 837 | else => {}, |
| 739 | } | 838 | } |
| ... | @@ -744,36 +843,26 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -744,36 +843,26 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { |
| 744 | .ptr_type_sentinel, | 843 | .ptr_type_sentinel, |
| 745 | .ptr_type, | 844 | .ptr_type, |
| 746 | .ptr_type_bit_range, | 845 | .ptr_type_bit_range, |
| 747 | => return main_tokens[n] - end_offset, | 846 | => return tree.nodeMainToken(n) - end_offset, |
| 748 | 847 | ||
| 749 | .switch_case_one => { | 848 | .switch_case_one, |
| 750 | if (datas[n].lhs == 0) { | 849 | .switch_case_inline_one, |
| 751 | return main_tokens[n] - 1 - end_offset; // else token | 850 | .switch_case, |
| 752 | } else { | 851 | .switch_case_inline, |
| 753 | n = datas[n].lhs; | 852 | => { |
| 754 | } | 853 | const full_switch = tree.fullSwitchCase(n).?; |
| 755 | }, | 854 | if (full_switch.inline_token) |inline_token| { |
| 756 | .switch_case_inline_one => { | 855 | return inline_token; |
| 757 | if (datas[n].lhs == 0) { | 856 | } else if (full_switch.ast.values.len == 0) { |
| 758 | return main_tokens[n] - 2 - end_offset; // else token | 857 | return full_switch.ast.arrow_token - 1 - end_offset; // else token |
| 759 | } else { | 858 | } else { |
| 760 | return firstToken(tree, datas[n].lhs) - 1; | 859 | n = full_switch.ast.values[0]; |
| 761 | } | 860 | } |
| 762 | }, | 861 | }, |
| 763 | .switch_case => { | ||
| 764 | const extra = tree.extraData(datas[n].lhs, Node.SubRange); | ||
| 765 | assert(extra.end - extra.start > 0); | ||
| 766 | n = tree.extra_data[extra.start]; | ||
| 767 | }, | ||
| 768 | .switch_case_inline => { | ||
| 769 | const extra = tree.extraData(datas[n].lhs, Node.SubRange); | ||
| 770 | assert(extra.end - extra.start > 0); | ||
| 771 | return firstToken(tree, tree.extra_data[extra.start]) - 1; | ||
| 772 | }, | ||
| 773 | 862 | ||
| 774 | .asm_output, .asm_input => { | 863 | .asm_output, .asm_input => { |
| 775 | assert(token_tags[main_tokens[n] - 1] == .l_bracket); | 864 | assert(tree.tokenTag(tree.nodeMainToken(n) - 1) == .l_bracket); |
| 776 | return main_tokens[n] - 1 - end_offset; | 865 | return tree.nodeMainToken(n) - 1 - end_offset; |
| 777 | }, | 866 | }, |
| 778 | 867 | ||
| 779 | .while_simple, | 868 | .while_simple, |
| ... | @@ -783,13 +872,13 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -783,13 +872,13 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { |
| 783 | .@"for", | 872 | .@"for", |
| 784 | => { | 873 | => { |
| 785 | // Look for a label and inline. | 874 | // Look for a label and inline. |
| 786 | const main_token = main_tokens[n]; | 875 | const main_token = tree.nodeMainToken(n); |
| 787 | var result = main_token; | 876 | var result = main_token; |
| 788 | if (token_tags[result -| 1] == .keyword_inline) { | 877 | if (tree.isTokenPrecededByTags(result, &.{.keyword_inline})) { |
| 789 | result -= 1; | 878 | result = result - 1; |
| 790 | } | 879 | } |
| 791 | if (token_tags[result -| 1] == .colon) { | 880 | if (tree.isTokenPrecededByTags(result, &.{ .identifier, .colon })) { |
| 792 | result -|= 2; | 881 | result = result - 2; |
| 793 | } | 882 | } |
| 794 | return result - end_offset; | 883 | return result - end_offset; |
| 795 | }, | 884 | }, |
| ... | @@ -797,14 +886,10 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -797,14 +886,10 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { |
| 797 | } | 886 | } |
| 798 | 887 | ||
| 799 | pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | 888 | pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { |
| 800 | const tags = tree.nodes.items(.tag); | ||
| 801 | const datas = tree.nodes.items(.data); | ||
| 802 | const main_tokens = tree.nodes.items(.main_token); | ||
| 803 | const token_tags = tree.tokens.items(.tag); | ||
| 804 | var n = node; | 889 | var n = node; |
| 805 | var end_offset: TokenIndex = 0; | 890 | var end_offset: u32 = 0; |
| 806 | while (true) switch (tags[n]) { | 891 | while (true) switch (tree.nodeTag(n)) { |
| 807 | .root => return @as(TokenIndex, @intCast(tree.tokens.len - 1)), | 892 | .root => return @intCast(tree.tokens.len - 1), |
| 808 | 893 | ||
| 809 | .@"usingnamespace", | 894 | .@"usingnamespace", |
| 810 | .bool_not, | 895 | .bool_not, |
| ... | @@ -819,11 +904,8 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -819,11 +904,8 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { |
| 819 | .@"resume", | 904 | .@"resume", |
| 820 | .@"nosuspend", | 905 | .@"nosuspend", |
| 821 | .@"comptime", | 906 | .@"comptime", |
| 822 | => n = datas[n].lhs, | 907 | => n = tree.nodeData(n).node, |
| 823 | 908 | ||
| 824 | .test_decl, | ||
| 825 | .@"errdefer", | ||
| 826 | .@"defer", | ||
| 827 | .@"catch", | 909 | .@"catch", |
| 828 | .equal_equal, | 910 | .equal_equal, |
| 829 | .bang_equal, | 911 | .bang_equal, |
| ... | @@ -849,7 +931,6 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -849,7 +931,6 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { |
| 849 | .assign_add_sat, | 931 | .assign_add_sat, |
| 850 | .assign_sub_sat, | 932 | .assign_sub_sat, |
| 851 | .assign, | 933 | .assign, |
| 852 | .assign_destructure, | ||
| 853 | .merge_error_sets, | 934 | .merge_error_sets, |
| 854 | .mul, | 935 | .mul, |
| 855 | .div, | 936 | .div, |
| ... | @@ -873,44 +954,53 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -873,44 +954,53 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { |
| 873 | .@"orelse", | 954 | .@"orelse", |
| 874 | .bool_and, | 955 | .bool_and, |
| 875 | .bool_or, | 956 | .bool_or, |
| 876 | .anyframe_type, | ||
| 877 | .error_union, | 957 | .error_union, |
| 878 | .if_simple, | 958 | .if_simple, |
| 879 | .while_simple, | 959 | .while_simple, |
| 880 | .for_simple, | 960 | .for_simple, |
| 881 | .fn_proto_simple, | ||
| 882 | .fn_proto_multi, | ||
| 883 | .fn_proto_one, | ||
| 884 | .fn_proto, | ||
| 885 | .fn_decl, | 961 | .fn_decl, |
| 962 | .array_type, | ||
| 963 | .switch_range, | ||
| 964 | => n = tree.nodeData(n).node_and_node[1], | ||
| 965 | |||
| 966 | .test_decl, .@"errdefer" => n = tree.nodeData(n).opt_token_and_node[1], | ||
| 967 | .@"defer" => n = tree.nodeData(n).node, | ||
| 968 | .anyframe_type => n = tree.nodeData(n).token_and_node[1], | ||
| 969 | |||
| 970 | .switch_case_one, | ||
| 971 | .switch_case_inline_one, | ||
| 886 | .ptr_type_aligned, | 972 | .ptr_type_aligned, |
| 887 | .ptr_type_sentinel, | 973 | .ptr_type_sentinel, |
| 974 | => n = tree.nodeData(n).opt_node_and_node[1], | ||
| 975 | |||
| 976 | .assign_destructure, | ||
| 888 | .ptr_type, | 977 | .ptr_type, |
| 889 | .ptr_type_bit_range, | 978 | .ptr_type_bit_range, |
| 890 | .array_type, | ||
| 891 | .switch_case_one, | ||
| 892 | .switch_case_inline_one, | ||
| 893 | .switch_case, | 979 | .switch_case, |
| 894 | .switch_case_inline, | 980 | .switch_case_inline, |
| 895 | .switch_range, | 981 | => n = tree.nodeData(n).extra_and_node[1], |
| 896 | => n = datas[n].rhs, | ||
| 897 | 982 | ||
| 898 | .for_range => if (datas[n].rhs != 0) { | 983 | .fn_proto_simple => n = tree.nodeData(n).opt_node_and_opt_node[1].unwrap().?, |
| 899 | n = datas[n].rhs; | 984 | .fn_proto_multi, |
| 900 | } else { | 985 | .fn_proto_one, |
| 901 | return main_tokens[n] + end_offset; | 986 | .fn_proto, |
| 987 | => n = tree.nodeData(n).extra_and_opt_node[1].unwrap().?, | ||
| 988 | |||
| 989 | .for_range => { | ||
| 990 | n = tree.nodeData(n).node_and_opt_node[1].unwrap() orelse { | ||
| 991 | return tree.nodeMainToken(n) + end_offset; | ||
| 992 | }; | ||
| 902 | }, | 993 | }, |
| 903 | 994 | ||
| 904 | .field_access, | 995 | .field_access, |
| 905 | .unwrap_optional, | 996 | .unwrap_optional, |
| 906 | .grouped_expression, | ||
| 907 | .multiline_string_literal, | ||
| 908 | .error_set_decl, | ||
| 909 | .asm_simple, | 997 | .asm_simple, |
| 910 | .asm_output, | 998 | => return tree.nodeData(n).node_and_token[1] + end_offset, |
| 911 | .asm_input, | 999 | .error_set_decl => return tree.nodeData(n).token + end_offset, |
| 912 | .error_value, | 1000 | .grouped_expression, .asm_input => return tree.nodeData(n).node_and_token[1] + end_offset, |
| 913 | => return datas[n].rhs + end_offset, | 1001 | .multiline_string_literal => return tree.nodeData(n).token_and_token[1] + end_offset, |
| 1002 | .asm_output => return tree.nodeData(n).opt_node_and_token[1] + end_offset, | ||
| 1003 | .error_value => return tree.nodeData(n).opt_token_and_opt_token[1].unwrap().? + end_offset, | ||
| 914 | 1004 | ||
| 915 | .anyframe_literal, | 1005 | .anyframe_literal, |
| 916 | .char_literal, | 1006 | .char_literal, |
| ... | @@ -920,80 +1010,88 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -920,80 +1010,88 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { |
| 920 | .deref, | 1010 | .deref, |
| 921 | .enum_literal, | 1011 | .enum_literal, |
| 922 | .string_literal, | 1012 | .string_literal, |
| 923 | => return main_tokens[n] + end_offset, | 1013 | => return tree.nodeMainToken(n) + end_offset, |
| 924 | 1014 | ||
| 925 | .@"return" => if (datas[n].lhs != 0) { | 1015 | .@"return" => { |
| 926 | n = datas[n].lhs; | 1016 | n = tree.nodeData(n).opt_node.unwrap() orelse { |
| 927 | } else { | 1017 | return tree.nodeMainToken(n) + end_offset; |
| 928 | return main_tokens[n] + end_offset; | 1018 | }; |
| 929 | }, | 1019 | }, |
| 930 | 1020 | ||
| 931 | .call, .async_call => { | 1021 | .call, .async_call => { |
| 1022 | _, const extra_index = tree.nodeData(n).node_and_extra; | ||
| 1023 | const params = tree.extraData(extra_index, Node.SubRange); | ||
| 1024 | assert(params.start != params.end); | ||
| 932 | end_offset += 1; // for the rparen | 1025 | end_offset += 1; // for the rparen |
| 933 | const params = tree.extraData(datas[n].rhs, Node.SubRange); | 1026 | n = @enumFromInt(tree.extra_data[@intFromEnum(params.end) - 1]); // last parameter |
| 934 | assert(params.end - params.start > 0); | ||
| 935 | n = tree.extra_data[params.end - 1]; // last parameter | ||
| 936 | }, | 1027 | }, |
| 937 | .tagged_union_enum_tag => { | 1028 | .tagged_union_enum_tag => { |
| 938 | const members = tree.extraData(datas[n].rhs, Node.SubRange); | 1029 | const arg, const extra_index = tree.nodeData(n).node_and_extra; |
| 939 | if (members.end - members.start == 0) { | 1030 | const members = tree.extraData(extra_index, Node.SubRange); |
| 1031 | if (members.start == members.end) { | ||
| 940 | end_offset += 4; // for the rparen + rparen + lbrace + rbrace | 1032 | end_offset += 4; // for the rparen + rparen + lbrace + rbrace |
| 941 | n = datas[n].lhs; | 1033 | n = arg; |
| 942 | } else { | 1034 | } else { |
| 943 | end_offset += 1; // for the rbrace | 1035 | end_offset += 1; // for the rbrace |
| 944 | n = tree.extra_data[members.end - 1]; // last parameter | 1036 | n = @enumFromInt(tree.extra_data[@intFromEnum(members.end) - 1]); // last parameter |
| 945 | } | 1037 | } |
| 946 | }, | 1038 | }, |
| 947 | .call_comma, | 1039 | .call_comma, |
| 948 | .async_call_comma, | 1040 | .async_call_comma, |
| 949 | .tagged_union_enum_tag_trailing, | 1041 | .tagged_union_enum_tag_trailing, |
| 950 | => { | 1042 | => { |
| 1043 | _, const extra_index = tree.nodeData(n).node_and_extra; | ||
| 1044 | const params = tree.extraData(extra_index, Node.SubRange); | ||
| 1045 | assert(params.start != params.end); | ||
| 951 | end_offset += 2; // for the comma/semicolon + rparen/rbrace | 1046 | end_offset += 2; // for the comma/semicolon + rparen/rbrace |
| 952 | const params = tree.extraData(datas[n].rhs, Node.SubRange); | 1047 | n = @enumFromInt(tree.extra_data[@intFromEnum(params.end) - 1]); // last parameter |
| 953 | assert(params.end > params.start); | ||
| 954 | n = tree.extra_data[params.end - 1]; // last parameter | ||
| 955 | }, | 1048 | }, |
| 956 | .@"switch" => { | 1049 | .@"switch" => { |
| 957 | const cases = tree.extraData(datas[n].rhs, Node.SubRange); | 1050 | const condition, const extra_index = tree.nodeData(n).node_and_extra; |
| 958 | if (cases.end - cases.start == 0) { | 1051 | const cases = tree.extraData(extra_index, Node.SubRange); |
| 1052 | if (cases.start == cases.end) { | ||
| 959 | end_offset += 3; // rparen, lbrace, rbrace | 1053 | end_offset += 3; // rparen, lbrace, rbrace |
| 960 | n = datas[n].lhs; // condition expression | 1054 | n = condition; |
| 961 | } else { | 1055 | } else { |
| 962 | end_offset += 1; // for the rbrace | 1056 | end_offset += 1; // for the rbrace |
| 963 | n = tree.extra_data[cases.end - 1]; // last case | 1057 | n = @enumFromInt(tree.extra_data[@intFromEnum(cases.end) - 1]); // last case |
| 964 | } | 1058 | } |
| 965 | }, | 1059 | }, |
| 966 | .container_decl_arg => { | 1060 | .container_decl_arg => { |
| 967 | const members = tree.extraData(datas[n].rhs, Node.SubRange); | 1061 | const arg, const extra_index = tree.nodeData(n).node_and_extra; |
| 968 | if (members.end - members.start == 0) { | 1062 | const members = tree.extraData(extra_index, Node.SubRange); |
| 1063 | if (members.end == members.start) { | ||
| 969 | end_offset += 3; // for the rparen + lbrace + rbrace | 1064 | end_offset += 3; // for the rparen + lbrace + rbrace |
| 970 | n = datas[n].lhs; | 1065 | n = arg; |
| 971 | } else { | 1066 | } else { |
| 972 | end_offset += 1; // for the rbrace | 1067 | end_offset += 1; // for the rbrace |
| 973 | n = tree.extra_data[members.end - 1]; // last parameter | 1068 | n = @enumFromInt(tree.extra_data[@intFromEnum(members.end) - 1]); // last parameter |
| 974 | } | 1069 | } |
| 975 | }, | 1070 | }, |
| 976 | .@"asm" => { | 1071 | .@"asm" => { |
| 977 | const extra = tree.extraData(datas[n].rhs, Node.Asm); | 1072 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 1073 | const extra = tree.extraData(extra_index, Node.Asm); | ||
| 978 | return extra.rparen + end_offset; | 1074 | return extra.rparen + end_offset; |
| 979 | }, | 1075 | }, |
| 980 | .array_init, | 1076 | .array_init, |
| 981 | .struct_init, | 1077 | .struct_init, |
| 982 | => { | 1078 | => { |
| 983 | const elements = tree.extraData(datas[n].rhs, Node.SubRange); | 1079 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 984 | assert(elements.end - elements.start > 0); | 1080 | const elements = tree.extraData(extra_index, Node.SubRange); |
| 1081 | assert(elements.start != elements.end); | ||
| 985 | end_offset += 1; // for the rbrace | 1082 | end_offset += 1; // for the rbrace |
| 986 | n = tree.extra_data[elements.end - 1]; // last element | 1083 | n = @enumFromInt(tree.extra_data[@intFromEnum(elements.end) - 1]); // last element |
| 987 | }, | 1084 | }, |
| 988 | .array_init_comma, | 1085 | .array_init_comma, |
| 989 | .struct_init_comma, | 1086 | .struct_init_comma, |
| 990 | .container_decl_arg_trailing, | 1087 | .container_decl_arg_trailing, |
| 991 | .switch_comma, | 1088 | .switch_comma, |
| 992 | => { | 1089 | => { |
| 993 | const members = tree.extraData(datas[n].rhs, Node.SubRange); | 1090 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 994 | assert(members.end - members.start > 0); | 1091 | const members = tree.extraData(extra_index, Node.SubRange); |
| 1092 | assert(members.start != members.end); | ||
| 995 | end_offset += 2; // for the comma + rbrace | 1093 | end_offset += 2; // for the comma + rbrace |
| 996 | n = tree.extra_data[members.end - 1]; // last parameter | 1094 | n = @enumFromInt(tree.extra_data[@intFromEnum(members.end) - 1]); // last parameter |
| 997 | }, | 1095 | }, |
| 998 | .array_init_dot, | 1096 | .array_init_dot, |
| 999 | .struct_init_dot, | 1097 | .struct_init_dot, |
| ... | @@ -1002,9 +1100,10 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -1002,9 +1100,10 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { |
| 1002 | .tagged_union, | 1100 | .tagged_union, |
| 1003 | .builtin_call, | 1101 | .builtin_call, |
| 1004 | => { | 1102 | => { |
| 1005 | assert(datas[n].rhs - datas[n].lhs > 0); | 1103 | const range = tree.nodeData(n).extra_range; |
| 1104 | assert(range.start != range.end); | ||
| 1006 | end_offset += 1; // for the rbrace | 1105 | end_offset += 1; // for the rbrace |
| 1007 | n = tree.extra_data[datas[n].rhs - 1]; // last statement | 1106 | n = @enumFromInt(tree.extra_data[@intFromEnum(range.end) - 1]); // last statement |
| 1008 | }, | 1107 | }, |
| 1009 | .array_init_dot_comma, | 1108 | .array_init_dot_comma, |
| 1010 | .struct_init_dot_comma, | 1109 | .struct_init_dot_comma, |
| ... | @@ -1013,20 +1112,21 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -1013,20 +1112,21 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { |
| 1013 | .tagged_union_trailing, | 1112 | .tagged_union_trailing, |
| 1014 | .builtin_call_comma, | 1113 | .builtin_call_comma, |
| 1015 | => { | 1114 | => { |
| 1016 | assert(datas[n].rhs - datas[n].lhs > 0); | 1115 | const range = tree.nodeData(n).extra_range; |
| 1116 | assert(range.start != range.end); | ||
| 1017 | end_offset += 2; // for the comma/semicolon + rbrace/rparen | 1117 | end_offset += 2; // for the comma/semicolon + rbrace/rparen |
| 1018 | n = tree.extra_data[datas[n].rhs - 1]; // last member | 1118 | n = @enumFromInt(tree.extra_data[@intFromEnum(range.end) - 1]); // last member |
| 1019 | }, | 1119 | }, |
| 1020 | .call_one, | 1120 | .call_one, |
| 1021 | .async_call_one, | 1121 | .async_call_one, |
| 1022 | .array_access, | ||
| 1023 | => { | 1122 | => { |
| 1024 | end_offset += 1; // for the rparen/rbracket | 1123 | _, const first_param = tree.nodeData(n).node_and_opt_node; |
| 1025 | if (datas[n].rhs == 0) { | 1124 | end_offset += 1; // for the rparen |
| 1026 | return main_tokens[n] + end_offset; | 1125 | n = first_param.unwrap() orelse { |
| 1027 | } | 1126 | return tree.nodeMainToken(n) + end_offset; |
| 1028 | n = datas[n].rhs; | 1127 | }; |
| 1029 | }, | 1128 | }, |
| 1129 | |||
| 1030 | .array_init_dot_two, | 1130 | .array_init_dot_two, |
| 1031 | .block_two, | 1131 | .block_two, |
| 1032 | .builtin_call_two, | 1132 | .builtin_call_two, |
| ... | @@ -1034,14 +1134,15 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -1034,14 +1134,15 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { |
| 1034 | .container_decl_two, | 1134 | .container_decl_two, |
| 1035 | .tagged_union_two, | 1135 | .tagged_union_two, |
| 1036 | => { | 1136 | => { |
| 1037 | if (datas[n].rhs != 0) { | 1137 | const opt_lhs, const opt_rhs = tree.nodeData(n).opt_node_and_opt_node; |
| 1138 | if (opt_rhs.unwrap()) |rhs| { | ||
| 1038 | end_offset += 1; // for the rparen/rbrace | 1139 | end_offset += 1; // for the rparen/rbrace |
| 1039 | n = datas[n].rhs; | 1140 | n = rhs; |
| 1040 | } else if (datas[n].lhs != 0) { | 1141 | } else if (opt_lhs.unwrap()) |lhs| { |
| 1041 | end_offset += 1; // for the rparen/rbrace | 1142 | end_offset += 1; // for the rparen/rbrace |
| 1042 | n = datas[n].lhs; | 1143 | n = lhs; |
| 1043 | } else { | 1144 | } else { |
| 1044 | switch (tags[n]) { | 1145 | switch (tree.nodeTag(n)) { |
| 1045 | .array_init_dot_two, | 1146 | .array_init_dot_two, |
| 1046 | .block_two, | 1147 | .block_two, |
| 1047 | .struct_init_dot_two, | 1148 | .struct_init_dot_two, |
| ... | @@ -1049,17 +1150,17 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -1049,17 +1150,17 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { |
| 1049 | .builtin_call_two => end_offset += 2, // lparen/lbrace + rparen/rbrace | 1150 | .builtin_call_two => end_offset += 2, // lparen/lbrace + rparen/rbrace |
| 1050 | .container_decl_two => { | 1151 | .container_decl_two => { |
| 1051 | var i: u32 = 2; // lbrace + rbrace | 1152 | var i: u32 = 2; // lbrace + rbrace |
| 1052 | while (token_tags[main_tokens[n] + i] == .container_doc_comment) i += 1; | 1153 | while (tree.tokenTag(tree.nodeMainToken(n) + i) == .container_doc_comment) i += 1; |
| 1053 | end_offset += i; | 1154 | end_offset += i; |
| 1054 | }, | 1155 | }, |
| 1055 | .tagged_union_two => { | 1156 | .tagged_union_two => { |
| 1056 | var i: u32 = 5; // (enum) {} | 1157 | var i: u32 = 5; // (enum) {} |
| 1057 | while (token_tags[main_tokens[n] + i] == .container_doc_comment) i += 1; | 1158 | while (tree.tokenTag(tree.nodeMainToken(n) + i) == .container_doc_comment) i += 1; |
| 1058 | end_offset += i; | 1159 | end_offset += i; |
| 1059 | }, | 1160 | }, |
| 1060 | else => unreachable, | 1161 | else => unreachable, |
| 1061 | } | 1162 | } |
| 1062 | return main_tokens[n] + end_offset; | 1163 | return tree.nodeMainToken(n) + end_offset; |
| 1063 | } | 1164 | } |
| 1064 | }, | 1165 | }, |
| 1065 | .array_init_dot_two_comma, | 1166 | .array_init_dot_two_comma, |
| ... | @@ -1069,341 +1170,345 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -1069,341 +1170,345 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { |
| 1069 | .container_decl_two_trailing, | 1170 | .container_decl_two_trailing, |
| 1070 | .tagged_union_two_trailing, | 1171 | .tagged_union_two_trailing, |
| 1071 | => { | 1172 | => { |
| 1173 | const opt_lhs, const opt_rhs = tree.nodeData(n).opt_node_and_opt_node; | ||
| 1072 | end_offset += 2; // for the comma/semicolon + rbrace/rparen | 1174 | end_offset += 2; // for the comma/semicolon + rbrace/rparen |
| 1073 | if (datas[n].rhs != 0) { | 1175 | if (opt_rhs.unwrap()) |rhs| { |
| 1074 | n = datas[n].rhs; | 1176 | n = rhs; |
| 1075 | } else if (datas[n].lhs != 0) { | 1177 | } else if (opt_lhs.unwrap()) |lhs| { |
| 1076 | n = datas[n].lhs; | 1178 | n = lhs; |
| 1077 | } else { | 1179 | } else { |
| 1078 | unreachable; | 1180 | unreachable; |
| 1079 | } | 1181 | } |
| 1080 | }, | 1182 | }, |
| 1081 | .simple_var_decl => { | 1183 | .simple_var_decl => { |
| 1082 | if (datas[n].rhs != 0) { | 1184 | const type_node, const init_node = tree.nodeData(n).opt_node_and_opt_node; |
| 1083 | n = datas[n].rhs; | 1185 | if (init_node.unwrap()) |rhs| { |
| 1084 | } else if (datas[n].lhs != 0) { | 1186 | n = rhs; |
| 1085 | n = datas[n].lhs; | 1187 | } else if (type_node.unwrap()) |lhs| { |
| 1188 | n = lhs; | ||
| 1086 | } else { | 1189 | } else { |
| 1087 | end_offset += 1; // from mut token to name | 1190 | end_offset += 1; // from mut token to name |
| 1088 | return main_tokens[n] + end_offset; | 1191 | return tree.nodeMainToken(n) + end_offset; |
| 1089 | } | 1192 | } |
| 1090 | }, | 1193 | }, |
| 1091 | .aligned_var_decl => { | 1194 | .aligned_var_decl => { |
| 1092 | if (datas[n].rhs != 0) { | 1195 | const align_node, const init_node = tree.nodeData(n).node_and_opt_node; |
| 1093 | n = datas[n].rhs; | 1196 | if (init_node.unwrap()) |rhs| { |
| 1094 | } else if (datas[n].lhs != 0) { | 1197 | n = rhs; |
| 1095 | end_offset += 1; // for the rparen | ||
| 1096 | n = datas[n].lhs; | ||
| 1097 | } else { | 1198 | } else { |
| 1098 | end_offset += 1; // from mut token to name | 1199 | end_offset += 1; // for the rparen |
| 1099 | return main_tokens[n] + end_offset; | 1200 | n = align_node; |
| 1100 | } | 1201 | } |
| 1101 | }, | 1202 | }, |
| 1102 | .global_var_decl => { | 1203 | .global_var_decl => { |
| 1103 | if (datas[n].rhs != 0) { | 1204 | const extra_index, const init_node = tree.nodeData(n).extra_and_opt_node; |
| 1104 | n = datas[n].rhs; | 1205 | if (init_node.unwrap()) |rhs| { |
| 1206 | n = rhs; | ||
| 1105 | } else { | 1207 | } else { |
| 1106 | const extra = tree.extraData(datas[n].lhs, Node.GlobalVarDecl); | 1208 | const extra = tree.extraData(extra_index, Node.GlobalVarDecl); |
| 1107 | if (extra.section_node != 0) { | 1209 | if (extra.section_node.unwrap()) |section_node| { |
| 1108 | end_offset += 1; // for the rparen | 1210 | end_offset += 1; // for the rparen |
| 1109 | n = extra.section_node; | 1211 | n = section_node; |
| 1110 | } else if (extra.align_node != 0) { | 1212 | } else if (extra.align_node.unwrap()) |align_node| { |
| 1111 | end_offset += 1; // for the rparen | 1213 | end_offset += 1; // for the rparen |
| 1112 | n = extra.align_node; | 1214 | n = align_node; |
| 1113 | } else if (extra.type_node != 0) { | 1215 | } else if (extra.type_node.unwrap()) |type_node| { |
| 1114 | n = extra.type_node; | 1216 | n = type_node; |
| 1115 | } else { | 1217 | } else { |
| 1116 | end_offset += 1; // from mut token to name | 1218 | end_offset += 1; // from mut token to name |
| 1117 | return main_tokens[n] + end_offset; | 1219 | return tree.nodeMainToken(n) + end_offset; |
| 1118 | } | 1220 | } |
| 1119 | } | 1221 | } |
| 1120 | }, | 1222 | }, |
| 1121 | .local_var_decl => { | 1223 | .local_var_decl => { |
| 1122 | if (datas[n].rhs != 0) { | 1224 | const extra_index, const init_node = tree.nodeData(n).extra_and_opt_node; |
| 1123 | n = datas[n].rhs; | 1225 | if (init_node.unwrap()) |rhs| { |
| 1226 | n = rhs; | ||
| 1124 | } else { | 1227 | } else { |
| 1125 | const extra = tree.extraData(datas[n].lhs, Node.LocalVarDecl); | 1228 | const extra = tree.extraData(extra_index, Node.LocalVarDecl); |
| 1126 | assert(extra.align_node != 0); | ||
| 1127 | end_offset += 1; // for the rparen | 1229 | end_offset += 1; // for the rparen |
| 1128 | n = extra.align_node; | 1230 | n = extra.align_node; |
| 1129 | } | 1231 | } |
| 1130 | }, | 1232 | }, |
| 1131 | .container_field_init => { | 1233 | .container_field_init => { |
| 1132 | if (datas[n].rhs != 0) { | 1234 | const type_expr, const value_expr = tree.nodeData(n).node_and_opt_node; |
| 1133 | n = datas[n].rhs; | 1235 | n = value_expr.unwrap() orelse type_expr; |
| 1134 | } else { | ||
| 1135 | assert(datas[n].lhs != 0); | ||
| 1136 | n = datas[n].lhs; | ||
| 1137 | } | ||
| 1138 | }, | 1236 | }, |
| 1139 | .container_field_align => { | 1237 | |
| 1140 | assert(datas[n].rhs != 0); | 1238 | .array_access, |
| 1141 | end_offset += 1; // for the rparen | 1239 | .array_init_one, |
| 1142 | n = datas[n].rhs; | 1240 | .container_field_align, |
| 1241 | => { | ||
| 1242 | _, const rhs = tree.nodeData(n).node_and_node; | ||
| 1243 | end_offset += 1; // for the rbracket/rbrace/rparen | ||
| 1244 | n = rhs; | ||
| 1143 | }, | 1245 | }, |
| 1144 | .container_field => { | 1246 | .container_field => { |
| 1145 | const extra = tree.extraData(datas[n].rhs, Node.ContainerField); | 1247 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 1146 | assert(extra.value_expr != 0); | 1248 | const extra = tree.extraData(extra_index, Node.ContainerField); |
| 1147 | n = extra.value_expr; | 1249 | n = extra.value_expr; |
| 1148 | }, | 1250 | }, |
| 1149 | 1251 | ||
| 1150 | .array_init_one, | 1252 | .struct_init_one => { |
| 1151 | .struct_init_one, | 1253 | _, const first_field = tree.nodeData(n).node_and_opt_node; |
| 1152 | => { | ||
| 1153 | end_offset += 1; // rbrace | 1254 | end_offset += 1; // rbrace |
| 1154 | if (datas[n].rhs == 0) { | 1255 | n = first_field.unwrap() orelse { |
| 1155 | return main_tokens[n] + end_offset; | 1256 | return tree.nodeMainToken(n) + end_offset; |
| 1156 | } else { | 1257 | }; |
| 1157 | n = datas[n].rhs; | 1258 | }, |
| 1158 | } | 1259 | .slice_open => { |
| 1260 | _, const start_node = tree.nodeData(n).node_and_node; | ||
| 1261 | end_offset += 2; // ellipsis2 + rbracket, or comma + rparen | ||
| 1262 | n = start_node; | ||
| 1263 | }, | ||
| 1264 | .array_init_one_comma => { | ||
| 1265 | _, const first_element = tree.nodeData(n).node_and_node; | ||
| 1266 | end_offset += 2; // comma + rbrace | ||
| 1267 | n = first_element; | ||
| 1159 | }, | 1268 | }, |
| 1160 | .slice_open, | ||
| 1161 | .call_one_comma, | 1269 | .call_one_comma, |
| 1162 | .async_call_one_comma, | 1270 | .async_call_one_comma, |
| 1163 | .array_init_one_comma, | ||
| 1164 | .struct_init_one_comma, | 1271 | .struct_init_one_comma, |
| 1165 | => { | 1272 | => { |
| 1273 | _, const first_field = tree.nodeData(n).node_and_opt_node; | ||
| 1166 | end_offset += 2; // ellipsis2 + rbracket, or comma + rparen | 1274 | end_offset += 2; // ellipsis2 + rbracket, or comma + rparen |
| 1167 | n = datas[n].rhs; | 1275 | n = first_field.unwrap().?; |
| 1168 | assert(n != 0); | ||
| 1169 | }, | 1276 | }, |
| 1170 | .slice => { | 1277 | .slice => { |
| 1171 | const extra = tree.extraData(datas[n].rhs, Node.Slice); | 1278 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 1172 | assert(extra.end != 0); // should have used slice_open | 1279 | const extra = tree.extraData(extra_index, Node.Slice); |
| 1173 | end_offset += 1; // rbracket | 1280 | end_offset += 1; // rbracket |
| 1174 | n = extra.end; | 1281 | n = extra.end; |
| 1175 | }, | 1282 | }, |
| 1176 | .slice_sentinel => { | 1283 | .slice_sentinel => { |
| 1177 | const extra = tree.extraData(datas[n].rhs, Node.SliceSentinel); | 1284 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 1178 | assert(extra.sentinel != 0); // should have used slice | 1285 | const extra = tree.extraData(extra_index, Node.SliceSentinel); |
| 1179 | end_offset += 1; // rbracket | 1286 | end_offset += 1; // rbracket |
| 1180 | n = extra.sentinel; | 1287 | n = extra.sentinel; |
| 1181 | }, | 1288 | }, |
| 1182 | 1289 | ||
| 1183 | .@"continue", .@"break" => { | 1290 | .@"continue", .@"break" => { |
| 1184 | if (datas[n].rhs != 0) { | 1291 | const opt_label, const opt_rhs = tree.nodeData(n).opt_token_and_opt_node; |
| 1185 | n = datas[n].rhs; | 1292 | if (opt_rhs.unwrap()) |rhs| { |
| 1186 | } else if (datas[n].lhs != 0) { | 1293 | n = rhs; |
| 1187 | return datas[n].lhs + end_offset; | 1294 | } else if (opt_label.unwrap()) |lhs| { |
| 1295 | return lhs + end_offset; | ||
| 1188 | } else { | 1296 | } else { |
| 1189 | return main_tokens[n] + end_offset; | 1297 | return tree.nodeMainToken(n) + end_offset; |
| 1190 | } | 1298 | } |
| 1191 | }, | 1299 | }, |
| 1192 | .while_cont => { | 1300 | .while_cont => { |
| 1193 | const extra = tree.extraData(datas[n].rhs, Node.WhileCont); | 1301 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 1194 | assert(extra.then_expr != 0); | 1302 | const extra = tree.extraData(extra_index, Node.WhileCont); |
| 1195 | n = extra.then_expr; | 1303 | n = extra.then_expr; |
| 1196 | }, | 1304 | }, |
| 1197 | .@"while" => { | 1305 | .@"while" => { |
| 1198 | const extra = tree.extraData(datas[n].rhs, Node.While); | 1306 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 1199 | assert(extra.else_expr != 0); | 1307 | const extra = tree.extraData(extra_index, Node.While); |
| 1200 | n = extra.else_expr; | 1308 | n = extra.else_expr; |
| 1201 | }, | 1309 | }, |
| 1202 | .@"if" => { | 1310 | .@"if" => { |
| 1203 | const extra = tree.extraData(datas[n].rhs, Node.If); | 1311 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 1204 | assert(extra.else_expr != 0); | 1312 | const extra = tree.extraData(extra_index, Node.If); |
| 1205 | n = extra.else_expr; | 1313 | n = extra.else_expr; |
| 1206 | }, | 1314 | }, |
| 1207 | .@"for" => { | 1315 | .@"for" => { |
| 1208 | const extra = @as(Node.For, @bitCast(datas[n].rhs)); | 1316 | const extra_index, const extra = tree.nodeData(n).@"for"; |
| 1209 | n = tree.extra_data[datas[n].lhs + extra.inputs + @intFromBool(extra.has_else)]; | 1317 | const index = @intFromEnum(extra_index) + extra.inputs + @intFromBool(extra.has_else); |
| 1318 | n = @enumFromInt(tree.extra_data[index]); | ||
| 1210 | }, | 1319 | }, |
| 1211 | .array_type_sentinel => { | 1320 | .array_type_sentinel => { |
| 1212 | const extra = tree.extraData(datas[n].rhs, Node.ArrayTypeSentinel); | 1321 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 1322 | const extra = tree.extraData(extra_index, Node.ArrayTypeSentinel); | ||
| 1213 | n = extra.elem_type; | 1323 | n = extra.elem_type; |
| 1214 | }, | 1324 | }, |
| 1215 | }; | 1325 | }; |
| 1216 | } | 1326 | } |
| 1217 | 1327 | ||
| 1218 | pub fn tokensOnSameLine(tree: Ast, token1: TokenIndex, token2: TokenIndex) bool { | 1328 | pub fn tokensOnSameLine(tree: Ast, token1: TokenIndex, token2: TokenIndex) bool { |
| 1219 | const token_starts = tree.tokens.items(.start); | 1329 | const source = tree.source[tree.tokenStart(token1)..tree.tokenStart(token2)]; |
| 1220 | const source = tree.source[token_starts[token1]..token_starts[token2]]; | ||
| 1221 | return mem.indexOfScalar(u8, source, '\n') == null; | 1330 | return mem.indexOfScalar(u8, source, '\n') == null; |
| 1222 | } | 1331 | } |
| 1223 | 1332 | ||
| 1224 | pub fn getNodeSource(tree: Ast, node: Node.Index) []const u8 { | 1333 | pub fn getNodeSource(tree: Ast, node: Node.Index) []const u8 { |
| 1225 | const token_starts = tree.tokens.items(.start); | ||
| 1226 | const first_token = tree.firstToken(node); | 1334 | const first_token = tree.firstToken(node); |
| 1227 | const last_token = tree.lastToken(node); | 1335 | const last_token = tree.lastToken(node); |
| 1228 | const start = token_starts[first_token]; | 1336 | const start = tree.tokenStart(first_token); |
| 1229 | const end = token_starts[last_token] + tree.tokenSlice(last_token).len; | 1337 | const end = tree.tokenStart(last_token) + tree.tokenSlice(last_token).len; |
| 1230 | return tree.source[start..end]; | 1338 | return tree.source[start..end]; |
| 1231 | } | 1339 | } |
| 1232 | 1340 | ||
| 1233 | pub fn globalVarDecl(tree: Ast, node: Node.Index) full.VarDecl { | 1341 | pub fn globalVarDecl(tree: Ast, node: Node.Index) full.VarDecl { |
| 1234 | assert(tree.nodes.items(.tag)[node] == .global_var_decl); | 1342 | assert(tree.nodeTag(node) == .global_var_decl); |
| 1235 | const data = tree.nodes.items(.data)[node]; | 1343 | const extra_index, const init_node = tree.nodeData(node).extra_and_opt_node; |
| 1236 | const extra = tree.extraData(data.lhs, Node.GlobalVarDecl); | 1344 | const extra = tree.extraData(extra_index, Node.GlobalVarDecl); |
| 1237 | return tree.fullVarDeclComponents(.{ | 1345 | return tree.fullVarDeclComponents(.{ |
| 1238 | .type_node = extra.type_node, | 1346 | .type_node = extra.type_node, |
| 1239 | .align_node = extra.align_node, | 1347 | .align_node = extra.align_node, |
| 1240 | .addrspace_node = extra.addrspace_node, | 1348 | .addrspace_node = extra.addrspace_node, |
| 1241 | .section_node = extra.section_node, | 1349 | .section_node = extra.section_node, |
| 1242 | .init_node = data.rhs, | 1350 | .init_node = init_node, |
| 1243 | .mut_token = tree.nodes.items(.main_token)[node], | 1351 | .mut_token = tree.nodeMainToken(node), |
| 1244 | }); | 1352 | }); |
| 1245 | } | 1353 | } |
| 1246 | 1354 | ||
| 1247 | pub fn localVarDecl(tree: Ast, node: Node.Index) full.VarDecl { | 1355 | pub fn localVarDecl(tree: Ast, node: Node.Index) full.VarDecl { |
| 1248 | assert(tree.nodes.items(.tag)[node] == .local_var_decl); | 1356 | assert(tree.nodeTag(node) == .local_var_decl); |
| 1249 | const data = tree.nodes.items(.data)[node]; | 1357 | const extra_index, const init_node = tree.nodeData(node).extra_and_opt_node; |
| 1250 | const extra = tree.extraData(data.lhs, Node.LocalVarDecl); | 1358 | const extra = tree.extraData(extra_index, Node.LocalVarDecl); |
| 1251 | return tree.fullVarDeclComponents(.{ | 1359 | return tree.fullVarDeclComponents(.{ |
| 1252 | .type_node = extra.type_node, | 1360 | .type_node = extra.type_node.toOptional(), |
| 1253 | .align_node = extra.align_node, | 1361 | .align_node = extra.align_node.toOptional(), |
| 1254 | .addrspace_node = 0, | 1362 | .addrspace_node = .none, |
| 1255 | .section_node = 0, | 1363 | .section_node = .none, |
| 1256 | .init_node = data.rhs, | 1364 | .init_node = init_node, |
| 1257 | .mut_token = tree.nodes.items(.main_token)[node], | 1365 | .mut_token = tree.nodeMainToken(node), |
| 1258 | }); | 1366 | }); |
| 1259 | } | 1367 | } |
| 1260 | 1368 | ||
| 1261 | pub fn simpleVarDecl(tree: Ast, node: Node.Index) full.VarDecl { | 1369 | pub fn simpleVarDecl(tree: Ast, node: Node.Index) full.VarDecl { |
| 1262 | assert(tree.nodes.items(.tag)[node] == .simple_var_decl); | 1370 | assert(tree.nodeTag(node) == .simple_var_decl); |
| 1263 | const data = tree.nodes.items(.data)[node]; | 1371 | const type_node, const init_node = tree.nodeData(node).opt_node_and_opt_node; |
| 1264 | return tree.fullVarDeclComponents(.{ | 1372 | return tree.fullVarDeclComponents(.{ |
| 1265 | .type_node = data.lhs, | 1373 | .type_node = type_node, |
| 1266 | .align_node = 0, | 1374 | .align_node = .none, |
| 1267 | .addrspace_node = 0, | 1375 | .addrspace_node = .none, |
| 1268 | .section_node = 0, | 1376 | .section_node = .none, |
| 1269 | .init_node = data.rhs, | 1377 | .init_node = init_node, |
| 1270 | .mut_token = tree.nodes.items(.main_token)[node], | 1378 | .mut_token = tree.nodeMainToken(node), |
| 1271 | }); | 1379 | }); |
| 1272 | } | 1380 | } |
| 1273 | 1381 | ||
| 1274 | pub fn alignedVarDecl(tree: Ast, node: Node.Index) full.VarDecl { | 1382 | pub fn alignedVarDecl(tree: Ast, node: Node.Index) full.VarDecl { |
| 1275 | assert(tree.nodes.items(.tag)[node] == .aligned_var_decl); | 1383 | assert(tree.nodeTag(node) == .aligned_var_decl); |
| 1276 | const data = tree.nodes.items(.data)[node]; | 1384 | const align_node, const init_node = tree.nodeData(node).node_and_opt_node; |
| 1277 | return tree.fullVarDeclComponents(.{ | 1385 | return tree.fullVarDeclComponents(.{ |
| 1278 | .type_node = 0, | 1386 | .type_node = .none, |
| 1279 | .align_node = data.lhs, | 1387 | .align_node = align_node.toOptional(), |
| 1280 | .addrspace_node = 0, | 1388 | .addrspace_node = .none, |
| 1281 | .section_node = 0, | 1389 | .section_node = .none, |
| 1282 | .init_node = data.rhs, | 1390 | .init_node = init_node, |
| 1283 | .mut_token = tree.nodes.items(.main_token)[node], | 1391 | .mut_token = tree.nodeMainToken(node), |
| 1284 | }); | 1392 | }); |
| 1285 | } | 1393 | } |
| 1286 | 1394 | ||
| 1287 | pub fn assignDestructure(tree: Ast, node: Node.Index) full.AssignDestructure { | 1395 | pub fn assignDestructure(tree: Ast, node: Node.Index) full.AssignDestructure { |
| 1288 | const data = tree.nodes.items(.data)[node]; | 1396 | const extra_index, const value_expr = tree.nodeData(node).extra_and_node; |
| 1289 | const variable_count = tree.extra_data[data.lhs]; | 1397 | const variable_count = tree.extra_data[@intFromEnum(extra_index)]; |
| 1290 | return tree.fullAssignDestructureComponents(.{ | 1398 | return tree.fullAssignDestructureComponents(.{ |
| 1291 | .variables = tree.extra_data[data.lhs + 1 ..][0..variable_count], | 1399 | .variables = tree.extraDataSliceWithLen(@enumFromInt(@intFromEnum(extra_index) + 1), variable_count, Node.Index), |
| 1292 | .equal_token = tree.nodes.items(.main_token)[node], | 1400 | .equal_token = tree.nodeMainToken(node), |
| 1293 | .value_expr = data.rhs, | 1401 | .value_expr = value_expr, |
| 1294 | }); | 1402 | }); |
| 1295 | } | 1403 | } |
| 1296 | 1404 | ||
| 1297 | pub fn ifSimple(tree: Ast, node: Node.Index) full.If { | 1405 | pub fn ifSimple(tree: Ast, node: Node.Index) full.If { |
| 1298 | assert(tree.nodes.items(.tag)[node] == .if_simple); | 1406 | assert(tree.nodeTag(node) == .if_simple); |
| 1299 | const data = tree.nodes.items(.data)[node]; | 1407 | const cond_expr, const then_expr = tree.nodeData(node).node_and_node; |
| 1300 | return tree.fullIfComponents(.{ | 1408 | return tree.fullIfComponents(.{ |
| 1301 | .cond_expr = data.lhs, | 1409 | .cond_expr = cond_expr, |
| 1302 | .then_expr = data.rhs, | 1410 | .then_expr = then_expr, |
| 1303 | .else_expr = 0, | 1411 | .else_expr = .none, |
| 1304 | .if_token = tree.nodes.items(.main_token)[node], | 1412 | .if_token = tree.nodeMainToken(node), |
| 1305 | }); | 1413 | }); |
| 1306 | } | 1414 | } |
| 1307 | 1415 | ||
| 1308 | pub fn ifFull(tree: Ast, node: Node.Index) full.If { | 1416 | pub fn ifFull(tree: Ast, node: Node.Index) full.If { |
| 1309 | assert(tree.nodes.items(.tag)[node] == .@"if"); | 1417 | assert(tree.nodeTag(node) == .@"if"); |
| 1310 | const data = tree.nodes.items(.data)[node]; | 1418 | const cond_expr, const extra_index = tree.nodeData(node).node_and_extra; |
| 1311 | const extra = tree.extraData(data.rhs, Node.If); | 1419 | const extra = tree.extraData(extra_index, Node.If); |
| 1312 | return tree.fullIfComponents(.{ | 1420 | return tree.fullIfComponents(.{ |
| 1313 | .cond_expr = data.lhs, | 1421 | .cond_expr = cond_expr, |
| 1314 | .then_expr = extra.then_expr, | 1422 | .then_expr = extra.then_expr, |
| 1315 | .else_expr = extra.else_expr, | 1423 | .else_expr = extra.else_expr.toOptional(), |
| 1316 | .if_token = tree.nodes.items(.main_token)[node], | 1424 | .if_token = tree.nodeMainToken(node), |
| 1317 | }); | 1425 | }); |
| 1318 | } | 1426 | } |
| 1319 | 1427 | ||
| 1320 | pub fn containerField(tree: Ast, node: Node.Index) full.ContainerField { | 1428 | pub fn containerField(tree: Ast, node: Node.Index) full.ContainerField { |
| 1321 | assert(tree.nodes.items(.tag)[node] == .container_field); | 1429 | assert(tree.nodeTag(node) == .container_field); |
| 1322 | const data = tree.nodes.items(.data)[node]; | 1430 | const type_expr, const extra_index = tree.nodeData(node).node_and_extra; |
| 1323 | const extra = tree.extraData(data.rhs, Node.ContainerField); | 1431 | const extra = tree.extraData(extra_index, Node.ContainerField); |
| 1324 | const main_token = tree.nodes.items(.main_token)[node]; | 1432 | const main_token = tree.nodeMainToken(node); |
| 1325 | return tree.fullContainerFieldComponents(.{ | 1433 | return tree.fullContainerFieldComponents(.{ |
| 1326 | .main_token = main_token, | 1434 | .main_token = main_token, |
| 1327 | .type_expr = data.lhs, | 1435 | .type_expr = type_expr.toOptional(), |
| 1328 | .align_expr = extra.align_expr, | 1436 | .align_expr = extra.align_expr.toOptional(), |
| 1329 | .value_expr = extra.value_expr, | 1437 | .value_expr = extra.value_expr.toOptional(), |
| 1330 | .tuple_like = tree.tokens.items(.tag)[main_token] != .identifier or | 1438 | .tuple_like = tree.tokenTag(main_token) != .identifier or |
| 1331 | tree.tokens.items(.tag)[main_token + 1] != .colon, | 1439 | tree.tokenTag(main_token + 1) != .colon, |
| 1332 | }); | 1440 | }); |
| 1333 | } | 1441 | } |
| 1334 | 1442 | ||
| 1335 | pub fn containerFieldInit(tree: Ast, node: Node.Index) full.ContainerField { | 1443 | pub fn containerFieldInit(tree: Ast, node: Node.Index) full.ContainerField { |
| 1336 | assert(tree.nodes.items(.tag)[node] == .container_field_init); | 1444 | assert(tree.nodeTag(node) == .container_field_init); |
| 1337 | const data = tree.nodes.items(.data)[node]; | 1445 | const type_expr, const value_expr = tree.nodeData(node).node_and_opt_node; |
| 1338 | const main_token = tree.nodes.items(.main_token)[node]; | 1446 | const main_token = tree.nodeMainToken(node); |
| 1339 | return tree.fullContainerFieldComponents(.{ | 1447 | return tree.fullContainerFieldComponents(.{ |
| 1340 | .main_token = main_token, | 1448 | .main_token = main_token, |
| 1341 | .type_expr = data.lhs, | 1449 | .type_expr = type_expr.toOptional(), |
| 1342 | .align_expr = 0, | 1450 | .align_expr = .none, |
| 1343 | .value_expr = data.rhs, | 1451 | .value_expr = value_expr, |
| 1344 | .tuple_like = tree.tokens.items(.tag)[main_token] != .identifier or | 1452 | .tuple_like = tree.tokenTag(main_token) != .identifier or |
| 1345 | tree.tokens.items(.tag)[main_token + 1] != .colon, | 1453 | tree.tokenTag(main_token + 1) != .colon, |
| 1346 | }); | 1454 | }); |
| 1347 | } | 1455 | } |
| 1348 | 1456 | ||
| 1349 | pub fn containerFieldAlign(tree: Ast, node: Node.Index) full.ContainerField { | 1457 | pub fn containerFieldAlign(tree: Ast, node: Node.Index) full.ContainerField { |
| 1350 | assert(tree.nodes.items(.tag)[node] == .container_field_align); | 1458 | assert(tree.nodeTag(node) == .container_field_align); |
| 1351 | const data = tree.nodes.items(.data)[node]; | 1459 | const type_expr, const align_expr = tree.nodeData(node).node_and_node; |
| 1352 | const main_token = tree.nodes.items(.main_token)[node]; | 1460 | const main_token = tree.nodeMainToken(node); |
| 1353 | return tree.fullContainerFieldComponents(.{ | 1461 | return tree.fullContainerFieldComponents(.{ |
| 1354 | .main_token = main_token, | 1462 | .main_token = main_token, |
| 1355 | .type_expr = data.lhs, | 1463 | .type_expr = type_expr.toOptional(), |
| 1356 | .align_expr = data.rhs, | 1464 | .align_expr = align_expr.toOptional(), |
| 1357 | .value_expr = 0, | 1465 | .value_expr = .none, |
| 1358 | .tuple_like = tree.tokens.items(.tag)[main_token] != .identifier or | 1466 | .tuple_like = tree.tokenTag(main_token) != .identifier or |
| 1359 | tree.tokens.items(.tag)[main_token + 1] != .colon, | 1467 | tree.tokenTag(main_token + 1) != .colon, |
| 1360 | }); | 1468 | }); |
| 1361 | } | 1469 | } |
| 1362 | 1470 | ||
| 1363 | pub fn fnProtoSimple(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.FnProto { | 1471 | pub fn fnProtoSimple(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.FnProto { |
| 1364 | assert(tree.nodes.items(.tag)[node] == .fn_proto_simple); | 1472 | assert(tree.nodeTag(node) == .fn_proto_simple); |
| 1365 | const data = tree.nodes.items(.data)[node]; | 1473 | const first_param, const return_type = tree.nodeData(node).opt_node_and_opt_node; |
| 1366 | buffer[0] = data.lhs; | 1474 | const params = loadOptionalNodesIntoBuffer(1, buffer, .{first_param}); |
| 1367 | const params = if (data.lhs == 0) buffer[0..0] else buffer[0..1]; | ||
| 1368 | return tree.fullFnProtoComponents(.{ | 1475 | return tree.fullFnProtoComponents(.{ |
| 1369 | .proto_node = node, | 1476 | .proto_node = node, |
| 1370 | .fn_token = tree.nodes.items(.main_token)[node], | 1477 | .fn_token = tree.nodeMainToken(node), |
| 1371 | .return_type = data.rhs, | 1478 | .return_type = return_type, |
| 1372 | .params = params, | 1479 | .params = params, |
| 1373 | .align_expr = 0, | 1480 | .align_expr = .none, |
| 1374 | .addrspace_expr = 0, | 1481 | .addrspace_expr = .none, |
| 1375 | .section_expr = 0, | 1482 | .section_expr = .none, |
| 1376 | .callconv_expr = 0, | 1483 | .callconv_expr = .none, |
| 1377 | }); | 1484 | }); |
| 1378 | } | 1485 | } |
| 1379 | 1486 | ||
| 1380 | pub fn fnProtoMulti(tree: Ast, node: Node.Index) full.FnProto { | 1487 | pub fn fnProtoMulti(tree: Ast, node: Node.Index) full.FnProto { |
| 1381 | assert(tree.nodes.items(.tag)[node] == .fn_proto_multi); | 1488 | assert(tree.nodeTag(node) == .fn_proto_multi); |
| 1382 | const data = tree.nodes.items(.data)[node]; | 1489 | const extra_index, const return_type = tree.nodeData(node).extra_and_opt_node; |
| 1383 | const params_range = tree.extraData(data.lhs, Node.SubRange); | 1490 | const params = tree.extraDataSlice(tree.extraData(extra_index, Node.SubRange), Node.Index); |
| 1384 | const params = tree.extra_data[params_range.start..params_range.end]; | ||
| 1385 | return tree.fullFnProtoComponents(.{ | 1491 | return tree.fullFnProtoComponents(.{ |
| 1386 | .proto_node = node, | 1492 | .proto_node = node, |
| 1387 | .fn_token = tree.nodes.items(.main_token)[node], | 1493 | .fn_token = tree.nodeMainToken(node), |
| 1388 | .return_type = data.rhs, | 1494 | .return_type = return_type, |
| 1389 | .params = params, | 1495 | .params = params, |
| 1390 | .align_expr = 0, | 1496 | .align_expr = .none, |
| 1391 | .addrspace_expr = 0, | 1497 | .addrspace_expr = .none, |
| 1392 | .section_expr = 0, | 1498 | .section_expr = .none, |
| 1393 | .callconv_expr = 0, | 1499 | .callconv_expr = .none, |
| 1394 | }); | 1500 | }); |
| 1395 | } | 1501 | } |
| 1396 | 1502 | ||
| 1397 | pub fn fnProtoOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.FnProto { | 1503 | pub fn fnProtoOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.FnProto { |
| 1398 | assert(tree.nodes.items(.tag)[node] == .fn_proto_one); | 1504 | assert(tree.nodeTag(node) == .fn_proto_one); |
| 1399 | const data = tree.nodes.items(.data)[node]; | 1505 | const extra_index, const return_type = tree.nodeData(node).extra_and_opt_node; |
| 1400 | const extra = tree.extraData(data.lhs, Node.FnProtoOne); | 1506 | const extra = tree.extraData(extra_index, Node.FnProtoOne); |
| 1401 | buffer[0] = extra.param; | 1507 | const params = loadOptionalNodesIntoBuffer(1, buffer, .{extra.param}); |
| 1402 | const params = if (extra.param == 0) buffer[0..0] else buffer[0..1]; | ||
| 1403 | return tree.fullFnProtoComponents(.{ | 1508 | return tree.fullFnProtoComponents(.{ |
| 1404 | .proto_node = node, | 1509 | .proto_node = node, |
| 1405 | .fn_token = tree.nodes.items(.main_token)[node], | 1510 | .fn_token = tree.nodeMainToken(node), |
| 1406 | .return_type = data.rhs, | 1511 | .return_type = return_type, |
| 1407 | .params = params, | 1512 | .params = params, |
| 1408 | .align_expr = extra.align_expr, | 1513 | .align_expr = extra.align_expr, |
| 1409 | .addrspace_expr = extra.addrspace_expr, | 1514 | .addrspace_expr = extra.addrspace_expr, |
| ... | @@ -1413,14 +1518,14 @@ pub fn fnProtoOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.FnPr | ... | @@ -1413,14 +1518,14 @@ pub fn fnProtoOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.FnPr |
| 1413 | } | 1518 | } |
| 1414 | 1519 | ||
| 1415 | pub fn fnProto(tree: Ast, node: Node.Index) full.FnProto { | 1520 | pub fn fnProto(tree: Ast, node: Node.Index) full.FnProto { |
| 1416 | assert(tree.nodes.items(.tag)[node] == .fn_proto); | 1521 | assert(tree.nodeTag(node) == .fn_proto); |
| 1417 | const data = tree.nodes.items(.data)[node]; | 1522 | const extra_index, const return_type = tree.nodeData(node).extra_and_opt_node; |
| 1418 | const extra = tree.extraData(data.lhs, Node.FnProto); | 1523 | const extra = tree.extraData(extra_index, Node.FnProto); |
| 1419 | const params = tree.extra_data[extra.params_start..extra.params_end]; | 1524 | const params = tree.extraDataSlice(.{ .start = extra.params_start, .end = extra.params_end }, Node.Index); |
| 1420 | return tree.fullFnProtoComponents(.{ | 1525 | return tree.fullFnProtoComponents(.{ |
| 1421 | .proto_node = node, | 1526 | .proto_node = node, |
| 1422 | .fn_token = tree.nodes.items(.main_token)[node], | 1527 | .fn_token = tree.nodeMainToken(node), |
| 1423 | .return_type = data.rhs, | 1528 | .return_type = return_type, |
| 1424 | .params = params, | 1529 | .params = params, |
| 1425 | .align_expr = extra.align_expr, | 1530 | .align_expr = extra.align_expr, |
| 1426 | .addrspace_expr = extra.addrspace_expr, | 1531 | .addrspace_expr = extra.addrspace_expr, |
| ... | @@ -1430,300 +1535,275 @@ pub fn fnProto(tree: Ast, node: Node.Index) full.FnProto { | ... | @@ -1430,300 +1535,275 @@ pub fn fnProto(tree: Ast, node: Node.Index) full.FnProto { |
| 1430 | } | 1535 | } |
| 1431 | 1536 | ||
| 1432 | pub fn structInitOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.StructInit { | 1537 | pub fn structInitOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.StructInit { |
| 1433 | assert(tree.nodes.items(.tag)[node] == .struct_init_one or | 1538 | assert(tree.nodeTag(node) == .struct_init_one or |
| 1434 | tree.nodes.items(.tag)[node] == .struct_init_one_comma); | 1539 | tree.nodeTag(node) == .struct_init_one_comma); |
| 1435 | const data = tree.nodes.items(.data)[node]; | 1540 | const type_expr, const first_field = tree.nodeData(node).node_and_opt_node; |
| 1436 | buffer[0] = data.rhs; | 1541 | const fields = loadOptionalNodesIntoBuffer(1, buffer, .{first_field}); |
| 1437 | const fields = if (data.rhs == 0) buffer[0..0] else buffer[0..1]; | ||
| 1438 | return .{ | 1542 | return .{ |
| 1439 | .ast = .{ | 1543 | .ast = .{ |
| 1440 | .lbrace = tree.nodes.items(.main_token)[node], | 1544 | .lbrace = tree.nodeMainToken(node), |
| 1441 | .fields = fields, | 1545 | .fields = fields, |
| 1442 | .type_expr = data.lhs, | 1546 | .type_expr = type_expr.toOptional(), |
| 1443 | }, | 1547 | }, |
| 1444 | }; | 1548 | }; |
| 1445 | } | 1549 | } |
| 1446 | 1550 | ||
| 1447 | pub fn structInitDotTwo(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) full.StructInit { | 1551 | pub fn structInitDotTwo(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) full.StructInit { |
| 1448 | assert(tree.nodes.items(.tag)[node] == .struct_init_dot_two or | 1552 | assert(tree.nodeTag(node) == .struct_init_dot_two or |
| 1449 | tree.nodes.items(.tag)[node] == .struct_init_dot_two_comma); | 1553 | tree.nodeTag(node) == .struct_init_dot_two_comma); |
| 1450 | const data = tree.nodes.items(.data)[node]; | 1554 | const fields = loadOptionalNodesIntoBuffer(2, buffer, tree.nodeData(node).opt_node_and_opt_node); |
| 1451 | buffer.* = .{ data.lhs, data.rhs }; | ||
| 1452 | const fields = if (data.rhs != 0) | ||
| 1453 | buffer[0..2] | ||
| 1454 | else if (data.lhs != 0) | ||
| 1455 | buffer[0..1] | ||
| 1456 | else | ||
| 1457 | buffer[0..0]; | ||
| 1458 | return .{ | 1555 | return .{ |
| 1459 | .ast = .{ | 1556 | .ast = .{ |
| 1460 | .lbrace = tree.nodes.items(.main_token)[node], | 1557 | .lbrace = tree.nodeMainToken(node), |
| 1461 | .fields = fields, | 1558 | .fields = fields, |
| 1462 | .type_expr = 0, | 1559 | .type_expr = .none, |
| 1463 | }, | 1560 | }, |
| 1464 | }; | 1561 | }; |
| 1465 | } | 1562 | } |
| 1466 | 1563 | ||
| 1467 | pub fn structInitDot(tree: Ast, node: Node.Index) full.StructInit { | 1564 | pub fn structInitDot(tree: Ast, node: Node.Index) full.StructInit { |
| 1468 | assert(tree.nodes.items(.tag)[node] == .struct_init_dot or | 1565 | assert(tree.nodeTag(node) == .struct_init_dot or |
| 1469 | tree.nodes.items(.tag)[node] == .struct_init_dot_comma); | 1566 | tree.nodeTag(node) == .struct_init_dot_comma); |
| 1470 | const data = tree.nodes.items(.data)[node]; | 1567 | const fields = tree.extraDataSlice(tree.nodeData(node).extra_range, Node.Index); |
| 1471 | return .{ | 1568 | return .{ |
| 1472 | .ast = .{ | 1569 | .ast = .{ |
| 1473 | .lbrace = tree.nodes.items(.main_token)[node], | 1570 | .lbrace = tree.nodeMainToken(node), |
| 1474 | .fields = tree.extra_data[data.lhs..data.rhs], | 1571 | .fields = fields, |
| 1475 | .type_expr = 0, | 1572 | .type_expr = .none, |
| 1476 | }, | 1573 | }, |
| 1477 | }; | 1574 | }; |
| 1478 | } | 1575 | } |
| 1479 | 1576 | ||
| 1480 | pub fn structInit(tree: Ast, node: Node.Index) full.StructInit { | 1577 | pub fn structInit(tree: Ast, node: Node.Index) full.StructInit { |
| 1481 | assert(tree.nodes.items(.tag)[node] == .struct_init or | 1578 | assert(tree.nodeTag(node) == .struct_init or |
| 1482 | tree.nodes.items(.tag)[node] == .struct_init_comma); | 1579 | tree.nodeTag(node) == .struct_init_comma); |
| 1483 | const data = tree.nodes.items(.data)[node]; | 1580 | const type_expr, const extra_index = tree.nodeData(node).node_and_extra; |
| 1484 | const fields_range = tree.extraData(data.rhs, Node.SubRange); | 1581 | const fields = tree.extraDataSlice(tree.extraData(extra_index, Node.SubRange), Node.Index); |
| 1485 | return .{ | 1582 | return .{ |
| 1486 | .ast = .{ | 1583 | .ast = .{ |
| 1487 | .lbrace = tree.nodes.items(.main_token)[node], | 1584 | .lbrace = tree.nodeMainToken(node), |
| 1488 | .fields = tree.extra_data[fields_range.start..fields_range.end], | 1585 | .fields = fields, |
| 1489 | .type_expr = data.lhs, | 1586 | .type_expr = type_expr.toOptional(), |
| 1490 | }, | 1587 | }, |
| 1491 | }; | 1588 | }; |
| 1492 | } | 1589 | } |
| 1493 | 1590 | ||
| 1494 | pub fn arrayInitOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.ArrayInit { | 1591 | pub fn arrayInitOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.ArrayInit { |
| 1495 | assert(tree.nodes.items(.tag)[node] == .array_init_one or | 1592 | assert(tree.nodeTag(node) == .array_init_one or |
| 1496 | tree.nodes.items(.tag)[node] == .array_init_one_comma); | 1593 | tree.nodeTag(node) == .array_init_one_comma); |
| 1497 | const data = tree.nodes.items(.data)[node]; | 1594 | const type_expr, buffer[0] = tree.nodeData(node).node_and_node; |
| 1498 | buffer[0] = data.rhs; | ||
| 1499 | const elements = if (data.rhs == 0) buffer[0..0] else buffer[0..1]; | ||
| 1500 | return .{ | 1595 | return .{ |
| 1501 | .ast = .{ | 1596 | .ast = .{ |
| 1502 | .lbrace = tree.nodes.items(.main_token)[node], | 1597 | .lbrace = tree.nodeMainToken(node), |
| 1503 | .elements = elements, | 1598 | .elements = buffer[0..1], |
| 1504 | .type_expr = data.lhs, | 1599 | .type_expr = type_expr.toOptional(), |
| 1505 | }, | 1600 | }, |
| 1506 | }; | 1601 | }; |
| 1507 | } | 1602 | } |
| 1508 | 1603 | ||
| 1509 | pub fn arrayInitDotTwo(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) full.ArrayInit { | 1604 | pub fn arrayInitDotTwo(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) full.ArrayInit { |
| 1510 | assert(tree.nodes.items(.tag)[node] == .array_init_dot_two or | 1605 | assert(tree.nodeTag(node) == .array_init_dot_two or |
| 1511 | tree.nodes.items(.tag)[node] == .array_init_dot_two_comma); | 1606 | tree.nodeTag(node) == .array_init_dot_two_comma); |
| 1512 | const data = tree.nodes.items(.data)[node]; | 1607 | const elements = loadOptionalNodesIntoBuffer(2, buffer, tree.nodeData(node).opt_node_and_opt_node); |
| 1513 | buffer.* = .{ data.lhs, data.rhs }; | ||
| 1514 | const elements = if (data.rhs != 0) | ||
| 1515 | buffer[0..2] | ||
| 1516 | else if (data.lhs != 0) | ||
| 1517 | buffer[0..1] | ||
| 1518 | else | ||
| 1519 | buffer[0..0]; | ||
| 1520 | return .{ | 1608 | return .{ |
| 1521 | .ast = .{ | 1609 | .ast = .{ |
| 1522 | .lbrace = tree.nodes.items(.main_token)[node], | 1610 | .lbrace = tree.nodeMainToken(node), |
| 1523 | .elements = elements, | 1611 | .elements = elements, |
| 1524 | .type_expr = 0, | 1612 | .type_expr = .none, |
| 1525 | }, | 1613 | }, |
| 1526 | }; | 1614 | }; |
| 1527 | } | 1615 | } |
| 1528 | 1616 | ||
| 1529 | pub fn arrayInitDot(tree: Ast, node: Node.Index) full.ArrayInit { | 1617 | pub fn arrayInitDot(tree: Ast, node: Node.Index) full.ArrayInit { |
| 1530 | assert(tree.nodes.items(.tag)[node] == .array_init_dot or | 1618 | assert(tree.nodeTag(node) == .array_init_dot or |
| 1531 | tree.nodes.items(.tag)[node] == .array_init_dot_comma); | 1619 | tree.nodeTag(node) == .array_init_dot_comma); |
| 1532 | const data = tree.nodes.items(.data)[node]; | 1620 | const elements = tree.extraDataSlice(tree.nodeData(node).extra_range, Node.Index); |
| 1533 | return .{ | 1621 | return .{ |
| 1534 | .ast = .{ | 1622 | .ast = .{ |
| 1535 | .lbrace = tree.nodes.items(.main_token)[node], | 1623 | .lbrace = tree.nodeMainToken(node), |
| 1536 | .elements = tree.extra_data[data.lhs..data.rhs], | 1624 | .elements = elements, |
| 1537 | .type_expr = 0, | 1625 | .type_expr = .none, |
| 1538 | }, | 1626 | }, |
| 1539 | }; | 1627 | }; |
| 1540 | } | 1628 | } |
| 1541 | 1629 | ||
| 1542 | pub fn arrayInit(tree: Ast, node: Node.Index) full.ArrayInit { | 1630 | pub fn arrayInit(tree: Ast, node: Node.Index) full.ArrayInit { |
| 1543 | assert(tree.nodes.items(.tag)[node] == .array_init or | 1631 | assert(tree.nodeTag(node) == .array_init or |
| 1544 | tree.nodes.items(.tag)[node] == .array_init_comma); | 1632 | tree.nodeTag(node) == .array_init_comma); |
| 1545 | const data = tree.nodes.items(.data)[node]; | 1633 | const type_expr, const extra_index = tree.nodeData(node).node_and_extra; |
| 1546 | const elem_range = tree.extraData(data.rhs, Node.SubRange); | 1634 | const elements = tree.extraDataSlice(tree.extraData(extra_index, Node.SubRange), Node.Index); |
| 1547 | return .{ | 1635 | return .{ |
| 1548 | .ast = .{ | 1636 | .ast = .{ |
| 1549 | .lbrace = tree.nodes.items(.main_token)[node], | 1637 | .lbrace = tree.nodeMainToken(node), |
| 1550 | .elements = tree.extra_data[elem_range.start..elem_range.end], | 1638 | .elements = elements, |
| 1551 | .type_expr = data.lhs, | 1639 | .type_expr = type_expr.toOptional(), |
| 1552 | }, | 1640 | }, |
| 1553 | }; | 1641 | }; |
| 1554 | } | 1642 | } |
| 1555 | 1643 | ||
| 1556 | pub fn arrayType(tree: Ast, node: Node.Index) full.ArrayType { | 1644 | pub fn arrayType(tree: Ast, node: Node.Index) full.ArrayType { |
| 1557 | assert(tree.nodes.items(.tag)[node] == .array_type); | 1645 | assert(tree.nodeTag(node) == .array_type); |
| 1558 | const data = tree.nodes.items(.data)[node]; | 1646 | const elem_count, const elem_type = tree.nodeData(node).node_and_node; |
| 1559 | return .{ | 1647 | return .{ |
| 1560 | .ast = .{ | 1648 | .ast = .{ |
| 1561 | .lbracket = tree.nodes.items(.main_token)[node], | 1649 | .lbracket = tree.nodeMainToken(node), |
| 1562 | .elem_count = data.lhs, | 1650 | .elem_count = elem_count, |
| 1563 | .sentinel = 0, | 1651 | .sentinel = .none, |
| 1564 | .elem_type = data.rhs, | 1652 | .elem_type = elem_type, |
| 1565 | }, | 1653 | }, |
| 1566 | }; | 1654 | }; |
| 1567 | } | 1655 | } |
| 1568 | 1656 | ||
| 1569 | pub fn arrayTypeSentinel(tree: Ast, node: Node.Index) full.ArrayType { | 1657 | pub fn arrayTypeSentinel(tree: Ast, node: Node.Index) full.ArrayType { |
| 1570 | assert(tree.nodes.items(.tag)[node] == .array_type_sentinel); | 1658 | assert(tree.nodeTag(node) == .array_type_sentinel); |
| 1571 | const data = tree.nodes.items(.data)[node]; | 1659 | const elem_count, const extra_index = tree.nodeData(node).node_and_extra; |
| 1572 | const extra = tree.extraData(data.rhs, Node.ArrayTypeSentinel); | 1660 | const extra = tree.extraData(extra_index, Node.ArrayTypeSentinel); |
| 1573 | assert(extra.sentinel != 0); | ||
| 1574 | return .{ | 1661 | return .{ |
| 1575 | .ast = .{ | 1662 | .ast = .{ |
| 1576 | .lbracket = tree.nodes.items(.main_token)[node], | 1663 | .lbracket = tree.nodeMainToken(node), |
| 1577 | .elem_count = data.lhs, | 1664 | .elem_count = elem_count, |
| 1578 | .sentinel = extra.sentinel, | 1665 | .sentinel = extra.sentinel.toOptional(), |
| 1579 | .elem_type = extra.elem_type, | 1666 | .elem_type = extra.elem_type, |
| 1580 | }, | 1667 | }, |
| 1581 | }; | 1668 | }; |
| 1582 | } | 1669 | } |
| 1583 | 1670 | ||
| 1584 | pub fn ptrTypeAligned(tree: Ast, node: Node.Index) full.PtrType { | 1671 | pub fn ptrTypeAligned(tree: Ast, node: Node.Index) full.PtrType { |
| 1585 | assert(tree.nodes.items(.tag)[node] == .ptr_type_aligned); | 1672 | assert(tree.nodeTag(node) == .ptr_type_aligned); |
| 1586 | const data = tree.nodes.items(.data)[node]; | 1673 | const align_node, const child_type = tree.nodeData(node).opt_node_and_node; |
| 1587 | return tree.fullPtrTypeComponents(.{ | 1674 | return tree.fullPtrTypeComponents(.{ |
| 1588 | .main_token = tree.nodes.items(.main_token)[node], | 1675 | .main_token = tree.nodeMainToken(node), |
| 1589 | .align_node = data.lhs, | 1676 | .align_node = align_node, |
| 1590 | .addrspace_node = 0, | 1677 | .addrspace_node = .none, |
| 1591 | .sentinel = 0, | 1678 | .sentinel = .none, |
| 1592 | .bit_range_start = 0, | 1679 | .bit_range_start = .none, |
| 1593 | .bit_range_end = 0, | 1680 | .bit_range_end = .none, |
| 1594 | .child_type = data.rhs, | 1681 | .child_type = child_type, |
| 1595 | }); | 1682 | }); |
| 1596 | } | 1683 | } |
| 1597 | 1684 | ||
| 1598 | pub fn ptrTypeSentinel(tree: Ast, node: Node.Index) full.PtrType { | 1685 | pub fn ptrTypeSentinel(tree: Ast, node: Node.Index) full.PtrType { |
| 1599 | assert(tree.nodes.items(.tag)[node] == .ptr_type_sentinel); | 1686 | assert(tree.nodeTag(node) == .ptr_type_sentinel); |
| 1600 | const data = tree.nodes.items(.data)[node]; | 1687 | const sentinel, const child_type = tree.nodeData(node).opt_node_and_node; |
| 1601 | return tree.fullPtrTypeComponents(.{ | 1688 | return tree.fullPtrTypeComponents(.{ |
| 1602 | .main_token = tree.nodes.items(.main_token)[node], | 1689 | .main_token = tree.nodeMainToken(node), |
| 1603 | .align_node = 0, | 1690 | .align_node = .none, |
| 1604 | .addrspace_node = 0, | 1691 | .addrspace_node = .none, |
| 1605 | .sentinel = data.lhs, | 1692 | .sentinel = sentinel, |
| 1606 | .bit_range_start = 0, | 1693 | .bit_range_start = .none, |
| 1607 | .bit_range_end = 0, | 1694 | .bit_range_end = .none, |
| 1608 | .child_type = data.rhs, | 1695 | .child_type = child_type, |
| 1609 | }); | 1696 | }); |
| 1610 | } | 1697 | } |
| 1611 | 1698 | ||
| 1612 | pub fn ptrType(tree: Ast, node: Node.Index) full.PtrType { | 1699 | pub fn ptrType(tree: Ast, node: Node.Index) full.PtrType { |
| 1613 | assert(tree.nodes.items(.tag)[node] == .ptr_type); | 1700 | assert(tree.nodeTag(node) == .ptr_type); |
| 1614 | const data = tree.nodes.items(.data)[node]; | 1701 | const extra_index, const child_type = tree.nodeData(node).extra_and_node; |
| 1615 | const extra = tree.extraData(data.lhs, Node.PtrType); | 1702 | const extra = tree.extraData(extra_index, Node.PtrType); |
| 1616 | return tree.fullPtrTypeComponents(.{ | 1703 | return tree.fullPtrTypeComponents(.{ |
| 1617 | .main_token = tree.nodes.items(.main_token)[node], | 1704 | .main_token = tree.nodeMainToken(node), |
| 1618 | .align_node = extra.align_node, | 1705 | .align_node = extra.align_node, |
| 1619 | .addrspace_node = extra.addrspace_node, | 1706 | .addrspace_node = extra.addrspace_node, |
| 1620 | .sentinel = extra.sentinel, | 1707 | .sentinel = extra.sentinel, |
| 1621 | .bit_range_start = 0, | 1708 | .bit_range_start = .none, |
| 1622 | .bit_range_end = 0, | 1709 | .bit_range_end = .none, |
| 1623 | .child_type = data.rhs, | 1710 | .child_type = child_type, |
| 1624 | }); | 1711 | }); |
| 1625 | } | 1712 | } |
| 1626 | 1713 | ||
| 1627 | pub fn ptrTypeBitRange(tree: Ast, node: Node.Index) full.PtrType { | 1714 | pub fn ptrTypeBitRange(tree: Ast, node: Node.Index) full.PtrType { |
| 1628 | assert(tree.nodes.items(.tag)[node] == .ptr_type_bit_range); | 1715 | assert(tree.nodeTag(node) == .ptr_type_bit_range); |
| 1629 | const data = tree.nodes.items(.data)[node]; | 1716 | const extra_index, const child_type = tree.nodeData(node).extra_and_node; |
| 1630 | const extra = tree.extraData(data.lhs, Node.PtrTypeBitRange); | 1717 | const extra = tree.extraData(extra_index, Node.PtrTypeBitRange); |
| 1631 | return tree.fullPtrTypeComponents(.{ | 1718 | return tree.fullPtrTypeComponents(.{ |
| 1632 | .main_token = tree.nodes.items(.main_token)[node], | 1719 | .main_token = tree.nodeMainToken(node), |
| 1633 | .align_node = extra.align_node, | 1720 | .align_node = extra.align_node.toOptional(), |
| 1634 | .addrspace_node = extra.addrspace_node, | 1721 | .addrspace_node = extra.addrspace_node, |
| 1635 | .sentinel = extra.sentinel, | 1722 | .sentinel = extra.sentinel, |
| 1636 | .bit_range_start = extra.bit_range_start, | 1723 | .bit_range_start = extra.bit_range_start.toOptional(), |
| 1637 | .bit_range_end = extra.bit_range_end, | 1724 | .bit_range_end = extra.bit_range_end.toOptional(), |
| 1638 | .child_type = data.rhs, | 1725 | .child_type = child_type, |
| 1639 | }); | 1726 | }); |
| 1640 | } | 1727 | } |
| 1641 | 1728 | ||
| 1642 | pub fn sliceOpen(tree: Ast, node: Node.Index) full.Slice { | 1729 | pub fn sliceOpen(tree: Ast, node: Node.Index) full.Slice { |
| 1643 | assert(tree.nodes.items(.tag)[node] == .slice_open); | 1730 | assert(tree.nodeTag(node) == .slice_open); |
| 1644 | const data = tree.nodes.items(.data)[node]; | 1731 | const sliced, const start = tree.nodeData(node).node_and_node; |
| 1645 | return .{ | 1732 | return .{ |
| 1646 | .ast = .{ | 1733 | .ast = .{ |
| 1647 | .sliced = data.lhs, | 1734 | .sliced = sliced, |
| 1648 | .lbracket = tree.nodes.items(.main_token)[node], | 1735 | .lbracket = tree.nodeMainToken(node), |
| 1649 | .start = data.rhs, | 1736 | .start = start, |
| 1650 | .end = 0, | 1737 | .end = .none, |
| 1651 | .sentinel = 0, | 1738 | .sentinel = .none, |
| 1652 | }, | 1739 | }, |
| 1653 | }; | 1740 | }; |
| 1654 | } | 1741 | } |
| 1655 | 1742 | ||
| 1656 | pub fn slice(tree: Ast, node: Node.Index) full.Slice { | 1743 | pub fn slice(tree: Ast, node: Node.Index) full.Slice { |
| 1657 | assert(tree.nodes.items(.tag)[node] == .slice); | 1744 | assert(tree.nodeTag(node) == .slice); |
| 1658 | const data = tree.nodes.items(.data)[node]; | 1745 | const sliced, const extra_index = tree.nodeData(node).node_and_extra; |
| 1659 | const extra = tree.extraData(data.rhs, Node.Slice); | 1746 | const extra = tree.extraData(extra_index, Node.Slice); |
| 1660 | return .{ | 1747 | return .{ |
| 1661 | .ast = .{ | 1748 | .ast = .{ |
| 1662 | .sliced = data.lhs, | 1749 | .sliced = sliced, |
| 1663 | .lbracket = tree.nodes.items(.main_token)[node], | 1750 | .lbracket = tree.nodeMainToken(node), |
| 1664 | .start = extra.start, | 1751 | .start = extra.start, |
| 1665 | .end = extra.end, | 1752 | .end = extra.end.toOptional(), |
| 1666 | .sentinel = 0, | 1753 | .sentinel = .none, |
| 1667 | }, | 1754 | }, |
| 1668 | }; | 1755 | }; |
| 1669 | } | 1756 | } |
| 1670 | 1757 | ||
| 1671 | pub fn sliceSentinel(tree: Ast, node: Node.Index) full.Slice { | 1758 | pub fn sliceSentinel(tree: Ast, node: Node.Index) full.Slice { |
| 1672 | assert(tree.nodes.items(.tag)[node] == .slice_sentinel); | 1759 | assert(tree.nodeTag(node) == .slice_sentinel); |
| 1673 | const data = tree.nodes.items(.data)[node]; | 1760 | const sliced, const extra_index = tree.nodeData(node).node_and_extra; |
| 1674 | const extra = tree.extraData(data.rhs, Node.SliceSentinel); | 1761 | const extra = tree.extraData(extra_index, Node.SliceSentinel); |
| 1675 | return .{ | 1762 | return .{ |
| 1676 | .ast = .{ | 1763 | .ast = .{ |
| 1677 | .sliced = data.lhs, | 1764 | .sliced = sliced, |
| 1678 | .lbracket = tree.nodes.items(.main_token)[node], | 1765 | .lbracket = tree.nodeMainToken(node), |
| 1679 | .start = extra.start, | 1766 | .start = extra.start, |
| 1680 | .end = extra.end, | 1767 | .end = extra.end, |
| 1681 | .sentinel = extra.sentinel, | 1768 | .sentinel = extra.sentinel.toOptional(), |
| 1682 | }, | 1769 | }, |
| 1683 | }; | 1770 | }; |
| 1684 | } | 1771 | } |
| 1685 | 1772 | ||
| 1686 | pub fn containerDeclTwo(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl { | 1773 | pub fn containerDeclTwo(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl { |
| 1687 | assert(tree.nodes.items(.tag)[node] == .container_decl_two or | 1774 | assert(tree.nodeTag(node) == .container_decl_two or |
| 1688 | tree.nodes.items(.tag)[node] == .container_decl_two_trailing); | 1775 | tree.nodeTag(node) == .container_decl_two_trailing); |
| 1689 | const data = tree.nodes.items(.data)[node]; | 1776 | const members = loadOptionalNodesIntoBuffer(2, buffer, tree.nodeData(node).opt_node_and_opt_node); |
| 1690 | buffer.* = .{ data.lhs, data.rhs }; | ||
| 1691 | const members = if (data.rhs != 0) | ||
| 1692 | buffer[0..2] | ||
| 1693 | else if (data.lhs != 0) | ||
| 1694 | buffer[0..1] | ||
| 1695 | else | ||
| 1696 | buffer[0..0]; | ||
| 1697 | return tree.fullContainerDeclComponents(.{ | 1777 | return tree.fullContainerDeclComponents(.{ |
| 1698 | .main_token = tree.nodes.items(.main_token)[node], | 1778 | .main_token = tree.nodeMainToken(node), |
| 1699 | .enum_token = null, | 1779 | .enum_token = null, |
| 1700 | .members = members, | 1780 | .members = members, |
| 1701 | .arg = 0, | 1781 | .arg = .none, |
| 1702 | }); | 1782 | }); |
| 1703 | } | 1783 | } |
| 1704 | 1784 | ||
| 1705 | pub fn containerDecl(tree: Ast, node: Node.Index) full.ContainerDecl { | 1785 | pub fn containerDecl(tree: Ast, node: Node.Index) full.ContainerDecl { |
| 1706 | assert(tree.nodes.items(.tag)[node] == .container_decl or | 1786 | assert(tree.nodeTag(node) == .container_decl or |
| 1707 | tree.nodes.items(.tag)[node] == .container_decl_trailing); | 1787 | tree.nodeTag(node) == .container_decl_trailing); |
| 1708 | const data = tree.nodes.items(.data)[node]; | 1788 | const members = tree.extraDataSlice(tree.nodeData(node).extra_range, Node.Index); |
| 1709 | return tree.fullContainerDeclComponents(.{ | 1789 | return tree.fullContainerDeclComponents(.{ |
| 1710 | .main_token = tree.nodes.items(.main_token)[node], | 1790 | .main_token = tree.nodeMainToken(node), |
| 1711 | .enum_token = null, | 1791 | .enum_token = null, |
| 1712 | .members = tree.extra_data[data.lhs..data.rhs], | 1792 | .members = members, |
| 1713 | .arg = 0, | 1793 | .arg = .none, |
| 1714 | }); | 1794 | }); |
| 1715 | } | 1795 | } |
| 1716 | 1796 | ||
| 1717 | pub fn containerDeclArg(tree: Ast, node: Node.Index) full.ContainerDecl { | 1797 | pub fn containerDeclArg(tree: Ast, node: Node.Index) full.ContainerDecl { |
| 1718 | assert(tree.nodes.items(.tag)[node] == .container_decl_arg or | 1798 | assert(tree.nodeTag(node) == .container_decl_arg or |
| 1719 | tree.nodes.items(.tag)[node] == .container_decl_arg_trailing); | 1799 | tree.nodeTag(node) == .container_decl_arg_trailing); |
| 1720 | const data = tree.nodes.items(.data)[node]; | 1800 | const arg, const extra_index = tree.nodeData(node).node_and_extra; |
| 1721 | const members_range = tree.extraData(data.rhs, Node.SubRange); | 1801 | const members = tree.extraDataSlice(tree.extraData(extra_index, Node.SubRange), Node.Index); |
| 1722 | return tree.fullContainerDeclComponents(.{ | 1802 | return tree.fullContainerDeclComponents(.{ |
| 1723 | .main_token = tree.nodes.items(.main_token)[node], | 1803 | .main_token = tree.nodeMainToken(node), |
| 1724 | .enum_token = null, | 1804 | .enum_token = null, |
| 1725 | .members = tree.extra_data[members_range.start..members_range.end], | 1805 | .members = members, |
| 1726 | .arg = data.lhs, | 1806 | .arg = arg.toOptional(), |
| 1727 | }); | 1807 | }); |
| 1728 | } | 1808 | } |
| 1729 | 1809 | ||
| ... | @@ -1731,175 +1811,170 @@ pub fn containerDeclRoot(tree: Ast) full.ContainerDecl { | ... | @@ -1731,175 +1811,170 @@ pub fn containerDeclRoot(tree: Ast) full.ContainerDecl { |
| 1731 | return .{ | 1811 | return .{ |
| 1732 | .layout_token = null, | 1812 | .layout_token = null, |
| 1733 | .ast = .{ | 1813 | .ast = .{ |
| 1734 | .main_token = undefined, | 1814 | .main_token = 0, |
| 1735 | .enum_token = null, | 1815 | .enum_token = null, |
| 1736 | .members = tree.rootDecls(), | 1816 | .members = tree.rootDecls(), |
| 1737 | .arg = 0, | 1817 | .arg = .none, |
| 1738 | }, | 1818 | }, |
| 1739 | }; | 1819 | }; |
| 1740 | } | 1820 | } |
| 1741 | 1821 | ||
| 1742 | pub fn taggedUnionTwo(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl { | 1822 | pub fn taggedUnionTwo(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl { |
| 1743 | assert(tree.nodes.items(.tag)[node] == .tagged_union_two or | 1823 | assert(tree.nodeTag(node) == .tagged_union_two or |
| 1744 | tree.nodes.items(.tag)[node] == .tagged_union_two_trailing); | 1824 | tree.nodeTag(node) == .tagged_union_two_trailing); |
| 1745 | const data = tree.nodes.items(.data)[node]; | 1825 | const members = loadOptionalNodesIntoBuffer(2, buffer, tree.nodeData(node).opt_node_and_opt_node); |
| 1746 | buffer.* = .{ data.lhs, data.rhs }; | 1826 | const main_token = tree.nodeMainToken(node); |
| 1747 | const members = if (data.rhs != 0) | ||
| 1748 | buffer[0..2] | ||
| 1749 | else if (data.lhs != 0) | ||
| 1750 | buffer[0..1] | ||
| 1751 | else | ||
| 1752 | buffer[0..0]; | ||
| 1753 | const main_token = tree.nodes.items(.main_token)[node]; | ||
| 1754 | return tree.fullContainerDeclComponents(.{ | 1827 | return tree.fullContainerDeclComponents(.{ |
| 1755 | .main_token = main_token, | 1828 | .main_token = main_token, |
| 1756 | .enum_token = main_token + 2, // union lparen enum | 1829 | .enum_token = main_token + 2, // union lparen enum |
| 1757 | .members = members, | 1830 | .members = members, |
| 1758 | .arg = 0, | 1831 | .arg = .none, |
| 1759 | }); | 1832 | }); |
| 1760 | } | 1833 | } |
| 1761 | 1834 | ||
| 1762 | pub fn taggedUnion(tree: Ast, node: Node.Index) full.ContainerDecl { | 1835 | pub fn taggedUnion(tree: Ast, node: Node.Index) full.ContainerDecl { |
| 1763 | assert(tree.nodes.items(.tag)[node] == .tagged_union or | 1836 | assert(tree.nodeTag(node) == .tagged_union or |
| 1764 | tree.nodes.items(.tag)[node] == .tagged_union_trailing); | 1837 | tree.nodeTag(node) == .tagged_union_trailing); |
| 1765 | const data = tree.nodes.items(.data)[node]; | 1838 | const members = tree.extraDataSlice(tree.nodeData(node).extra_range, Node.Index); |
| 1766 | const main_token = tree.nodes.items(.main_token)[node]; | 1839 | const main_token = tree.nodeMainToken(node); |
| 1767 | return tree.fullContainerDeclComponents(.{ | 1840 | return tree.fullContainerDeclComponents(.{ |
| 1768 | .main_token = main_token, | 1841 | .main_token = main_token, |
| 1769 | .enum_token = main_token + 2, // union lparen enum | 1842 | .enum_token = main_token + 2, // union lparen enum |
| 1770 | .members = tree.extra_data[data.lhs..data.rhs], | 1843 | .members = members, |
| 1771 | .arg = 0, | 1844 | .arg = .none, |
| 1772 | }); | 1845 | }); |
| 1773 | } | 1846 | } |
| 1774 | 1847 | ||
| 1775 | pub fn taggedUnionEnumTag(tree: Ast, node: Node.Index) full.ContainerDecl { | 1848 | pub fn taggedUnionEnumTag(tree: Ast, node: Node.Index) full.ContainerDecl { |
| 1776 | assert(tree.nodes.items(.tag)[node] == .tagged_union_enum_tag or | 1849 | assert(tree.nodeTag(node) == .tagged_union_enum_tag or |
| 1777 | tree.nodes.items(.tag)[node] == .tagged_union_enum_tag_trailing); | 1850 | tree.nodeTag(node) == .tagged_union_enum_tag_trailing); |
| 1778 | const data = tree.nodes.items(.data)[node]; | 1851 | const arg, const extra_index = tree.nodeData(node).node_and_extra; |
| 1779 | const members_range = tree.extraData(data.rhs, Node.SubRange); | 1852 | const members = tree.extraDataSlice(tree.extraData(extra_index, Node.SubRange), Node.Index); |
| 1780 | const main_token = tree.nodes.items(.main_token)[node]; | 1853 | const main_token = tree.nodeMainToken(node); |
| 1781 | return tree.fullContainerDeclComponents(.{ | 1854 | return tree.fullContainerDeclComponents(.{ |
| 1782 | .main_token = main_token, | 1855 | .main_token = main_token, |
| 1783 | .enum_token = main_token + 2, // union lparen enum | 1856 | .enum_token = main_token + 2, // union lparen enum |
| 1784 | .members = tree.extra_data[members_range.start..members_range.end], | 1857 | .members = members, |
| 1785 | .arg = data.lhs, | 1858 | .arg = arg.toOptional(), |
| 1786 | }); | 1859 | }); |
| 1787 | } | 1860 | } |
| 1788 | 1861 | ||
| 1789 | pub fn switchFull(tree: Ast, node: Node.Index) full.Switch { | 1862 | pub fn switchFull(tree: Ast, node: Node.Index) full.Switch { |
| 1790 | const data = &tree.nodes.items(.data)[node]; | 1863 | const main_token = tree.nodeMainToken(node); |
| 1791 | const main_token = tree.nodes.items(.main_token)[node]; | 1864 | const switch_token: TokenIndex, const label_token: ?TokenIndex = switch (tree.tokenTag(main_token)) { |
| 1792 | const switch_token: TokenIndex, const label_token: ?TokenIndex = switch (tree.tokens.items(.tag)[main_token]) { | ||
| 1793 | .identifier => .{ main_token + 2, main_token }, | 1865 | .identifier => .{ main_token + 2, main_token }, |
| 1794 | .keyword_switch => .{ main_token, null }, | 1866 | .keyword_switch => .{ main_token, null }, |
| 1795 | else => unreachable, | 1867 | else => unreachable, |
| 1796 | }; | 1868 | }; |
| 1797 | const extra = tree.extraData(data.rhs, Ast.Node.SubRange); | 1869 | const condition, const extra_index = tree.nodeData(node).node_and_extra; |
| 1870 | const cases = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Node.Index); | ||
| 1798 | return .{ | 1871 | return .{ |
| 1799 | .ast = .{ | 1872 | .ast = .{ |
| 1800 | .switch_token = switch_token, | 1873 | .switch_token = switch_token, |
| 1801 | .condition = data.lhs, | 1874 | .condition = condition, |
| 1802 | .cases = tree.extra_data[extra.start..extra.end], | 1875 | .cases = cases, |
| 1803 | }, | 1876 | }, |
| 1804 | .label_token = label_token, | 1877 | .label_token = label_token, |
| 1805 | }; | 1878 | }; |
| 1806 | } | 1879 | } |
| 1807 | 1880 | ||
| 1808 | pub fn switchCaseOne(tree: Ast, node: Node.Index) full.SwitchCase { | 1881 | pub fn switchCaseOne(tree: Ast, node: Node.Index) full.SwitchCase { |
| 1809 | const data = &tree.nodes.items(.data)[node]; | 1882 | const first_value, const target_expr = tree.nodeData(node).opt_node_and_node; |
| 1810 | const values: *[1]Node.Index = &data.lhs; | ||
| 1811 | return tree.fullSwitchCaseComponents(.{ | 1883 | return tree.fullSwitchCaseComponents(.{ |
| 1812 | .values = if (data.lhs == 0) values[0..0] else values[0..1], | 1884 | .values = if (first_value == .none) |
| 1813 | .arrow_token = tree.nodes.items(.main_token)[node], | 1885 | &.{} |
| 1814 | .target_expr = data.rhs, | 1886 | else |
| 1887 | // Ensure that the returned slice points into the existing memory of the Ast | ||
| 1888 | (@as(*const Node.Index, @ptrCast(&tree.nodes.items(.data)[@intFromEnum(node)].opt_node_and_node[0])))[0..1], | ||
| 1889 | .arrow_token = tree.nodeMainToken(node), | ||
| 1890 | .target_expr = target_expr, | ||
| 1815 | }, node); | 1891 | }, node); |
| 1816 | } | 1892 | } |
| 1817 | 1893 | ||
| 1818 | pub fn switchCase(tree: Ast, node: Node.Index) full.SwitchCase { | 1894 | pub fn switchCase(tree: Ast, node: Node.Index) full.SwitchCase { |
| 1819 | const data = tree.nodes.items(.data)[node]; | 1895 | const extra_index, const target_expr = tree.nodeData(node).extra_and_node; |
| 1820 | const extra = tree.extraData(data.lhs, Node.SubRange); | 1896 | const values = tree.extraDataSlice(tree.extraData(extra_index, Node.SubRange), Node.Index); |
| 1821 | return tree.fullSwitchCaseComponents(.{ | 1897 | return tree.fullSwitchCaseComponents(.{ |
| 1822 | .values = tree.extra_data[extra.start..extra.end], | 1898 | .values = values, |
| 1823 | .arrow_token = tree.nodes.items(.main_token)[node], | 1899 | .arrow_token = tree.nodeMainToken(node), |
| 1824 | .target_expr = data.rhs, | 1900 | .target_expr = target_expr, |
| 1825 | }, node); | 1901 | }, node); |
| 1826 | } | 1902 | } |
| 1827 | 1903 | ||
| 1828 | pub fn asmSimple(tree: Ast, node: Node.Index) full.Asm { | 1904 | pub fn asmSimple(tree: Ast, node: Node.Index) full.Asm { |
| 1829 | const data = tree.nodes.items(.data)[node]; | 1905 | const template, const rparen = tree.nodeData(node).node_and_token; |
| 1830 | return tree.fullAsmComponents(.{ | 1906 | return tree.fullAsmComponents(.{ |
| 1831 | .asm_token = tree.nodes.items(.main_token)[node], | 1907 | .asm_token = tree.nodeMainToken(node), |
| 1832 | .template = data.lhs, | 1908 | .template = template, |
| 1833 | .items = &.{}, | 1909 | .items = &.{}, |
| 1834 | .rparen = data.rhs, | 1910 | .rparen = rparen, |
| 1835 | }); | 1911 | }); |
| 1836 | } | 1912 | } |
| 1837 | 1913 | ||
| 1838 | pub fn asmFull(tree: Ast, node: Node.Index) full.Asm { | 1914 | pub fn asmFull(tree: Ast, node: Node.Index) full.Asm { |
| 1839 | const data = tree.nodes.items(.data)[node]; | 1915 | const template, const extra_index = tree.nodeData(node).node_and_extra; |
| 1840 | const extra = tree.extraData(data.rhs, Node.Asm); | 1916 | const extra = tree.extraData(extra_index, Node.Asm); |
| 1917 | const items = tree.extraDataSlice(.{ .start = extra.items_start, .end = extra.items_end }, Node.Index); | ||
| 1841 | return tree.fullAsmComponents(.{ | 1918 | return tree.fullAsmComponents(.{ |
| 1842 | .asm_token = tree.nodes.items(.main_token)[node], | 1919 | .asm_token = tree.nodeMainToken(node), |
| 1843 | .template = data.lhs, | 1920 | .template = template, |
| 1844 | .items = tree.extra_data[extra.items_start..extra.items_end], | 1921 | .items = items, |
| 1845 | .rparen = extra.rparen, | 1922 | .rparen = extra.rparen, |
| 1846 | }); | 1923 | }); |
| 1847 | } | 1924 | } |
| 1848 | 1925 | ||
| 1849 | pub fn whileSimple(tree: Ast, node: Node.Index) full.While { | 1926 | pub fn whileSimple(tree: Ast, node: Node.Index) full.While { |
| 1850 | const data = tree.nodes.items(.data)[node]; | 1927 | const cond_expr, const then_expr = tree.nodeData(node).node_and_node; |
| 1851 | return tree.fullWhileComponents(.{ | 1928 | return tree.fullWhileComponents(.{ |
| 1852 | .while_token = tree.nodes.items(.main_token)[node], | 1929 | .while_token = tree.nodeMainToken(node), |
| 1853 | .cond_expr = data.lhs, | 1930 | .cond_expr = cond_expr, |
| 1854 | .cont_expr = 0, | 1931 | .cont_expr = .none, |
| 1855 | .then_expr = data.rhs, | 1932 | .then_expr = then_expr, |
| 1856 | .else_expr = 0, | 1933 | .else_expr = .none, |
| 1857 | }); | 1934 | }); |
| 1858 | } | 1935 | } |
| 1859 | 1936 | ||
| 1860 | pub fn whileCont(tree: Ast, node: Node.Index) full.While { | 1937 | pub fn whileCont(tree: Ast, node: Node.Index) full.While { |
| 1861 | const data = tree.nodes.items(.data)[node]; | 1938 | const cond_expr, const extra_index = tree.nodeData(node).node_and_extra; |
| 1862 | const extra = tree.extraData(data.rhs, Node.WhileCont); | 1939 | const extra = tree.extraData(extra_index, Node.WhileCont); |
| 1863 | return tree.fullWhileComponents(.{ | 1940 | return tree.fullWhileComponents(.{ |
| 1864 | .while_token = tree.nodes.items(.main_token)[node], | 1941 | .while_token = tree.nodeMainToken(node), |
| 1865 | .cond_expr = data.lhs, | 1942 | .cond_expr = cond_expr, |
| 1866 | .cont_expr = extra.cont_expr, | 1943 | .cont_expr = extra.cont_expr.toOptional(), |
| 1867 | .then_expr = extra.then_expr, | 1944 | .then_expr = extra.then_expr, |
| 1868 | .else_expr = 0, | 1945 | .else_expr = .none, |
| 1869 | }); | 1946 | }); |
| 1870 | } | 1947 | } |
| 1871 | 1948 | ||
| 1872 | pub fn whileFull(tree: Ast, node: Node.Index) full.While { | 1949 | pub fn whileFull(tree: Ast, node: Node.Index) full.While { |
| 1873 | const data = tree.nodes.items(.data)[node]; | 1950 | const cond_expr, const extra_index = tree.nodeData(node).node_and_extra; |
| 1874 | const extra = tree.extraData(data.rhs, Node.While); | 1951 | const extra = tree.extraData(extra_index, Node.While); |
| 1875 | return tree.fullWhileComponents(.{ | 1952 | return tree.fullWhileComponents(.{ |
| 1876 | .while_token = tree.nodes.items(.main_token)[node], | 1953 | .while_token = tree.nodeMainToken(node), |
| 1877 | .cond_expr = data.lhs, | 1954 | .cond_expr = cond_expr, |
| 1878 | .cont_expr = extra.cont_expr, | 1955 | .cont_expr = extra.cont_expr, |
| 1879 | .then_expr = extra.then_expr, | 1956 | .then_expr = extra.then_expr, |
| 1880 | .else_expr = extra.else_expr, | 1957 | .else_expr = extra.else_expr.toOptional(), |
| 1881 | }); | 1958 | }); |
| 1882 | } | 1959 | } |
| 1883 | 1960 | ||
| 1884 | pub fn forSimple(tree: Ast, node: Node.Index) full.For { | 1961 | pub fn forSimple(tree: Ast, node: Node.Index) full.For { |
| 1885 | const data = &tree.nodes.items(.data)[node]; | 1962 | const data = &tree.nodes.items(.data)[@intFromEnum(node)].node_and_node; |
| 1886 | const inputs: *[1]Node.Index = &data.lhs; | ||
| 1887 | return tree.fullForComponents(.{ | 1963 | return tree.fullForComponents(.{ |
| 1888 | .for_token = tree.nodes.items(.main_token)[node], | 1964 | .for_token = tree.nodeMainToken(node), |
| 1889 | .inputs = inputs[0..1], | 1965 | .inputs = (&data[0])[0..1], |
| 1890 | .then_expr = data.rhs, | 1966 | .then_expr = data[1], |
| 1891 | .else_expr = 0, | 1967 | .else_expr = .none, |
| 1892 | }); | 1968 | }); |
| 1893 | } | 1969 | } |
| 1894 | 1970 | ||
| 1895 | pub fn forFull(tree: Ast, node: Node.Index) full.For { | 1971 | pub fn forFull(tree: Ast, node: Node.Index) full.For { |
| 1896 | const data = tree.nodes.items(.data)[node]; | 1972 | const extra_index, const extra = tree.nodeData(node).@"for"; |
| 1897 | const extra = @as(Node.For, @bitCast(data.rhs)); | 1973 | const inputs = tree.extraDataSliceWithLen(extra_index, extra.inputs, Node.Index); |
| 1898 | const inputs = tree.extra_data[data.lhs..][0..extra.inputs]; | 1974 | const then_expr: Node.Index = @enumFromInt(tree.extra_data[@intFromEnum(extra_index) + extra.inputs]); |
| 1899 | const then_expr = tree.extra_data[data.lhs + extra.inputs]; | 1975 | const else_expr: Node.OptionalIndex = if (extra.has_else) @enumFromInt(tree.extra_data[@intFromEnum(extra_index) + extra.inputs + 1]) else .none; |
| 1900 | const else_expr = if (extra.has_else) tree.extra_data[data.lhs + extra.inputs + 1] else 0; | ||
| 1901 | return tree.fullForComponents(.{ | 1976 | return tree.fullForComponents(.{ |
| 1902 | .for_token = tree.nodes.items(.main_token)[node], | 1977 | .for_token = tree.nodeMainToken(node), |
| 1903 | .inputs = inputs, | 1978 | .inputs = inputs, |
| 1904 | .then_expr = then_expr, | 1979 | .then_expr = then_expr, |
| 1905 | .else_expr = else_expr, | 1980 | .else_expr = else_expr, |
| ... | @@ -1907,28 +1982,26 @@ pub fn forFull(tree: Ast, node: Node.Index) full.For { | ... | @@ -1907,28 +1982,26 @@ pub fn forFull(tree: Ast, node: Node.Index) full.For { |
| 1907 | } | 1982 | } |
| 1908 | 1983 | ||
| 1909 | pub fn callOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.Call { | 1984 | pub fn callOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.Call { |
| 1910 | const data = tree.nodes.items(.data)[node]; | 1985 | const fn_expr, const first_param = tree.nodeData(node).node_and_opt_node; |
| 1911 | buffer.* = .{data.rhs}; | 1986 | const params = loadOptionalNodesIntoBuffer(1, buffer, .{first_param}); |
| 1912 | const params = if (data.rhs != 0) buffer[0..1] else buffer[0..0]; | ||
| 1913 | return tree.fullCallComponents(.{ | 1987 | return tree.fullCallComponents(.{ |
| 1914 | .lparen = tree.nodes.items(.main_token)[node], | 1988 | .lparen = tree.nodeMainToken(node), |
| 1915 | .fn_expr = data.lhs, | 1989 | .fn_expr = fn_expr, |
| 1916 | .params = params, | 1990 | .params = params, |
| 1917 | }); | 1991 | }); |
| 1918 | } | 1992 | } |
| 1919 | 1993 | ||
| 1920 | pub fn callFull(tree: Ast, node: Node.Index) full.Call { | 1994 | pub fn callFull(tree: Ast, node: Node.Index) full.Call { |
| 1921 | const data = tree.nodes.items(.data)[node]; | 1995 | const fn_expr, const extra_index = tree.nodeData(node).node_and_extra; |
| 1922 | const extra = tree.extraData(data.rhs, Node.SubRange); | 1996 | const params = tree.extraDataSlice(tree.extraData(extra_index, Node.SubRange), Node.Index); |
| 1923 | return tree.fullCallComponents(.{ | 1997 | return tree.fullCallComponents(.{ |
| 1924 | .lparen = tree.nodes.items(.main_token)[node], | 1998 | .lparen = tree.nodeMainToken(node), |
| 1925 | .fn_expr = data.lhs, | 1999 | .fn_expr = fn_expr, |
| 1926 | .params = tree.extra_data[extra.start..extra.end], | 2000 | .params = params, |
| 1927 | }); | 2001 | }); |
| 1928 | } | 2002 | } |
| 1929 | 2003 | ||
| 1930 | fn fullVarDeclComponents(tree: Ast, info: full.VarDecl.Components) full.VarDecl { | 2004 | fn fullVarDeclComponents(tree: Ast, info: full.VarDecl.Components) full.VarDecl { |
| 1931 | const token_tags = tree.tokens.items(.tag); | ||
| 1932 | var result: full.VarDecl = .{ | 2005 | var result: full.VarDecl = .{ |
| 1933 | .ast = info, | 2006 | .ast = info, |
| 1934 | .visib_token = null, | 2007 | .visib_token = null, |
| ... | @@ -1940,7 +2013,7 @@ fn fullVarDeclComponents(tree: Ast, info: full.VarDecl.Components) full.VarDecl | ... | @@ -1940,7 +2013,7 @@ fn fullVarDeclComponents(tree: Ast, info: full.VarDecl.Components) full.VarDecl |
| 1940 | var i = info.mut_token; | 2013 | var i = info.mut_token; |
| 1941 | while (i > 0) { | 2014 | while (i > 0) { |
| 1942 | i -= 1; | 2015 | i -= 1; |
| 1943 | switch (token_tags[i]) { | 2016 | switch (tree.tokenTag(i)) { |
| 1944 | .keyword_extern, .keyword_export => result.extern_export_token = i, | 2017 | .keyword_extern, .keyword_export => result.extern_export_token = i, |
| 1945 | .keyword_comptime => result.comptime_token = i, | 2018 | .keyword_comptime => result.comptime_token = i, |
| 1946 | .keyword_pub => result.visib_token = i, | 2019 | .keyword_pub => result.visib_token = i, |
| ... | @@ -1953,14 +2026,12 @@ fn fullVarDeclComponents(tree: Ast, info: full.VarDecl.Components) full.VarDecl | ... | @@ -1953,14 +2026,12 @@ fn fullVarDeclComponents(tree: Ast, info: full.VarDecl.Components) full.VarDecl |
| 1953 | } | 2026 | } |
| 1954 | 2027 | ||
| 1955 | fn fullAssignDestructureComponents(tree: Ast, info: full.AssignDestructure.Components) full.AssignDestructure { | 2028 | fn fullAssignDestructureComponents(tree: Ast, info: full.AssignDestructure.Components) full.AssignDestructure { |
| 1956 | const token_tags = tree.tokens.items(.tag); | ||
| 1957 | const node_tags = tree.nodes.items(.tag); | ||
| 1958 | var result: full.AssignDestructure = .{ | 2029 | var result: full.AssignDestructure = .{ |
| 1959 | .comptime_token = null, | 2030 | .comptime_token = null, |
| 1960 | .ast = info, | 2031 | .ast = info, |
| 1961 | }; | 2032 | }; |
| 1962 | const first_variable_token = tree.firstToken(info.variables[0]); | 2033 | const first_variable_token = tree.firstToken(info.variables[0]); |
| 1963 | const maybe_comptime_token = switch (node_tags[info.variables[0]]) { | 2034 | const maybe_comptime_token = switch (tree.nodeTag(info.variables[0])) { |
| 1964 | .global_var_decl, | 2035 | .global_var_decl, |
| 1965 | .local_var_decl, | 2036 | .local_var_decl, |
| 1966 | .aligned_var_decl, | 2037 | .aligned_var_decl, |
| ... | @@ -1968,14 +2039,13 @@ fn fullAssignDestructureComponents(tree: Ast, info: full.AssignDestructure.Compo | ... | @@ -1968,14 +2039,13 @@ fn fullAssignDestructureComponents(tree: Ast, info: full.AssignDestructure.Compo |
| 1968 | => first_variable_token, | 2039 | => first_variable_token, |
| 1969 | else => first_variable_token - 1, | 2040 | else => first_variable_token - 1, |
| 1970 | }; | 2041 | }; |
| 1971 | if (token_tags[maybe_comptime_token] == .keyword_comptime) { | 2042 | if (tree.tokenTag(maybe_comptime_token) == .keyword_comptime) { |
| 1972 | result.comptime_token = maybe_comptime_token; | 2043 | result.comptime_token = maybe_comptime_token; |
| 1973 | } | 2044 | } |
| 1974 | return result; | 2045 | return result; |
| 1975 | } | 2046 | } |
| 1976 | 2047 | ||
| 1977 | fn fullIfComponents(tree: Ast, info: full.If.Components) full.If { | 2048 | fn fullIfComponents(tree: Ast, info: full.If.Components) full.If { |
| 1978 | const token_tags = tree.tokens.items(.tag); | ||
| 1979 | var result: full.If = .{ | 2049 | var result: full.If = .{ |
| 1980 | .ast = info, | 2050 | .ast = info, |
| 1981 | .payload_token = null, | 2051 | .payload_token = null, |
| ... | @@ -1985,14 +2055,14 @@ fn fullIfComponents(tree: Ast, info: full.If.Components) full.If { | ... | @@ -1985,14 +2055,14 @@ fn fullIfComponents(tree: Ast, info: full.If.Components) full.If { |
| 1985 | // if (cond_expr) |x| | 2055 | // if (cond_expr) |x| |
| 1986 | // ^ ^ | 2056 | // ^ ^ |
| 1987 | const payload_pipe = tree.lastToken(info.cond_expr) + 2; | 2057 | const payload_pipe = tree.lastToken(info.cond_expr) + 2; |
| 1988 | if (token_tags[payload_pipe] == .pipe) { | 2058 | if (tree.tokenTag(payload_pipe) == .pipe) { |
| 1989 | result.payload_token = payload_pipe + 1; | 2059 | result.payload_token = payload_pipe + 1; |
| 1990 | } | 2060 | } |
| 1991 | if (info.else_expr != 0) { | 2061 | if (info.else_expr != .none) { |
| 1992 | // then_expr else |x| | 2062 | // then_expr else |x| |
| 1993 | // ^ ^ | 2063 | // ^ ^ |
| 1994 | result.else_token = tree.lastToken(info.then_expr) + 1; | 2064 | result.else_token = tree.lastToken(info.then_expr) + 1; |
| 1995 | if (token_tags[result.else_token + 1] == .pipe) { | 2065 | if (tree.tokenTag(result.else_token + 1) == .pipe) { |
| 1996 | result.error_token = result.else_token + 2; | 2066 | result.error_token = result.else_token + 2; |
| 1997 | } | 2067 | } |
| 1998 | } | 2068 | } |
| ... | @@ -2000,12 +2070,11 @@ fn fullIfComponents(tree: Ast, info: full.If.Components) full.If { | ... | @@ -2000,12 +2070,11 @@ fn fullIfComponents(tree: Ast, info: full.If.Components) full.If { |
| 2000 | } | 2070 | } |
| 2001 | 2071 | ||
| 2002 | fn fullContainerFieldComponents(tree: Ast, info: full.ContainerField.Components) full.ContainerField { | 2072 | fn fullContainerFieldComponents(tree: Ast, info: full.ContainerField.Components) full.ContainerField { |
| 2003 | const token_tags = tree.tokens.items(.tag); | ||
| 2004 | var result: full.ContainerField = .{ | 2073 | var result: full.ContainerField = .{ |
| 2005 | .ast = info, | 2074 | .ast = info, |
| 2006 | .comptime_token = null, | 2075 | .comptime_token = null, |
| 2007 | }; | 2076 | }; |
| 2008 | if (info.main_token > 0 and token_tags[info.main_token - 1] == .keyword_comptime) { | 2077 | if (tree.isTokenPrecededByTags(info.main_token, &.{.keyword_comptime})) { |
| 2009 | // comptime type = init, | 2078 | // comptime type = init, |
| 2010 | // ^ ^ | 2079 | // ^ ^ |
| 2011 | // comptime name: type = init, | 2080 | // comptime name: type = init, |
| ... | @@ -2016,7 +2085,6 @@ fn fullContainerFieldComponents(tree: Ast, info: full.ContainerField.Components) | ... | @@ -2016,7 +2085,6 @@ fn fullContainerFieldComponents(tree: Ast, info: full.ContainerField.Components) |
| 2016 | } | 2085 | } |
| 2017 | 2086 | ||
| 2018 | fn fullFnProtoComponents(tree: Ast, info: full.FnProto.Components) full.FnProto { | 2087 | fn fullFnProtoComponents(tree: Ast, info: full.FnProto.Components) full.FnProto { |
| 2019 | const token_tags = tree.tokens.items(.tag); | ||
| 2020 | var result: full.FnProto = .{ | 2088 | var result: full.FnProto = .{ |
| 2021 | .ast = info, | 2089 | .ast = info, |
| 2022 | .visib_token = null, | 2090 | .visib_token = null, |
| ... | @@ -2028,7 +2096,7 @@ fn fullFnProtoComponents(tree: Ast, info: full.FnProto.Components) full.FnProto | ... | @@ -2028,7 +2096,7 @@ fn fullFnProtoComponents(tree: Ast, info: full.FnProto.Components) full.FnProto |
| 2028 | var i = info.fn_token; | 2096 | var i = info.fn_token; |
| 2029 | while (i > 0) { | 2097 | while (i > 0) { |
| 2030 | i -= 1; | 2098 | i -= 1; |
| 2031 | switch (token_tags[i]) { | 2099 | switch (tree.tokenTag(i)) { |
| 2032 | .keyword_extern, | 2100 | .keyword_extern, |
| 2033 | .keyword_export, | 2101 | .keyword_export, |
| 2034 | .keyword_inline, | 2102 | .keyword_inline, |
| ... | @@ -2040,25 +2108,24 @@ fn fullFnProtoComponents(tree: Ast, info: full.FnProto.Components) full.FnProto | ... | @@ -2040,25 +2108,24 @@ fn fullFnProtoComponents(tree: Ast, info: full.FnProto.Components) full.FnProto |
| 2040 | } | 2108 | } |
| 2041 | } | 2109 | } |
| 2042 | const after_fn_token = info.fn_token + 1; | 2110 | const after_fn_token = info.fn_token + 1; |
| 2043 | if (token_tags[after_fn_token] == .identifier) { | 2111 | if (tree.tokenTag(after_fn_token) == .identifier) { |
| 2044 | result.name_token = after_fn_token; | 2112 | result.name_token = after_fn_token; |
| 2045 | result.lparen = after_fn_token + 1; | 2113 | result.lparen = after_fn_token + 1; |
| 2046 | } else { | 2114 | } else { |
| 2047 | result.lparen = after_fn_token; | 2115 | result.lparen = after_fn_token; |
| 2048 | } | 2116 | } |
| 2049 | assert(token_tags[result.lparen] == .l_paren); | 2117 | assert(tree.tokenTag(result.lparen) == .l_paren); |
| 2050 | 2118 | ||
| 2051 | return result; | 2119 | return result; |
| 2052 | } | 2120 | } |
| 2053 | 2121 | ||
| 2054 | fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType { | 2122 | fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType { |
| 2055 | const token_tags = tree.tokens.items(.tag); | 2123 | const size: std.builtin.Type.Pointer.Size = switch (tree.tokenTag(info.main_token)) { |
| 2056 | const size: std.builtin.Type.Pointer.Size = switch (token_tags[info.main_token]) { | ||
| 2057 | .asterisk, | 2124 | .asterisk, |
| 2058 | .asterisk_asterisk, | 2125 | .asterisk_asterisk, |
| 2059 | => .one, | 2126 | => .one, |
| 2060 | .l_bracket => switch (token_tags[info.main_token + 1]) { | 2127 | .l_bracket => switch (tree.tokenTag(info.main_token + 1)) { |
| 2061 | .asterisk => if (token_tags[info.main_token + 2] == .identifier) .c else .many, | 2128 | .asterisk => if (tree.tokenTag(info.main_token + 2) == .identifier) .c else .many, |
| 2062 | else => .slice, | 2129 | else => .slice, |
| 2063 | }, | 2130 | }, |
| 2064 | else => unreachable, | 2131 | else => unreachable, |
| ... | @@ -2074,23 +2141,23 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType | ... | @@ -2074,23 +2141,23 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType |
| 2074 | // here while looking for modifiers as that could result in false | 2141 | // here while looking for modifiers as that could result in false |
| 2075 | // positives. Therefore, start after a sentinel if there is one and | 2142 | // positives. Therefore, start after a sentinel if there is one and |
| 2076 | // skip over any align node and bit range nodes. | 2143 | // skip over any align node and bit range nodes. |
| 2077 | var i = if (info.sentinel != 0) tree.lastToken(info.sentinel) + 1 else switch (size) { | 2144 | var i = if (info.sentinel.unwrap()) |sentinel| tree.lastToken(sentinel) + 1 else switch (size) { |
| 2078 | .many, .c => info.main_token + 1, | 2145 | .many, .c => info.main_token + 1, |
| 2079 | else => info.main_token, | 2146 | else => info.main_token, |
| 2080 | }; | 2147 | }; |
| 2081 | const end = tree.firstToken(info.child_type); | 2148 | const end = tree.firstToken(info.child_type); |
| 2082 | while (i < end) : (i += 1) { | 2149 | while (i < end) : (i += 1) { |
| 2083 | switch (token_tags[i]) { | 2150 | switch (tree.tokenTag(i)) { |
| 2084 | .keyword_allowzero => result.allowzero_token = i, | 2151 | .keyword_allowzero => result.allowzero_token = i, |
| 2085 | .keyword_const => result.const_token = i, | 2152 | .keyword_const => result.const_token = i, |
| 2086 | .keyword_volatile => result.volatile_token = i, | 2153 | .keyword_volatile => result.volatile_token = i, |
| 2087 | .keyword_align => { | 2154 | .keyword_align => { |
| 2088 | assert(info.align_node != 0); | 2155 | const align_node = info.align_node.unwrap().?; |
| 2089 | if (info.bit_range_end != 0) { | 2156 | if (info.bit_range_end.unwrap()) |bit_range_end| { |
| 2090 | assert(info.bit_range_start != 0); | 2157 | assert(info.bit_range_start != .none); |
| 2091 | i = tree.lastToken(info.bit_range_end) + 1; | 2158 | i = tree.lastToken(bit_range_end) + 1; |
| 2092 | } else { | 2159 | } else { |
| 2093 | i = tree.lastToken(info.align_node) + 1; | 2160 | i = tree.lastToken(align_node) + 1; |
| 2094 | } | 2161 | } |
| 2095 | }, | 2162 | }, |
| 2096 | else => {}, | 2163 | else => {}, |
| ... | @@ -2100,30 +2167,29 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType | ... | @@ -2100,30 +2167,29 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType |
| 2100 | } | 2167 | } |
| 2101 | 2168 | ||
| 2102 | fn fullContainerDeclComponents(tree: Ast, info: full.ContainerDecl.Components) full.ContainerDecl { | 2169 | fn fullContainerDeclComponents(tree: Ast, info: full.ContainerDecl.Components) full.ContainerDecl { |
| 2103 | const token_tags = tree.tokens.items(.tag); | ||
| 2104 | var result: full.ContainerDecl = .{ | 2170 | var result: full.ContainerDecl = .{ |
| 2105 | .ast = info, | 2171 | .ast = info, |
| 2106 | .layout_token = null, | 2172 | .layout_token = null, |
| 2107 | }; | 2173 | }; |
| 2108 | 2174 | ||
| 2109 | if (info.main_token == 0) return result; | 2175 | if (info.main_token == 0) return result; // .root |
| 2176 | const previous_token = info.main_token - 1; | ||
| 2110 | 2177 | ||
| 2111 | switch (token_tags[info.main_token - 1]) { | 2178 | switch (tree.tokenTag(previous_token)) { |
| 2112 | .keyword_extern, .keyword_packed => result.layout_token = info.main_token - 1, | 2179 | .keyword_extern, .keyword_packed => result.layout_token = previous_token, |
| 2113 | else => {}, | 2180 | else => {}, |
| 2114 | } | 2181 | } |
| 2115 | return result; | 2182 | return result; |
| 2116 | } | 2183 | } |
| 2117 | 2184 | ||
| 2118 | fn fullSwitchComponents(tree: Ast, info: full.Switch.Components) full.Switch { | 2185 | fn fullSwitchComponents(tree: Ast, info: full.Switch.Components) full.Switch { |
| 2119 | const token_tags = tree.tokens.items(.tag); | ||
| 2120 | const tok_i = info.switch_token -| 1; | 2186 | const tok_i = info.switch_token -| 1; |
| 2121 | var result: full.Switch = .{ | 2187 | var result: full.Switch = .{ |
| 2122 | .ast = info, | 2188 | .ast = info, |
| 2123 | .label_token = null, | 2189 | .label_token = null, |
| 2124 | }; | 2190 | }; |
| 2125 | if (token_tags[tok_i] == .colon and | 2191 | if (tree.tokenTag(tok_i) == .colon and |
| 2126 | token_tags[tok_i -| 1] == .identifier) | 2192 | tree.tokenTag(tok_i -| 1) == .identifier) |
| 2127 | { | 2193 | { |
| 2128 | result.label_token = tok_i - 1; | 2194 | result.label_token = tok_i - 1; |
| 2129 | } | 2195 | } |
| ... | @@ -2131,26 +2197,25 @@ fn fullSwitchComponents(tree: Ast, info: full.Switch.Components) full.Switch { | ... | @@ -2131,26 +2197,25 @@ fn fullSwitchComponents(tree: Ast, info: full.Switch.Components) full.Switch { |
| 2131 | } | 2197 | } |
| 2132 | 2198 | ||
| 2133 | fn fullSwitchCaseComponents(tree: Ast, info: full.SwitchCase.Components, node: Node.Index) full.SwitchCase { | 2199 | fn fullSwitchCaseComponents(tree: Ast, info: full.SwitchCase.Components, node: Node.Index) full.SwitchCase { |
| 2134 | const token_tags = tree.tokens.items(.tag); | ||
| 2135 | const node_tags = tree.nodes.items(.tag); | ||
| 2136 | var result: full.SwitchCase = .{ | 2200 | var result: full.SwitchCase = .{ |
| 2137 | .ast = info, | 2201 | .ast = info, |
| 2138 | .payload_token = null, | 2202 | .payload_token = null, |
| 2139 | .inline_token = null, | 2203 | .inline_token = null, |
| 2140 | }; | 2204 | }; |
| 2141 | if (token_tags[info.arrow_token + 1] == .pipe) { | 2205 | if (tree.tokenTag(info.arrow_token + 1) == .pipe) { |
| 2142 | result.payload_token = info.arrow_token + 2; | 2206 | result.payload_token = info.arrow_token + 2; |
| 2143 | } | 2207 | } |
| 2144 | switch (node_tags[node]) { | 2208 | result.inline_token = switch (tree.nodeTag(node)) { |
| 2145 | .switch_case_inline, .switch_case_inline_one => result.inline_token = firstToken(tree, node), | 2209 | .switch_case_inline, .switch_case_inline_one => if (result.ast.values.len == 0) |
| 2146 | else => {}, | 2210 | info.arrow_token - 2 |
| 2147 | } | 2211 | else |
| 2212 | tree.firstToken(result.ast.values[0]) - 1, | ||
| 2213 | else => null, | ||
| 2214 | }; | ||
| 2148 | return result; | 2215 | return result; |
| 2149 | } | 2216 | } |
| 2150 | 2217 | ||
| 2151 | fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { | 2218 | fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { |
| 2152 | const token_tags = tree.tokens.items(.tag); | ||
| 2153 | const node_tags = tree.nodes.items(.tag); | ||
| 2154 | var result: full.Asm = .{ | 2219 | var result: full.Asm = .{ |
| 2155 | .ast = info, | 2220 | .ast = info, |
| 2156 | .volatile_token = null, | 2221 | .volatile_token = null, |
| ... | @@ -2158,11 +2223,11 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { | ... | @@ -2158,11 +2223,11 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { |
| 2158 | .outputs = &.{}, | 2223 | .outputs = &.{}, |
| 2159 | .first_clobber = null, | 2224 | .first_clobber = null, |
| 2160 | }; | 2225 | }; |
| 2161 | if (token_tags[info.asm_token + 1] == .keyword_volatile) { | 2226 | if (tree.tokenTag(info.asm_token + 1) == .keyword_volatile) { |
| 2162 | result.volatile_token = info.asm_token + 1; | 2227 | result.volatile_token = info.asm_token + 1; |
| 2163 | } | 2228 | } |
| 2164 | const outputs_end: usize = for (info.items, 0..) |item, i| { | 2229 | const outputs_end: usize = for (info.items, 0..) |item, i| { |
| 2165 | switch (node_tags[item]) { | 2230 | switch (tree.nodeTag(item)) { |
| 2166 | .asm_output => continue, | 2231 | .asm_output => continue, |
| 2167 | else => break i, | 2232 | else => break i, |
| 2168 | } | 2233 | } |
| ... | @@ -2174,10 +2239,10 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { | ... | @@ -2174,10 +2239,10 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { |
| 2174 | if (info.items.len == 0) { | 2239 | if (info.items.len == 0) { |
| 2175 | // asm ("foo" ::: "a", "b"); | 2240 | // asm ("foo" ::: "a", "b"); |
| 2176 | const template_token = tree.lastToken(info.template); | 2241 | const template_token = tree.lastToken(info.template); |
| 2177 | if (token_tags[template_token + 1] == .colon and | 2242 | if (tree.tokenTag(template_token + 1) == .colon and |
| 2178 | token_tags[template_token + 2] == .colon and | 2243 | tree.tokenTag(template_token + 2) == .colon and |
| 2179 | token_tags[template_token + 3] == .colon and | 2244 | tree.tokenTag(template_token + 3) == .colon and |
| 2180 | token_tags[template_token + 4] == .string_literal) | 2245 | tree.tokenTag(template_token + 4) == .string_literal) |
| 2181 | { | 2246 | { |
| 2182 | result.first_clobber = template_token + 4; | 2247 | result.first_clobber = template_token + 4; |
| 2183 | } | 2248 | } |
| ... | @@ -2187,9 +2252,9 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { | ... | @@ -2187,9 +2252,9 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { |
| 2187 | const rparen = tree.lastToken(last_input); | 2252 | const rparen = tree.lastToken(last_input); |
| 2188 | var i = rparen + 1; | 2253 | var i = rparen + 1; |
| 2189 | // Allow a (useless) comma right after the closing parenthesis. | 2254 | // Allow a (useless) comma right after the closing parenthesis. |
| 2190 | if (token_tags[i] == .comma) i += 1; | 2255 | if (tree.tokenTag(i) == .comma) i = i + 1; |
| 2191 | if (token_tags[i] == .colon and | 2256 | if (tree.tokenTag(i) == .colon and |
| 2192 | token_tags[i + 1] == .string_literal) | 2257 | tree.tokenTag(i + 1) == .string_literal) |
| 2193 | { | 2258 | { |
| 2194 | result.first_clobber = i + 1; | 2259 | result.first_clobber = i + 1; |
| 2195 | } | 2260 | } |
| ... | @@ -2199,10 +2264,10 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { | ... | @@ -2199,10 +2264,10 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { |
| 2199 | const rparen = tree.lastToken(last_output); | 2264 | const rparen = tree.lastToken(last_output); |
| 2200 | var i = rparen + 1; | 2265 | var i = rparen + 1; |
| 2201 | // Allow a (useless) comma right after the closing parenthesis. | 2266 | // Allow a (useless) comma right after the closing parenthesis. |
| 2202 | if (token_tags[i] == .comma) i += 1; | 2267 | if (tree.tokenTag(i) == .comma) i = i + 1; |
| 2203 | if (token_tags[i] == .colon and | 2268 | if (tree.tokenTag(i) == .colon and |
| 2204 | token_tags[i + 1] == .colon and | 2269 | tree.tokenTag(i + 1) == .colon and |
| 2205 | token_tags[i + 2] == .string_literal) | 2270 | tree.tokenTag(i + 2) == .string_literal) |
| 2206 | { | 2271 | { |
| 2207 | result.first_clobber = i + 2; | 2272 | result.first_clobber = i + 2; |
| 2208 | } | 2273 | } |
| ... | @@ -2212,7 +2277,6 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { | ... | @@ -2212,7 +2277,6 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { |
| 2212 | } | 2277 | } |
| 2213 | 2278 | ||
| 2214 | fn fullWhileComponents(tree: Ast, info: full.While.Components) full.While { | 2279 | fn fullWhileComponents(tree: Ast, info: full.While.Components) full.While { |
| 2215 | const token_tags = tree.tokens.items(.tag); | ||
| 2216 | var result: full.While = .{ | 2280 | var result: full.While = .{ |
| 2217 | .ast = info, | 2281 | .ast = info, |
| 2218 | .inline_token = null, | 2282 | .inline_token = null, |
| ... | @@ -2221,25 +2285,23 @@ fn fullWhileComponents(tree: Ast, info: full.While.Components) full.While { | ... | @@ -2221,25 +2285,23 @@ fn fullWhileComponents(tree: Ast, info: full.While.Components) full.While { |
| 2221 | .else_token = undefined, | 2285 | .else_token = undefined, |
| 2222 | .error_token = null, | 2286 | .error_token = null, |
| 2223 | }; | 2287 | }; |
| 2224 | var tok_i = info.while_token -| 1; | 2288 | var tok_i = info.while_token; |
| 2225 | if (token_tags[tok_i] == .keyword_inline) { | 2289 | if (tree.isTokenPrecededByTags(tok_i, &.{.keyword_inline})) { |
| 2226 | result.inline_token = tok_i; | 2290 | result.inline_token = tok_i - 1; |
| 2227 | tok_i -|= 1; | 2291 | tok_i = tok_i - 1; |
| 2228 | } | 2292 | } |
| 2229 | if (token_tags[tok_i] == .colon and | 2293 | if (tree.isTokenPrecededByTags(tok_i, &.{ .identifier, .colon })) { |
| 2230 | token_tags[tok_i -| 1] == .identifier) | 2294 | result.label_token = tok_i - 2; |
| 2231 | { | ||
| 2232 | result.label_token = tok_i - 1; | ||
| 2233 | } | 2295 | } |
| 2234 | const last_cond_token = tree.lastToken(info.cond_expr); | 2296 | const last_cond_token = tree.lastToken(info.cond_expr); |
| 2235 | if (token_tags[last_cond_token + 2] == .pipe) { | 2297 | if (tree.tokenTag(last_cond_token + 2) == .pipe) { |
| 2236 | result.payload_token = last_cond_token + 3; | 2298 | result.payload_token = last_cond_token + 3; |
| 2237 | } | 2299 | } |
| 2238 | if (info.else_expr != 0) { | 2300 | if (info.else_expr != .none) { |
| 2239 | // then_expr else |x| | 2301 | // then_expr else |x| |
| 2240 | // ^ ^ | 2302 | // ^ ^ |
| 2241 | result.else_token = tree.lastToken(info.then_expr) + 1; | 2303 | result.else_token = tree.lastToken(info.then_expr) + 1; |
| 2242 | if (token_tags[result.else_token + 1] == .pipe) { | 2304 | if (tree.tokenTag(result.else_token + 1) == .pipe) { |
| 2243 | result.error_token = result.else_token + 2; | 2305 | result.error_token = result.else_token + 2; |
| 2244 | } | 2306 | } |
| 2245 | } | 2307 | } |
| ... | @@ -2247,7 +2309,6 @@ fn fullWhileComponents(tree: Ast, info: full.While.Components) full.While { | ... | @@ -2247,7 +2309,6 @@ fn fullWhileComponents(tree: Ast, info: full.While.Components) full.While { |
| 2247 | } | 2309 | } |
| 2248 | 2310 | ||
| 2249 | fn fullForComponents(tree: Ast, info: full.For.Components) full.For { | 2311 | fn fullForComponents(tree: Ast, info: full.For.Components) full.For { |
| 2250 | const token_tags = tree.tokens.items(.tag); | ||
| 2251 | var result: full.For = .{ | 2312 | var result: full.For = .{ |
| 2252 | .ast = info, | 2313 | .ast = info, |
| 2253 | .inline_token = null, | 2314 | .inline_token = null, |
| ... | @@ -2255,39 +2316,36 @@ fn fullForComponents(tree: Ast, info: full.For.Components) full.For { | ... | @@ -2255,39 +2316,36 @@ fn fullForComponents(tree: Ast, info: full.For.Components) full.For { |
| 2255 | .payload_token = undefined, | 2316 | .payload_token = undefined, |
| 2256 | .else_token = undefined, | 2317 | .else_token = undefined, |
| 2257 | }; | 2318 | }; |
| 2258 | var tok_i = info.for_token -| 1; | 2319 | var tok_i = info.for_token; |
| 2259 | if (token_tags[tok_i] == .keyword_inline) { | 2320 | if (tree.isTokenPrecededByTags(tok_i, &.{.keyword_inline})) { |
| 2260 | result.inline_token = tok_i; | 2321 | result.inline_token = tok_i - 1; |
| 2261 | tok_i -|= 1; | 2322 | tok_i = tok_i - 1; |
| 2262 | } | 2323 | } |
| 2263 | if (token_tags[tok_i] == .colon and | 2324 | if (tree.isTokenPrecededByTags(tok_i, &.{ .identifier, .colon })) { |
| 2264 | token_tags[tok_i -| 1] == .identifier) | 2325 | result.label_token = tok_i - 2; |
| 2265 | { | ||
| 2266 | result.label_token = tok_i - 1; | ||
| 2267 | } | 2326 | } |
| 2268 | const last_cond_token = tree.lastToken(info.inputs[info.inputs.len - 1]); | 2327 | const last_cond_token = tree.lastToken(info.inputs[info.inputs.len - 1]); |
| 2269 | result.payload_token = last_cond_token + 3 + @intFromBool(token_tags[last_cond_token + 1] == .comma); | 2328 | result.payload_token = last_cond_token + @as(u32, 3) + @intFromBool(tree.tokenTag(last_cond_token + 1) == .comma); |
| 2270 | if (info.else_expr != 0) { | 2329 | if (info.else_expr != .none) { |
| 2271 | result.else_token = tree.lastToken(info.then_expr) + 1; | 2330 | result.else_token = tree.lastToken(info.then_expr) + 1; |
| 2272 | } | 2331 | } |
| 2273 | return result; | 2332 | return result; |
| 2274 | } | 2333 | } |
| 2275 | 2334 | ||
| 2276 | fn fullCallComponents(tree: Ast, info: full.Call.Components) full.Call { | 2335 | fn fullCallComponents(tree: Ast, info: full.Call.Components) full.Call { |
| 2277 | const token_tags = tree.tokens.items(.tag); | ||
| 2278 | var result: full.Call = .{ | 2336 | var result: full.Call = .{ |
| 2279 | .ast = info, | 2337 | .ast = info, |
| 2280 | .async_token = null, | 2338 | .async_token = null, |
| 2281 | }; | 2339 | }; |
| 2282 | const first_token = tree.firstToken(info.fn_expr); | 2340 | const first_token = tree.firstToken(info.fn_expr); |
| 2283 | if (first_token != 0 and token_tags[first_token - 1] == .keyword_async) { | 2341 | if (tree.isTokenPrecededByTags(first_token, &.{.keyword_async})) { |
| 2284 | result.async_token = first_token - 1; | 2342 | result.async_token = first_token - 1; |
| 2285 | } | 2343 | } |
| 2286 | return result; | 2344 | return result; |
| 2287 | } | 2345 | } |
| 2288 | 2346 | ||
| 2289 | pub fn fullVarDecl(tree: Ast, node: Node.Index) ?full.VarDecl { | 2347 | pub fn fullVarDecl(tree: Ast, node: Node.Index) ?full.VarDecl { |
| 2290 | return switch (tree.nodes.items(.tag)[node]) { | 2348 | return switch (tree.nodeTag(node)) { |
| 2291 | .global_var_decl => tree.globalVarDecl(node), | 2349 | .global_var_decl => tree.globalVarDecl(node), |
| 2292 | .local_var_decl => tree.localVarDecl(node), | 2350 | .local_var_decl => tree.localVarDecl(node), |
| 2293 | .aligned_var_decl => tree.alignedVarDecl(node), | 2351 | .aligned_var_decl => tree.alignedVarDecl(node), |
| ... | @@ -2297,7 +2355,7 @@ pub fn fullVarDecl(tree: Ast, node: Node.Index) ?full.VarDecl { | ... | @@ -2297,7 +2355,7 @@ pub fn fullVarDecl(tree: Ast, node: Node.Index) ?full.VarDecl { |
| 2297 | } | 2355 | } |
| 2298 | 2356 | ||
| 2299 | pub fn fullIf(tree: Ast, node: Node.Index) ?full.If { | 2357 | pub fn fullIf(tree: Ast, node: Node.Index) ?full.If { |
| 2300 | return switch (tree.nodes.items(.tag)[node]) { | 2358 | return switch (tree.nodeTag(node)) { |
| 2301 | .if_simple => tree.ifSimple(node), | 2359 | .if_simple => tree.ifSimple(node), |
| 2302 | .@"if" => tree.ifFull(node), | 2360 | .@"if" => tree.ifFull(node), |
| 2303 | else => null, | 2361 | else => null, |
| ... | @@ -2305,7 +2363,7 @@ pub fn fullIf(tree: Ast, node: Node.Index) ?full.If { | ... | @@ -2305,7 +2363,7 @@ pub fn fullIf(tree: Ast, node: Node.Index) ?full.If { |
| 2305 | } | 2363 | } |
| 2306 | 2364 | ||
| 2307 | pub fn fullWhile(tree: Ast, node: Node.Index) ?full.While { | 2365 | pub fn fullWhile(tree: Ast, node: Node.Index) ?full.While { |
| 2308 | return switch (tree.nodes.items(.tag)[node]) { | 2366 | return switch (tree.nodeTag(node)) { |
| 2309 | .while_simple => tree.whileSimple(node), | 2367 | .while_simple => tree.whileSimple(node), |
| 2310 | .while_cont => tree.whileCont(node), | 2368 | .while_cont => tree.whileCont(node), |
| 2311 | .@"while" => tree.whileFull(node), | 2369 | .@"while" => tree.whileFull(node), |
| ... | @@ -2314,7 +2372,7 @@ pub fn fullWhile(tree: Ast, node: Node.Index) ?full.While { | ... | @@ -2314,7 +2372,7 @@ pub fn fullWhile(tree: Ast, node: Node.Index) ?full.While { |
| 2314 | } | 2372 | } |
| 2315 | 2373 | ||
| 2316 | pub fn fullFor(tree: Ast, node: Node.Index) ?full.For { | 2374 | pub fn fullFor(tree: Ast, node: Node.Index) ?full.For { |
| 2317 | return switch (tree.nodes.items(.tag)[node]) { | 2375 | return switch (tree.nodeTag(node)) { |
| 2318 | .for_simple => tree.forSimple(node), | 2376 | .for_simple => tree.forSimple(node), |
| 2319 | .@"for" => tree.forFull(node), | 2377 | .@"for" => tree.forFull(node), |
| 2320 | else => null, | 2378 | else => null, |
| ... | @@ -2322,7 +2380,7 @@ pub fn fullFor(tree: Ast, node: Node.Index) ?full.For { | ... | @@ -2322,7 +2380,7 @@ pub fn fullFor(tree: Ast, node: Node.Index) ?full.For { |
| 2322 | } | 2380 | } |
| 2323 | 2381 | ||
| 2324 | pub fn fullContainerField(tree: Ast, node: Node.Index) ?full.ContainerField { | 2382 | pub fn fullContainerField(tree: Ast, node: Node.Index) ?full.ContainerField { |
| 2325 | return switch (tree.nodes.items(.tag)[node]) { | 2383 | return switch (tree.nodeTag(node)) { |
| 2326 | .container_field_init => tree.containerFieldInit(node), | 2384 | .container_field_init => tree.containerFieldInit(node), |
| 2327 | .container_field_align => tree.containerFieldAlign(node), | 2385 | .container_field_align => tree.containerFieldAlign(node), |
| 2328 | .container_field => tree.containerField(node), | 2386 | .container_field => tree.containerField(node), |
| ... | @@ -2331,18 +2389,18 @@ pub fn fullContainerField(tree: Ast, node: Node.Index) ?full.ContainerField { | ... | @@ -2331,18 +2389,18 @@ pub fn fullContainerField(tree: Ast, node: Node.Index) ?full.ContainerField { |
| 2331 | } | 2389 | } |
| 2332 | 2390 | ||
| 2333 | pub fn fullFnProto(tree: Ast, buffer: *[1]Ast.Node.Index, node: Node.Index) ?full.FnProto { | 2391 | pub fn fullFnProto(tree: Ast, buffer: *[1]Ast.Node.Index, node: Node.Index) ?full.FnProto { |
| 2334 | return switch (tree.nodes.items(.tag)[node]) { | 2392 | return switch (tree.nodeTag(node)) { |
| 2335 | .fn_proto => tree.fnProto(node), | 2393 | .fn_proto => tree.fnProto(node), |
| 2336 | .fn_proto_multi => tree.fnProtoMulti(node), | 2394 | .fn_proto_multi => tree.fnProtoMulti(node), |
| 2337 | .fn_proto_one => tree.fnProtoOne(buffer, node), | 2395 | .fn_proto_one => tree.fnProtoOne(buffer, node), |
| 2338 | .fn_proto_simple => tree.fnProtoSimple(buffer, node), | 2396 | .fn_proto_simple => tree.fnProtoSimple(buffer, node), |
| 2339 | .fn_decl => tree.fullFnProto(buffer, tree.nodes.items(.data)[node].lhs), | 2397 | .fn_decl => tree.fullFnProto(buffer, tree.nodeData(node).node_and_node[0]), |
| 2340 | else => null, | 2398 | else => null, |
| 2341 | }; | 2399 | }; |
| 2342 | } | 2400 | } |
| 2343 | 2401 | ||
| 2344 | pub fn fullStructInit(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index) ?full.StructInit { | 2402 | pub fn fullStructInit(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index) ?full.StructInit { |
| 2345 | return switch (tree.nodes.items(.tag)[node]) { | 2403 | return switch (tree.nodeTag(node)) { |
| 2346 | .struct_init_one, .struct_init_one_comma => tree.structInitOne(buffer[0..1], node), | 2404 | .struct_init_one, .struct_init_one_comma => tree.structInitOne(buffer[0..1], node), |
| 2347 | .struct_init_dot_two, .struct_init_dot_two_comma => tree.structInitDotTwo(buffer, node), | 2405 | .struct_init_dot_two, .struct_init_dot_two_comma => tree.structInitDotTwo(buffer, node), |
| 2348 | .struct_init_dot, .struct_init_dot_comma => tree.structInitDot(node), | 2406 | .struct_init_dot, .struct_init_dot_comma => tree.structInitDot(node), |
| ... | @@ -2352,7 +2410,7 @@ pub fn fullStructInit(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index) ? | ... | @@ -2352,7 +2410,7 @@ pub fn fullStructInit(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index) ? |
| 2352 | } | 2410 | } |
| 2353 | 2411 | ||
| 2354 | pub fn fullArrayInit(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) ?full.ArrayInit { | 2412 | pub fn fullArrayInit(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) ?full.ArrayInit { |
| 2355 | return switch (tree.nodes.items(.tag)[node]) { | 2413 | return switch (tree.nodeTag(node)) { |
| 2356 | .array_init_one, .array_init_one_comma => tree.arrayInitOne(buffer[0..1], node), | 2414 | .array_init_one, .array_init_one_comma => tree.arrayInitOne(buffer[0..1], node), |
| 2357 | .array_init_dot_two, .array_init_dot_two_comma => tree.arrayInitDotTwo(buffer, node), | 2415 | .array_init_dot_two, .array_init_dot_two_comma => tree.arrayInitDotTwo(buffer, node), |
| 2358 | .array_init_dot, .array_init_dot_comma => tree.arrayInitDot(node), | 2416 | .array_init_dot, .array_init_dot_comma => tree.arrayInitDot(node), |
| ... | @@ -2362,7 +2420,7 @@ pub fn fullArrayInit(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) ?full. | ... | @@ -2362,7 +2420,7 @@ pub fn fullArrayInit(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) ?full. |
| 2362 | } | 2420 | } |
| 2363 | 2421 | ||
| 2364 | pub fn fullArrayType(tree: Ast, node: Node.Index) ?full.ArrayType { | 2422 | pub fn fullArrayType(tree: Ast, node: Node.Index) ?full.ArrayType { |
| 2365 | return switch (tree.nodes.items(.tag)[node]) { | 2423 | return switch (tree.nodeTag(node)) { |
| 2366 | .array_type => tree.arrayType(node), | 2424 | .array_type => tree.arrayType(node), |
| 2367 | .array_type_sentinel => tree.arrayTypeSentinel(node), | 2425 | .array_type_sentinel => tree.arrayTypeSentinel(node), |
| 2368 | else => null, | 2426 | else => null, |
| ... | @@ -2370,7 +2428,7 @@ pub fn fullArrayType(tree: Ast, node: Node.Index) ?full.ArrayType { | ... | @@ -2370,7 +2428,7 @@ pub fn fullArrayType(tree: Ast, node: Node.Index) ?full.ArrayType { |
| 2370 | } | 2428 | } |
| 2371 | 2429 | ||
| 2372 | pub fn fullPtrType(tree: Ast, node: Node.Index) ?full.PtrType { | 2430 | pub fn fullPtrType(tree: Ast, node: Node.Index) ?full.PtrType { |
| 2373 | return switch (tree.nodes.items(.tag)[node]) { | 2431 | return switch (tree.nodeTag(node)) { |
| 2374 | .ptr_type_aligned => tree.ptrTypeAligned(node), | 2432 | .ptr_type_aligned => tree.ptrTypeAligned(node), |
| 2375 | .ptr_type_sentinel => tree.ptrTypeSentinel(node), | 2433 | .ptr_type_sentinel => tree.ptrTypeSentinel(node), |
| 2376 | .ptr_type => tree.ptrType(node), | 2434 | .ptr_type => tree.ptrType(node), |
| ... | @@ -2380,7 +2438,7 @@ pub fn fullPtrType(tree: Ast, node: Node.Index) ?full.PtrType { | ... | @@ -2380,7 +2438,7 @@ pub fn fullPtrType(tree: Ast, node: Node.Index) ?full.PtrType { |
| 2380 | } | 2438 | } |
| 2381 | 2439 | ||
| 2382 | pub fn fullSlice(tree: Ast, node: Node.Index) ?full.Slice { | 2440 | pub fn fullSlice(tree: Ast, node: Node.Index) ?full.Slice { |
| 2383 | return switch (tree.nodes.items(.tag)[node]) { | 2441 | return switch (tree.nodeTag(node)) { |
| 2384 | .slice_open => tree.sliceOpen(node), | 2442 | .slice_open => tree.sliceOpen(node), |
| 2385 | .slice => tree.slice(node), | 2443 | .slice => tree.slice(node), |
| 2386 | .slice_sentinel => tree.sliceSentinel(node), | 2444 | .slice_sentinel => tree.sliceSentinel(node), |
| ... | @@ -2389,7 +2447,7 @@ pub fn fullSlice(tree: Ast, node: Node.Index) ?full.Slice { | ... | @@ -2389,7 +2447,7 @@ pub fn fullSlice(tree: Ast, node: Node.Index) ?full.Slice { |
| 2389 | } | 2447 | } |
| 2390 | 2448 | ||
| 2391 | pub fn fullContainerDecl(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index) ?full.ContainerDecl { | 2449 | pub fn fullContainerDecl(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index) ?full.ContainerDecl { |
| 2392 | return switch (tree.nodes.items(.tag)[node]) { | 2450 | return switch (tree.nodeTag(node)) { |
| 2393 | .root => tree.containerDeclRoot(), | 2451 | .root => tree.containerDeclRoot(), |
| 2394 | .container_decl, .container_decl_trailing => tree.containerDecl(node), | 2452 | .container_decl, .container_decl_trailing => tree.containerDecl(node), |
| 2395 | .container_decl_arg, .container_decl_arg_trailing => tree.containerDeclArg(node), | 2453 | .container_decl_arg, .container_decl_arg_trailing => tree.containerDeclArg(node), |
| ... | @@ -2402,14 +2460,14 @@ pub fn fullContainerDecl(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index | ... | @@ -2402,14 +2460,14 @@ pub fn fullContainerDecl(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index |
| 2402 | } | 2460 | } |
| 2403 | 2461 | ||
| 2404 | pub fn fullSwitch(tree: Ast, node: Node.Index) ?full.Switch { | 2462 | pub fn fullSwitch(tree: Ast, node: Node.Index) ?full.Switch { |
| 2405 | return switch (tree.nodes.items(.tag)[node]) { | 2463 | return switch (tree.nodeTag(node)) { |
| 2406 | .@"switch", .switch_comma => tree.switchFull(node), | 2464 | .@"switch", .switch_comma => tree.switchFull(node), |
| 2407 | else => null, | 2465 | else => null, |
| 2408 | }; | 2466 | }; |
| 2409 | } | 2467 | } |
| 2410 | 2468 | ||
| 2411 | pub fn fullSwitchCase(tree: Ast, node: Node.Index) ?full.SwitchCase { | 2469 | pub fn fullSwitchCase(tree: Ast, node: Node.Index) ?full.SwitchCase { |
| 2412 | return switch (tree.nodes.items(.tag)[node]) { | 2470 | return switch (tree.nodeTag(node)) { |
| 2413 | .switch_case_one, .switch_case_inline_one => tree.switchCaseOne(node), | 2471 | .switch_case_one, .switch_case_inline_one => tree.switchCaseOne(node), |
| 2414 | .switch_case, .switch_case_inline => tree.switchCase(node), | 2472 | .switch_case, .switch_case_inline => tree.switchCase(node), |
| 2415 | else => null, | 2473 | else => null, |
| ... | @@ -2417,7 +2475,7 @@ pub fn fullSwitchCase(tree: Ast, node: Node.Index) ?full.SwitchCase { | ... | @@ -2417,7 +2475,7 @@ pub fn fullSwitchCase(tree: Ast, node: Node.Index) ?full.SwitchCase { |
| 2417 | } | 2475 | } |
| 2418 | 2476 | ||
| 2419 | pub fn fullAsm(tree: Ast, node: Node.Index) ?full.Asm { | 2477 | pub fn fullAsm(tree: Ast, node: Node.Index) ?full.Asm { |
| 2420 | return switch (tree.nodes.items(.tag)[node]) { | 2478 | return switch (tree.nodeTag(node)) { |
| 2421 | .asm_simple => tree.asmSimple(node), | 2479 | .asm_simple => tree.asmSimple(node), |
| 2422 | .@"asm" => tree.asmFull(node), | 2480 | .@"asm" => tree.asmFull(node), |
| 2423 | else => null, | 2481 | else => null, |
| ... | @@ -2425,7 +2483,7 @@ pub fn fullAsm(tree: Ast, node: Node.Index) ?full.Asm { | ... | @@ -2425,7 +2483,7 @@ pub fn fullAsm(tree: Ast, node: Node.Index) ?full.Asm { |
| 2425 | } | 2483 | } |
| 2426 | 2484 | ||
| 2427 | pub fn fullCall(tree: Ast, buffer: *[1]Ast.Node.Index, node: Node.Index) ?full.Call { | 2485 | pub fn fullCall(tree: Ast, buffer: *[1]Ast.Node.Index, node: Node.Index) ?full.Call { |
| 2428 | return switch (tree.nodes.items(.tag)[node]) { | 2486 | return switch (tree.nodeTag(node)) { |
| 2429 | .call, .call_comma, .async_call, .async_call_comma => tree.callFull(node), | 2487 | .call, .call_comma, .async_call, .async_call_comma => tree.callFull(node), |
| 2430 | .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => tree.callOne(buffer, node), | 2488 | .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => tree.callOne(buffer, node), |
| 2431 | else => null, | 2489 | else => null, |
| ... | @@ -2433,37 +2491,17 @@ pub fn fullCall(tree: Ast, buffer: *[1]Ast.Node.Index, node: Node.Index) ?full.C | ... | @@ -2433,37 +2491,17 @@ pub fn fullCall(tree: Ast, buffer: *[1]Ast.Node.Index, node: Node.Index) ?full.C |
| 2433 | } | 2491 | } |
| 2434 | 2492 | ||
| 2435 | pub fn builtinCallParams(tree: Ast, buffer: *[2]Ast.Node.Index, node: Ast.Node.Index) ?[]const Node.Index { | 2493 | pub fn builtinCallParams(tree: Ast, buffer: *[2]Ast.Node.Index, node: Ast.Node.Index) ?[]const Node.Index { |
| 2436 | const data = tree.nodes.items(.data)[node]; | 2494 | return switch (tree.nodeTag(node)) { |
| 2437 | return switch (tree.nodes.items(.tag)[node]) { | 2495 | .builtin_call_two, .builtin_call_two_comma => loadOptionalNodesIntoBuffer(2, buffer, tree.nodeData(node).opt_node_and_opt_node), |
| 2438 | .builtin_call_two, .builtin_call_two_comma => { | 2496 | .builtin_call, .builtin_call_comma => tree.extraDataSlice(tree.nodeData(node).extra_range, Node.Index), |
| 2439 | buffer.* = .{ data.lhs, data.rhs }; | ||
| 2440 | if (data.rhs != 0) { | ||
| 2441 | return buffer[0..2]; | ||
| 2442 | } else if (data.lhs != 0) { | ||
| 2443 | return buffer[0..1]; | ||
| 2444 | } else { | ||
| 2445 | return buffer[0..0]; | ||
| 2446 | } | ||
| 2447 | }, | ||
| 2448 | .builtin_call, .builtin_call_comma => tree.extra_data[data.lhs..data.rhs], | ||
| 2449 | else => null, | 2497 | else => null, |
| 2450 | }; | 2498 | }; |
| 2451 | } | 2499 | } |
| 2452 | 2500 | ||
| 2453 | pub fn blockStatements(tree: Ast, buffer: *[2]Ast.Node.Index, node: Ast.Node.Index) ?[]const Node.Index { | 2501 | pub fn blockStatements(tree: Ast, buffer: *[2]Ast.Node.Index, node: Ast.Node.Index) ?[]const Node.Index { |
| 2454 | const data = tree.nodes.items(.data)[node]; | 2502 | return switch (tree.nodeTag(node)) { |
| 2455 | return switch (tree.nodes.items(.tag)[node]) { | 2503 | .block_two, .block_two_semicolon => loadOptionalNodesIntoBuffer(2, buffer, tree.nodeData(node).opt_node_and_opt_node), |
| 2456 | .block_two, .block_two_semicolon => { | 2504 | .block, .block_semicolon => tree.extraDataSlice(tree.nodeData(node).extra_range, Node.Index), |
| 2457 | buffer.* = .{ data.lhs, data.rhs }; | ||
| 2458 | if (data.rhs != 0) { | ||
| 2459 | return buffer[0..2]; | ||
| 2460 | } else if (data.lhs != 0) { | ||
| 2461 | return buffer[0..1]; | ||
| 2462 | } else { | ||
| 2463 | return buffer[0..0]; | ||
| 2464 | } | ||
| 2465 | }, | ||
| 2466 | .block, .block_semicolon => tree.extra_data[data.lhs..data.rhs], | ||
| 2467 | else => null, | 2505 | else => null, |
| 2468 | }; | 2506 | }; |
| 2469 | } | 2507 | } |
| ... | @@ -2480,11 +2518,11 @@ pub const full = struct { | ... | @@ -2480,11 +2518,11 @@ pub const full = struct { |
| 2480 | 2518 | ||
| 2481 | pub const Components = struct { | 2519 | pub const Components = struct { |
| 2482 | mut_token: TokenIndex, | 2520 | mut_token: TokenIndex, |
| 2483 | type_node: Node.Index, | 2521 | type_node: Node.OptionalIndex, |
| 2484 | align_node: Node.Index, | 2522 | align_node: Node.OptionalIndex, |
| 2485 | addrspace_node: Node.Index, | 2523 | addrspace_node: Node.OptionalIndex, |
| 2486 | section_node: Node.Index, | 2524 | section_node: Node.OptionalIndex, |
| 2487 | init_node: Node.Index, | 2525 | init_node: Node.OptionalIndex, |
| 2488 | }; | 2526 | }; |
| 2489 | 2527 | ||
| 2490 | pub fn firstToken(var_decl: VarDecl) TokenIndex { | 2528 | pub fn firstToken(var_decl: VarDecl) TokenIndex { |
| ... | @@ -2513,7 +2551,7 @@ pub const full = struct { | ... | @@ -2513,7 +2551,7 @@ pub const full = struct { |
| 2513 | payload_token: ?TokenIndex, | 2551 | payload_token: ?TokenIndex, |
| 2514 | /// Points to the identifier after the `|`. | 2552 | /// Points to the identifier after the `|`. |
| 2515 | error_token: ?TokenIndex, | 2553 | error_token: ?TokenIndex, |
| 2516 | /// Populated only if else_expr != 0. | 2554 | /// Populated only if else_expr != .none. |
| 2517 | else_token: TokenIndex, | 2555 | else_token: TokenIndex, |
| 2518 | ast: Components, | 2556 | ast: Components, |
| 2519 | 2557 | ||
| ... | @@ -2521,7 +2559,7 @@ pub const full = struct { | ... | @@ -2521,7 +2559,7 @@ pub const full = struct { |
| 2521 | if_token: TokenIndex, | 2559 | if_token: TokenIndex, |
| 2522 | cond_expr: Node.Index, | 2560 | cond_expr: Node.Index, |
| 2523 | then_expr: Node.Index, | 2561 | then_expr: Node.Index, |
| 2524 | else_expr: Node.Index, | 2562 | else_expr: Node.OptionalIndex, |
| 2525 | }; | 2563 | }; |
| 2526 | }; | 2564 | }; |
| 2527 | 2565 | ||
| ... | @@ -2531,15 +2569,15 @@ pub const full = struct { | ... | @@ -2531,15 +2569,15 @@ pub const full = struct { |
| 2531 | label_token: ?TokenIndex, | 2569 | label_token: ?TokenIndex, |
| 2532 | payload_token: ?TokenIndex, | 2570 | payload_token: ?TokenIndex, |
| 2533 | error_token: ?TokenIndex, | 2571 | error_token: ?TokenIndex, |
| 2534 | /// Populated only if else_expr != 0. | 2572 | /// Populated only if else_expr != none. |
| 2535 | else_token: TokenIndex, | 2573 | else_token: TokenIndex, |
| 2536 | 2574 | ||
| 2537 | pub const Components = struct { | 2575 | pub const Components = struct { |
| 2538 | while_token: TokenIndex, | 2576 | while_token: TokenIndex, |
| 2539 | cond_expr: Node.Index, | 2577 | cond_expr: Node.Index, |
| 2540 | cont_expr: Node.Index, | 2578 | cont_expr: Node.OptionalIndex, |
| 2541 | then_expr: Node.Index, | 2579 | then_expr: Node.Index, |
| 2542 | else_expr: Node.Index, | 2580 | else_expr: Node.OptionalIndex, |
| 2543 | }; | 2581 | }; |
| 2544 | }; | 2582 | }; |
| 2545 | 2583 | ||
| ... | @@ -2548,14 +2586,14 @@ pub const full = struct { | ... | @@ -2548,14 +2586,14 @@ pub const full = struct { |
| 2548 | inline_token: ?TokenIndex, | 2586 | inline_token: ?TokenIndex, |
| 2549 | label_token: ?TokenIndex, | 2587 | label_token: ?TokenIndex, |
| 2550 | payload_token: TokenIndex, | 2588 | payload_token: TokenIndex, |
| 2551 | /// Populated only if else_expr != 0. | 2589 | /// Populated only if else_expr != .none. |
| 2552 | else_token: TokenIndex, | 2590 | else_token: ?TokenIndex, |
| 2553 | 2591 | ||
| 2554 | pub const Components = struct { | 2592 | pub const Components = struct { |
| 2555 | for_token: TokenIndex, | 2593 | for_token: TokenIndex, |
| 2556 | inputs: []const Node.Index, | 2594 | inputs: []const Node.Index, |
| 2557 | then_expr: Node.Index, | 2595 | then_expr: Node.Index, |
| 2558 | else_expr: Node.Index, | 2596 | else_expr: Node.OptionalIndex, |
| 2559 | }; | 2597 | }; |
| 2560 | }; | 2598 | }; |
| 2561 | 2599 | ||
| ... | @@ -2565,9 +2603,10 @@ pub const full = struct { | ... | @@ -2565,9 +2603,10 @@ pub const full = struct { |
| 2565 | 2603 | ||
| 2566 | pub const Components = struct { | 2604 | pub const Components = struct { |
| 2567 | main_token: TokenIndex, | 2605 | main_token: TokenIndex, |
| 2568 | type_expr: Node.Index, | 2606 | /// Can only be `.none` after calling `convertToNonTupleLike`. |
| 2569 | align_expr: Node.Index, | 2607 | type_expr: Node.OptionalIndex, |
| 2570 | value_expr: Node.Index, | 2608 | align_expr: Node.OptionalIndex, |
| 2609 | value_expr: Node.OptionalIndex, | ||
| 2571 | tuple_like: bool, | 2610 | tuple_like: bool, |
| 2572 | }; | 2611 | }; |
| 2573 | 2612 | ||
| ... | @@ -2575,11 +2614,11 @@ pub const full = struct { | ... | @@ -2575,11 +2614,11 @@ pub const full = struct { |
| 2575 | return cf.comptime_token orelse cf.ast.main_token; | 2614 | return cf.comptime_token orelse cf.ast.main_token; |
| 2576 | } | 2615 | } |
| 2577 | 2616 | ||
| 2578 | pub fn convertToNonTupleLike(cf: *ContainerField, nodes: NodeList.Slice) void { | 2617 | pub fn convertToNonTupleLike(cf: *ContainerField, tree: *const Ast) void { |
| 2579 | if (!cf.ast.tuple_like) return; | 2618 | if (!cf.ast.tuple_like) return; |
| 2580 | if (nodes.items(.tag)[cf.ast.type_expr] != .identifier) return; | 2619 | if (tree.nodeTag(cf.ast.type_expr.unwrap().?) != .identifier) return; |
| 2581 | 2620 | ||
| 2582 | cf.ast.type_expr = 0; | 2621 | cf.ast.type_expr = .none; |
| 2583 | cf.ast.tuple_like = false; | 2622 | cf.ast.tuple_like = false; |
| 2584 | } | 2623 | } |
| 2585 | }; | 2624 | }; |
| ... | @@ -2595,12 +2634,12 @@ pub const full = struct { | ... | @@ -2595,12 +2634,12 @@ pub const full = struct { |
| 2595 | pub const Components = struct { | 2634 | pub const Components = struct { |
| 2596 | proto_node: Node.Index, | 2635 | proto_node: Node.Index, |
| 2597 | fn_token: TokenIndex, | 2636 | fn_token: TokenIndex, |
| 2598 | return_type: Node.Index, | 2637 | return_type: Node.OptionalIndex, |
| 2599 | params: []const Node.Index, | 2638 | params: []const Node.Index, |
| 2600 | align_expr: Node.Index, | 2639 | align_expr: Node.OptionalIndex, |
| 2601 | addrspace_expr: Node.Index, | 2640 | addrspace_expr: Node.OptionalIndex, |
| 2602 | section_expr: Node.Index, | 2641 | section_expr: Node.OptionalIndex, |
| 2603 | callconv_expr: Node.Index, | 2642 | callconv_expr: Node.OptionalIndex, |
| 2604 | }; | 2643 | }; |
| 2605 | 2644 | ||
| 2606 | pub const Param = struct { | 2645 | pub const Param = struct { |
| ... | @@ -2608,7 +2647,7 @@ pub const full = struct { | ... | @@ -2608,7 +2647,7 @@ pub const full = struct { |
| 2608 | name_token: ?TokenIndex, | 2647 | name_token: ?TokenIndex, |
| 2609 | comptime_noalias: ?TokenIndex, | 2648 | comptime_noalias: ?TokenIndex, |
| 2610 | anytype_ellipsis3: ?TokenIndex, | 2649 | anytype_ellipsis3: ?TokenIndex, |
| 2611 | type_expr: Node.Index, | 2650 | type_expr: ?Node.Index, |
| 2612 | }; | 2651 | }; |
| 2613 | 2652 | ||
| 2614 | pub fn firstToken(fn_proto: FnProto) TokenIndex { | 2653 | pub fn firstToken(fn_proto: FnProto) TokenIndex { |
| ... | @@ -2628,7 +2667,7 @@ pub const full = struct { | ... | @@ -2628,7 +2667,7 @@ pub const full = struct { |
| 2628 | tok_flag: bool, | 2667 | tok_flag: bool, |
| 2629 | 2668 | ||
| 2630 | pub fn next(it: *Iterator) ?Param { | 2669 | pub fn next(it: *Iterator) ?Param { |
| 2631 | const token_tags = it.tree.tokens.items(.tag); | 2670 | const tree = it.tree; |
| 2632 | while (true) { | 2671 | while (true) { |
| 2633 | var first_doc_comment: ?TokenIndex = null; | 2672 | var first_doc_comment: ?TokenIndex = null; |
| 2634 | var comptime_noalias: ?TokenIndex = null; | 2673 | var comptime_noalias: ?TokenIndex = null; |
| ... | @@ -2638,8 +2677,8 @@ pub const full = struct { | ... | @@ -2638,8 +2677,8 @@ pub const full = struct { |
| 2638 | return null; | 2677 | return null; |
| 2639 | } | 2678 | } |
| 2640 | const param_type = it.fn_proto.ast.params[it.param_i]; | 2679 | const param_type = it.fn_proto.ast.params[it.param_i]; |
| 2641 | var tok_i = it.tree.firstToken(param_type) - 1; | 2680 | var tok_i = tree.firstToken(param_type) - 1; |
| 2642 | while (true) : (tok_i -= 1) switch (token_tags[tok_i]) { | 2681 | while (true) : (tok_i -= 1) switch (tree.tokenTag(tok_i)) { |
| 2643 | .colon => continue, | 2682 | .colon => continue, |
| 2644 | .identifier => name_token = tok_i, | 2683 | .identifier => name_token = tok_i, |
| 2645 | .doc_comment => first_doc_comment = tok_i, | 2684 | .doc_comment => first_doc_comment = tok_i, |
| ... | @@ -2647,9 +2686,9 @@ pub const full = struct { | ... | @@ -2647,9 +2686,9 @@ pub const full = struct { |
| 2647 | else => break, | 2686 | else => break, |
| 2648 | }; | 2687 | }; |
| 2649 | it.param_i += 1; | 2688 | it.param_i += 1; |
| 2650 | it.tok_i = it.tree.lastToken(param_type) + 1; | 2689 | it.tok_i = tree.lastToken(param_type) + 1; |
| 2651 | // Look for anytype and ... params afterwards. | 2690 | // Look for anytype and ... params afterwards. |
| 2652 | if (token_tags[it.tok_i] == .comma) { | 2691 | if (tree.tokenTag(it.tok_i) == .comma) { |
| 2653 | it.tok_i += 1; | 2692 | it.tok_i += 1; |
| 2654 | } | 2693 | } |
| 2655 | it.tok_flag = true; | 2694 | it.tok_flag = true; |
| ... | @@ -2661,19 +2700,19 @@ pub const full = struct { | ... | @@ -2661,19 +2700,19 @@ pub const full = struct { |
| 2661 | .type_expr = param_type, | 2700 | .type_expr = param_type, |
| 2662 | }; | 2701 | }; |
| 2663 | } | 2702 | } |
| 2664 | if (token_tags[it.tok_i] == .comma) { | 2703 | if (tree.tokenTag(it.tok_i) == .comma) { |
| 2665 | it.tok_i += 1; | 2704 | it.tok_i += 1; |
| 2666 | } | 2705 | } |
| 2667 | if (token_tags[it.tok_i] == .r_paren) { | 2706 | if (tree.tokenTag(it.tok_i) == .r_paren) { |
| 2668 | return null; | 2707 | return null; |
| 2669 | } | 2708 | } |
| 2670 | if (token_tags[it.tok_i] == .doc_comment) { | 2709 | if (tree.tokenTag(it.tok_i) == .doc_comment) { |
| 2671 | first_doc_comment = it.tok_i; | 2710 | first_doc_comment = it.tok_i; |
| 2672 | while (token_tags[it.tok_i] == .doc_comment) { | 2711 | while (tree.tokenTag(it.tok_i) == .doc_comment) { |
| 2673 | it.tok_i += 1; | 2712 | it.tok_i += 1; |
| 2674 | } | 2713 | } |
| 2675 | } | 2714 | } |
| 2676 | switch (token_tags[it.tok_i]) { | 2715 | switch (tree.tokenTag(it.tok_i)) { |
| 2677 | .ellipsis3 => { | 2716 | .ellipsis3 => { |
| 2678 | it.tok_flag = false; // Next iteration should return null. | 2717 | it.tok_flag = false; // Next iteration should return null. |
| 2679 | return Param{ | 2718 | return Param{ |
| ... | @@ -2681,7 +2720,7 @@ pub const full = struct { | ... | @@ -2681,7 +2720,7 @@ pub const full = struct { |
| 2681 | .comptime_noalias = null, | 2720 | .comptime_noalias = null, |
| 2682 | .name_token = null, | 2721 | .name_token = null, |
| 2683 | .anytype_ellipsis3 = it.tok_i, | 2722 | .anytype_ellipsis3 = it.tok_i, |
| 2684 | .type_expr = 0, | 2723 | .type_expr = null, |
| 2685 | }; | 2724 | }; |
| 2686 | }, | 2725 | }, |
| 2687 | .keyword_noalias, .keyword_comptime => { | 2726 | .keyword_noalias, .keyword_comptime => { |
| ... | @@ -2690,20 +2729,20 @@ pub const full = struct { | ... | @@ -2690,20 +2729,20 @@ pub const full = struct { |
| 2690 | }, | 2729 | }, |
| 2691 | else => {}, | 2730 | else => {}, |
| 2692 | } | 2731 | } |
| 2693 | if (token_tags[it.tok_i] == .identifier and | 2732 | if (tree.tokenTag(it.tok_i) == .identifier and |
| 2694 | token_tags[it.tok_i + 1] == .colon) | 2733 | tree.tokenTag(it.tok_i + 1) == .colon) |
| 2695 | { | 2734 | { |
| 2696 | name_token = it.tok_i; | 2735 | name_token = it.tok_i; |
| 2697 | it.tok_i += 2; | 2736 | it.tok_i += 2; |
| 2698 | } | 2737 | } |
| 2699 | if (token_tags[it.tok_i] == .keyword_anytype) { | 2738 | if (tree.tokenTag(it.tok_i) == .keyword_anytype) { |
| 2700 | it.tok_i += 1; | 2739 | it.tok_i += 1; |
| 2701 | return Param{ | 2740 | return Param{ |
| 2702 | .first_doc_comment = first_doc_comment, | 2741 | .first_doc_comment = first_doc_comment, |
| 2703 | .comptime_noalias = comptime_noalias, | 2742 | .comptime_noalias = comptime_noalias, |
| 2704 | .name_token = name_token, | 2743 | .name_token = name_token, |
| 2705 | .anytype_ellipsis3 = it.tok_i - 1, | 2744 | .anytype_ellipsis3 = it.tok_i - 1, |
| 2706 | .type_expr = 0, | 2745 | .type_expr = null, |
| 2707 | }; | 2746 | }; |
| 2708 | } | 2747 | } |
| 2709 | it.tok_flag = false; | 2748 | it.tok_flag = false; |
| ... | @@ -2728,7 +2767,7 @@ pub const full = struct { | ... | @@ -2728,7 +2767,7 @@ pub const full = struct { |
| 2728 | pub const Components = struct { | 2767 | pub const Components = struct { |
| 2729 | lbrace: TokenIndex, | 2768 | lbrace: TokenIndex, |
| 2730 | fields: []const Node.Index, | 2769 | fields: []const Node.Index, |
| 2731 | type_expr: Node.Index, | 2770 | type_expr: Node.OptionalIndex, |
| 2732 | }; | 2771 | }; |
| 2733 | }; | 2772 | }; |
| 2734 | 2773 | ||
| ... | @@ -2738,7 +2777,7 @@ pub const full = struct { | ... | @@ -2738,7 +2777,7 @@ pub const full = struct { |
| 2738 | pub const Components = struct { | 2777 | pub const Components = struct { |
| 2739 | lbrace: TokenIndex, | 2778 | lbrace: TokenIndex, |
| 2740 | elements: []const Node.Index, | 2779 | elements: []const Node.Index, |
| 2741 | type_expr: Node.Index, | 2780 | type_expr: Node.OptionalIndex, |
| 2742 | }; | 2781 | }; |
| 2743 | }; | 2782 | }; |
| 2744 | 2783 | ||
| ... | @@ -2748,7 +2787,7 @@ pub const full = struct { | ... | @@ -2748,7 +2787,7 @@ pub const full = struct { |
| 2748 | pub const Components = struct { | 2787 | pub const Components = struct { |
| 2749 | lbracket: TokenIndex, | 2788 | lbracket: TokenIndex, |
| 2750 | elem_count: Node.Index, | 2789 | elem_count: Node.Index, |
| 2751 | sentinel: Node.Index, | 2790 | sentinel: Node.OptionalIndex, |
| 2752 | elem_type: Node.Index, | 2791 | elem_type: Node.Index, |
| 2753 | }; | 2792 | }; |
| 2754 | }; | 2793 | }; |
| ... | @@ -2762,11 +2801,11 @@ pub const full = struct { | ... | @@ -2762,11 +2801,11 @@ pub const full = struct { |
| 2762 | 2801 | ||
| 2763 | pub const Components = struct { | 2802 | pub const Components = struct { |
| 2764 | main_token: TokenIndex, | 2803 | main_token: TokenIndex, |
| 2765 | align_node: Node.Index, | 2804 | align_node: Node.OptionalIndex, |
| 2766 | addrspace_node: Node.Index, | 2805 | addrspace_node: Node.OptionalIndex, |
| 2767 | sentinel: Node.Index, | 2806 | sentinel: Node.OptionalIndex, |
| 2768 | bit_range_start: Node.Index, | 2807 | bit_range_start: Node.OptionalIndex, |
| 2769 | bit_range_end: Node.Index, | 2808 | bit_range_end: Node.OptionalIndex, |
| 2770 | child_type: Node.Index, | 2809 | child_type: Node.Index, |
| 2771 | }; | 2810 | }; |
| 2772 | }; | 2811 | }; |
| ... | @@ -2778,8 +2817,8 @@ pub const full = struct { | ... | @@ -2778,8 +2817,8 @@ pub const full = struct { |
| 2778 | sliced: Node.Index, | 2817 | sliced: Node.Index, |
| 2779 | lbracket: TokenIndex, | 2818 | lbracket: TokenIndex, |
| 2780 | start: Node.Index, | 2819 | start: Node.Index, |
| 2781 | end: Node.Index, | 2820 | end: Node.OptionalIndex, |
| 2782 | sentinel: Node.Index, | 2821 | sentinel: Node.OptionalIndex, |
| 2783 | }; | 2822 | }; |
| 2784 | }; | 2823 | }; |
| 2785 | 2824 | ||
| ... | @@ -2792,7 +2831,7 @@ pub const full = struct { | ... | @@ -2792,7 +2831,7 @@ pub const full = struct { |
| 2792 | /// Populated when main_token is Keyword_union. | 2831 | /// Populated when main_token is Keyword_union. |
| 2793 | enum_token: ?TokenIndex, | 2832 | enum_token: ?TokenIndex, |
| 2794 | members: []const Node.Index, | 2833 | members: []const Node.Index, |
| 2795 | arg: Node.Index, | 2834 | arg: Node.OptionalIndex, |
| 2796 | }; | 2835 | }; |
| 2797 | }; | 2836 | }; |
| 2798 | 2837 | ||
| ... | @@ -2935,16 +2974,82 @@ pub const Error = struct { | ... | @@ -2935,16 +2974,82 @@ pub const Error = struct { |
| 2935 | }; | 2974 | }; |
| 2936 | }; | 2975 | }; |
| 2937 | 2976 | ||
| 2977 | /// Index into `extra_data`. | ||
| 2978 | pub const ExtraIndex = enum(u32) { | ||
| 2979 | _, | ||
| 2980 | }; | ||
| 2981 | |||
| 2938 | pub const Node = struct { | 2982 | pub const Node = struct { |
| 2939 | tag: Tag, | 2983 | tag: Tag, |
| 2940 | main_token: TokenIndex, | 2984 | main_token: TokenIndex, |
| 2941 | data: Data, | 2985 | data: Data, |
| 2942 | 2986 | ||
| 2943 | pub const Index = u32; | 2987 | /// Index into `nodes`. |
| 2988 | pub const Index = enum(u32) { | ||
| 2989 | root = 0, | ||
| 2990 | _, | ||
| 2991 | |||
| 2992 | pub fn toOptional(i: Index) OptionalIndex { | ||
| 2993 | const result: OptionalIndex = @enumFromInt(@intFromEnum(i)); | ||
| 2994 | assert(result != .none); | ||
| 2995 | return result; | ||
| 2996 | } | ||
| 2997 | |||
| 2998 | pub fn toOffset(base: Index, destination: Index) Offset { | ||
| 2999 | const base_i64: i64 = @intFromEnum(base); | ||
| 3000 | const destination_i64: i64 = @intFromEnum(destination); | ||
| 3001 | return @enumFromInt(destination_i64 - base_i64); | ||
| 3002 | } | ||
| 3003 | }; | ||
| 3004 | |||
| 3005 | /// Index into `nodes`, or null. | ||
| 3006 | pub const OptionalIndex = enum(u32) { | ||
| 3007 | root = 0, | ||
| 3008 | none = std.math.maxInt(u32), | ||
| 3009 | _, | ||
| 3010 | |||
| 3011 | pub fn unwrap(oi: OptionalIndex) ?Index { | ||
| 3012 | return if (oi == .none) null else @enumFromInt(@intFromEnum(oi)); | ||
| 3013 | } | ||
| 3014 | |||
| 3015 | pub fn fromOptional(oi: ?Index) OptionalIndex { | ||
| 3016 | return if (oi) |i| i.toOptional() else .none; | ||
| 3017 | } | ||
| 3018 | }; | ||
| 3019 | |||
| 3020 | /// A relative node index. | ||
| 3021 | pub const Offset = enum(i32) { | ||
| 3022 | zero = 0, | ||
| 3023 | _, | ||
| 3024 | |||
| 3025 | pub fn toOptional(o: Offset) OptionalOffset { | ||
| 3026 | const result: OptionalOffset = @enumFromInt(@intFromEnum(o)); | ||
| 3027 | assert(result != .none); | ||
| 3028 | return result; | ||
| 3029 | } | ||
| 3030 | |||
| 3031 | pub fn toAbsolute(offset: Offset, base: Index) Index { | ||
| 3032 | return @enumFromInt(@as(i64, @intFromEnum(base)) + @intFromEnum(offset)); | ||
| 3033 | } | ||
| 3034 | }; | ||
| 3035 | |||
| 3036 | /// A relative node index, or null. | ||
| 3037 | pub const OptionalOffset = enum(i32) { | ||
| 3038 | none = std.math.maxInt(i32), | ||
| 3039 | _, | ||
| 3040 | |||
| 3041 | pub fn unwrap(oo: OptionalOffset) ?Offset { | ||
| 3042 | return if (oo == .none) null else @enumFromInt(@intFromEnum(oo)); | ||
| 3043 | } | ||
| 3044 | }; | ||
| 2944 | 3045 | ||
| 2945 | comptime { | 3046 | comptime { |
| 2946 | // Goal is to keep this under one byte for efficiency. | 3047 | // Goal is to keep this under one byte for efficiency. |
| 2947 | assert(@sizeOf(Tag) == 1); | 3048 | assert(@sizeOf(Tag) == 1); |
| 3049 | |||
| 3050 | if (!std.debug.runtime_safety) { | ||
| 3051 | assert(@sizeOf(Data) == 8); | ||
| 3052 | } | ||
| 2948 | } | 3053 | } |
| 2949 | 3054 | ||
| 2950 | /// Note: The FooComma/FooSemicolon variants exist to ease the implementation of | 3055 | /// Note: The FooComma/FooSemicolon variants exist to ease the implementation of |
| ... | @@ -3435,9 +3540,26 @@ pub const Node = struct { | ... | @@ -3435,9 +3540,26 @@ pub const Node = struct { |
| 3435 | } | 3540 | } |
| 3436 | }; | 3541 | }; |
| 3437 | 3542 | ||
| 3438 | pub const Data = struct { | 3543 | pub const Data = union { |
| 3439 | lhs: Index, | 3544 | node: Index, |
| 3440 | rhs: Index, | 3545 | opt_node: OptionalIndex, |
| 3546 | token: TokenIndex, | ||
| 3547 | node_and_node: struct { Index, Index }, | ||
| 3548 | opt_node_and_opt_node: struct { OptionalIndex, OptionalIndex }, | ||
| 3549 | node_and_opt_node: struct { Index, OptionalIndex }, | ||
| 3550 | opt_node_and_node: struct { OptionalIndex, Index }, | ||
| 3551 | node_and_extra: struct { Index, ExtraIndex }, | ||
| 3552 | extra_and_node: struct { ExtraIndex, Index }, | ||
| 3553 | extra_and_opt_node: struct { ExtraIndex, OptionalIndex }, | ||
| 3554 | node_and_token: struct { Index, TokenIndex }, | ||
| 3555 | token_and_node: struct { TokenIndex, Index }, | ||
| 3556 | token_and_token: struct { TokenIndex, TokenIndex }, | ||
| 3557 | opt_node_and_token: struct { OptionalIndex, TokenIndex }, | ||
| 3558 | opt_token_and_node: struct { OptionalTokenIndex, Index }, | ||
| 3559 | opt_token_and_opt_node: struct { OptionalTokenIndex, OptionalIndex }, | ||
| 3560 | opt_token_and_opt_token: struct { OptionalTokenIndex, OptionalTokenIndex }, | ||
| 3561 | @"for": struct { ExtraIndex, For }, | ||
| 3562 | extra_range: SubRange, | ||
| 3441 | }; | 3563 | }; |
| 3442 | 3564 | ||
| 3443 | pub const LocalVarDecl = struct { | 3565 | pub const LocalVarDecl = struct { |
| ... | @@ -3451,24 +3573,24 @@ pub const Node = struct { | ... | @@ -3451,24 +3573,24 @@ pub const Node = struct { |
| 3451 | }; | 3573 | }; |
| 3452 | 3574 | ||
| 3453 | pub const PtrType = struct { | 3575 | pub const PtrType = struct { |
| 3454 | sentinel: Index, | 3576 | sentinel: OptionalIndex, |
| 3455 | align_node: Index, | 3577 | align_node: OptionalIndex, |
| 3456 | addrspace_node: Index, | 3578 | addrspace_node: OptionalIndex, |
| 3457 | }; | 3579 | }; |
| 3458 | 3580 | ||
| 3459 | pub const PtrTypeBitRange = struct { | 3581 | pub const PtrTypeBitRange = struct { |
| 3460 | sentinel: Index, | 3582 | sentinel: OptionalIndex, |
| 3461 | align_node: Index, | 3583 | align_node: Index, |
| 3462 | addrspace_node: Index, | 3584 | addrspace_node: OptionalIndex, |
| 3463 | bit_range_start: Index, | 3585 | bit_range_start: Index, |
| 3464 | bit_range_end: Index, | 3586 | bit_range_end: Index, |
| 3465 | }; | 3587 | }; |
| 3466 | 3588 | ||
| 3467 | pub const SubRange = struct { | 3589 | pub const SubRange = struct { |
| 3468 | /// Index into sub_list. | 3590 | /// Index into extra_data. |
| 3469 | start: Index, | 3591 | start: ExtraIndex, |
| 3470 | /// Index into sub_list. | 3592 | /// Index into extra_data. |
| 3471 | end: Index, | 3593 | end: ExtraIndex, |
| 3472 | }; | 3594 | }; |
| 3473 | 3595 | ||
| 3474 | pub const If = struct { | 3596 | pub const If = struct { |
| ... | @@ -3483,13 +3605,13 @@ pub const Node = struct { | ... | @@ -3483,13 +3605,13 @@ pub const Node = struct { |
| 3483 | 3605 | ||
| 3484 | pub const GlobalVarDecl = struct { | 3606 | pub const GlobalVarDecl = struct { |
| 3485 | /// Populated if there is an explicit type ascription. | 3607 | /// Populated if there is an explicit type ascription. |
| 3486 | type_node: Index, | 3608 | type_node: OptionalIndex, |
| 3487 | /// Populated if align(A) is present. | 3609 | /// Populated if align(A) is present. |
| 3488 | align_node: Index, | 3610 | align_node: OptionalIndex, |
| 3489 | /// Populated if addrspace(A) is present. | 3611 | /// Populated if addrspace(A) is present. |
| 3490 | addrspace_node: Index, | 3612 | addrspace_node: OptionalIndex, |
| 3491 | /// Populated if linksection(A) is present. | 3613 | /// Populated if linksection(A) is present. |
| 3492 | section_node: Index, | 3614 | section_node: OptionalIndex, |
| 3493 | }; | 3615 | }; |
| 3494 | 3616 | ||
| 3495 | pub const Slice = struct { | 3617 | pub const Slice = struct { |
| ... | @@ -3499,13 +3621,13 @@ pub const Node = struct { | ... | @@ -3499,13 +3621,13 @@ pub const Node = struct { |
| 3499 | 3621 | ||
| 3500 | pub const SliceSentinel = struct { | 3622 | pub const SliceSentinel = struct { |
| 3501 | start: Index, | 3623 | start: Index, |
| 3502 | /// May be 0 if the slice is "open" | 3624 | /// May be .none if the slice is "open" |
| 3503 | end: Index, | 3625 | end: OptionalIndex, |
| 3504 | sentinel: Index, | 3626 | sentinel: Index, |
| 3505 | }; | 3627 | }; |
| 3506 | 3628 | ||
| 3507 | pub const While = struct { | 3629 | pub const While = struct { |
| 3508 | cont_expr: Index, | 3630 | cont_expr: OptionalIndex, |
| 3509 | then_expr: Index, | 3631 | then_expr: Index, |
| 3510 | else_expr: Index, | 3632 | else_expr: Index, |
| 3511 | }; | 3633 | }; |
| ... | @@ -3522,44 +3644,44 @@ pub const Node = struct { | ... | @@ -3522,44 +3644,44 @@ pub const Node = struct { |
| 3522 | 3644 | ||
| 3523 | pub const FnProtoOne = struct { | 3645 | pub const FnProtoOne = struct { |
| 3524 | /// Populated if there is exactly 1 parameter. Otherwise there are 0 parameters. | 3646 | /// Populated if there is exactly 1 parameter. Otherwise there are 0 parameters. |
| 3525 | param: Index, | 3647 | param: OptionalIndex, |
| 3526 | /// Populated if align(A) is present. | 3648 | /// Populated if align(A) is present. |
| 3527 | align_expr: Index, | 3649 | align_expr: OptionalIndex, |
| 3528 | /// Populated if addrspace(A) is present. | 3650 | /// Populated if addrspace(A) is present. |
| 3529 | addrspace_expr: Index, | 3651 | addrspace_expr: OptionalIndex, |
| 3530 | /// Populated if linksection(A) is present. | 3652 | /// Populated if linksection(A) is present. |
| 3531 | section_expr: Index, | 3653 | section_expr: OptionalIndex, |
| 3532 | /// Populated if callconv(A) is present. | 3654 | /// Populated if callconv(A) is present. |
| 3533 | callconv_expr: Index, | 3655 | callconv_expr: OptionalIndex, |
| 3534 | }; | 3656 | }; |
| 3535 | 3657 | ||
| 3536 | pub const FnProto = struct { | 3658 | pub const FnProto = struct { |
| 3537 | params_start: Index, | 3659 | params_start: ExtraIndex, |
| 3538 | params_end: Index, | 3660 | params_end: ExtraIndex, |
| 3539 | /// Populated if align(A) is present. | 3661 | /// Populated if align(A) is present. |
| 3540 | align_expr: Index, | 3662 | align_expr: OptionalIndex, |
| 3541 | /// Populated if addrspace(A) is present. | 3663 | /// Populated if addrspace(A) is present. |
| 3542 | addrspace_expr: Index, | 3664 | addrspace_expr: OptionalIndex, |
| 3543 | /// Populated if linksection(A) is present. | 3665 | /// Populated if linksection(A) is present. |
| 3544 | section_expr: Index, | 3666 | section_expr: OptionalIndex, |
| 3545 | /// Populated if callconv(A) is present. | 3667 | /// Populated if callconv(A) is present. |
| 3546 | callconv_expr: Index, | 3668 | callconv_expr: OptionalIndex, |
| 3547 | }; | 3669 | }; |
| 3548 | 3670 | ||
| 3549 | pub const Asm = struct { | 3671 | pub const Asm = struct { |
| 3550 | items_start: Index, | 3672 | items_start: ExtraIndex, |
| 3551 | items_end: Index, | 3673 | items_end: ExtraIndex, |
| 3552 | /// Needed to make lastToken() work. | 3674 | /// Needed to make lastToken() work. |
| 3553 | rparen: TokenIndex, | 3675 | rparen: TokenIndex, |
| 3554 | }; | 3676 | }; |
| 3555 | }; | 3677 | }; |
| 3556 | 3678 | ||
| 3557 | pub fn nodeToSpan(tree: *const Ast, node: u32) Span { | 3679 | pub fn nodeToSpan(tree: *const Ast, node: Ast.Node.Index) Span { |
| 3558 | return tokensToSpan( | 3680 | return tokensToSpan( |
| 3559 | tree, | 3681 | tree, |
| 3560 | tree.firstToken(node), | 3682 | tree.firstToken(node), |
| 3561 | tree.lastToken(node), | 3683 | tree.lastToken(node), |
| 3562 | tree.nodes.items(.main_token)[node], | 3684 | tree.nodeMainToken(node), |
| 3563 | ); | 3685 | ); |
| 3564 | } | 3686 | } |
| 3565 | 3687 | ||
| ... | @@ -3568,7 +3690,6 @@ pub fn tokenToSpan(tree: *const Ast, token: Ast.TokenIndex) Span { | ... | @@ -3568,7 +3690,6 @@ pub fn tokenToSpan(tree: *const Ast, token: Ast.TokenIndex) Span { |
| 3568 | } | 3690 | } |
| 3569 | 3691 | ||
| 3570 | pub fn tokensToSpan(tree: *const Ast, start: Ast.TokenIndex, end: Ast.TokenIndex, main: Ast.TokenIndex) Span { | 3692 | pub fn tokensToSpan(tree: *const Ast, start: Ast.TokenIndex, end: Ast.TokenIndex, main: Ast.TokenIndex) Span { |
| 3571 | const token_starts = tree.tokens.items(.start); | ||
| 3572 | var start_tok = start; | 3693 | var start_tok = start; |
| 3573 | var end_tok = end; | 3694 | var end_tok = end; |
| 3574 | 3695 | ||
| ... | @@ -3582,9 +3703,9 @@ pub fn tokensToSpan(tree: *const Ast, start: Ast.TokenIndex, end: Ast.TokenIndex | ... | @@ -3582,9 +3703,9 @@ pub fn tokensToSpan(tree: *const Ast, start: Ast.TokenIndex, end: Ast.TokenIndex |
| 3582 | start_tok = main; | 3703 | start_tok = main; |
| 3583 | end_tok = main; | 3704 | end_tok = main; |
| 3584 | } | 3705 | } |
| 3585 | const start_off = token_starts[start_tok]; | 3706 | const start_off = tree.tokenStart(start_tok); |
| 3586 | const end_off = token_starts[end_tok] + @as(u32, @intCast(tree.tokenSlice(end_tok).len)); | 3707 | const end_off = tree.tokenStart(end_tok) + @as(u32, @intCast(tree.tokenSlice(end_tok).len)); |
| 3587 | return Span{ .start = start_off, .end = end_off, .main = token_starts[main] }; | 3708 | return Span{ .start = start_off, .end = end_off, .main = tree.tokenStart(main) }; |
| 3588 | } | 3709 | } |
| 3589 | 3710 | ||
| 3590 | const std = @import("../std.zig"); | 3711 | const std = @import("../std.zig"); |
lib/std/zig/AstGen.zig+612-743| ... | @@ -99,8 +99,18 @@ fn setExtra(astgen: *AstGen, index: usize, extra: anytype) void { | ... | @@ -99,8 +99,18 @@ fn setExtra(astgen: *AstGen, index: usize, extra: anytype) void { |
| 99 | Zir.Inst.Declaration.Name, | 99 | Zir.Inst.Declaration.Name, |
| 100 | std.zig.SimpleComptimeReason, | 100 | std.zig.SimpleComptimeReason, |
| 101 | Zir.NullTerminatedString, | 101 | Zir.NullTerminatedString, |
| 102 | // Ast.TokenIndex is missing because it is a u32. | ||
| 103 | Ast.OptionalTokenIndex, | ||
| 104 | Ast.Node.Index, | ||
| 105 | Ast.Node.OptionalIndex, | ||
| 102 | => @intFromEnum(@field(extra, field.name)), | 106 | => @intFromEnum(@field(extra, field.name)), |
| 103 | 107 | ||
| 108 | Ast.TokenOffset, | ||
| 109 | Ast.OptionalTokenOffset, | ||
| 110 | Ast.Node.Offset, | ||
| 111 | Ast.Node.OptionalOffset, | ||
| 112 | => @bitCast(@intFromEnum(@field(extra, field.name))), | ||
| 113 | |||
| 104 | i32, | 114 | i32, |
| 105 | Zir.Inst.Call.Flags, | 115 | Zir.Inst.Call.Flags, |
| 106 | Zir.Inst.BuiltinCall.Flags, | 116 | Zir.Inst.BuiltinCall.Flags, |
| ... | @@ -168,7 +178,7 @@ pub fn generate(gpa: Allocator, tree: Ast) Allocator.Error!Zir { | ... | @@ -168,7 +178,7 @@ pub fn generate(gpa: Allocator, tree: Ast) Allocator.Error!Zir { |
| 168 | .is_comptime = true, | 178 | .is_comptime = true, |
| 169 | .parent = &top_scope.base, | 179 | .parent = &top_scope.base, |
| 170 | .anon_name_strategy = .parent, | 180 | .anon_name_strategy = .parent, |
| 171 | .decl_node_index = 0, | 181 | .decl_node_index = .root, |
| 172 | .decl_line = 0, | 182 | .decl_line = 0, |
| 173 | .astgen = &astgen, | 183 | .astgen = &astgen, |
| 174 | .instructions = &gz_instructions, | 184 | .instructions = &gz_instructions, |
| ... | @@ -182,10 +192,10 @@ pub fn generate(gpa: Allocator, tree: Ast) Allocator.Error!Zir { | ... | @@ -182,10 +192,10 @@ pub fn generate(gpa: Allocator, tree: Ast) Allocator.Error!Zir { |
| 182 | if (AstGen.structDeclInner( | 192 | if (AstGen.structDeclInner( |
| 183 | &gen_scope, | 193 | &gen_scope, |
| 184 | &gen_scope.base, | 194 | &gen_scope.base, |
| 185 | 0, | 195 | .root, |
| 186 | tree.containerDeclRoot(), | 196 | tree.containerDeclRoot(), |
| 187 | .auto, | 197 | .auto, |
| 188 | 0, | 198 | .none, |
| 189 | )) |struct_decl_ref| { | 199 | )) |struct_decl_ref| { |
| 190 | assert(struct_decl_ref.toIndex().? == .main_struct_inst); | 200 | assert(struct_decl_ref.toIndex().? == .main_struct_inst); |
| 191 | break :fatal false; | 201 | break :fatal false; |
| ... | @@ -430,9 +440,7 @@ fn reachableExprComptime( | ... | @@ -430,9 +440,7 @@ fn reachableExprComptime( |
| 430 | fn lvalExpr(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { | 440 | fn lvalExpr(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 431 | const astgen = gz.astgen; | 441 | const astgen = gz.astgen; |
| 432 | const tree = astgen.tree; | 442 | const tree = astgen.tree; |
| 433 | const node_tags = tree.nodes.items(.tag); | 443 | switch (tree.nodeTag(node)) { |
| 434 | const main_tokens = tree.nodes.items(.main_token); | ||
| 435 | switch (node_tags[node]) { | ||
| 436 | .root => unreachable, | 444 | .root => unreachable, |
| 437 | .@"usingnamespace" => unreachable, | 445 | .@"usingnamespace" => unreachable, |
| 438 | .test_decl => unreachable, | 446 | .test_decl => unreachable, |
| ... | @@ -600,7 +608,7 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Ins | ... | @@ -600,7 +608,7 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Ins |
| 600 | .builtin_call_two, | 608 | .builtin_call_two, |
| 601 | .builtin_call_two_comma, | 609 | .builtin_call_two_comma, |
| 602 | => { | 610 | => { |
| 603 | const builtin_token = main_tokens[node]; | 611 | const builtin_token = tree.nodeMainToken(node); |
| 604 | const builtin_name = tree.tokenSlice(builtin_token); | 612 | const builtin_name = tree.tokenSlice(builtin_token); |
| 605 | // If the builtin is an invalid name, we don't cause an error here; instead | 613 | // If the builtin is an invalid name, we don't cause an error here; instead |
| 606 | // let it pass, and the error will be "invalid builtin function" later. | 614 | // let it pass, and the error will be "invalid builtin function" later. |
| ... | @@ -631,10 +639,6 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Ins | ... | @@ -631,10 +639,6 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Ins |
| 631 | fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { | 639 | fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 632 | const astgen = gz.astgen; | 640 | const astgen = gz.astgen; |
| 633 | const tree = astgen.tree; | 641 | const tree = astgen.tree; |
| 634 | const main_tokens = tree.nodes.items(.main_token); | ||
| 635 | const token_tags = tree.tokens.items(.tag); | ||
| 636 | const node_datas = tree.nodes.items(.data); | ||
| 637 | const node_tags = tree.nodes.items(.tag); | ||
| 638 | 642 | ||
| 639 | const prev_anon_name_strategy = gz.anon_name_strategy; | 643 | const prev_anon_name_strategy = gz.anon_name_strategy; |
| 640 | defer gz.anon_name_strategy = prev_anon_name_strategy; | 644 | defer gz.anon_name_strategy = prev_anon_name_strategy; |
| ... | @@ -642,7 +646,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -642,7 +646,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 642 | gz.anon_name_strategy = .anon; | 646 | gz.anon_name_strategy = .anon; |
| 643 | } | 647 | } |
| 644 | 648 | ||
| 645 | switch (node_tags[node]) { | 649 | switch (tree.nodeTag(node)) { |
| 646 | .root => unreachable, // Top-level declaration. | 650 | .root => unreachable, // Top-level declaration. |
| 647 | .@"usingnamespace" => unreachable, // Top-level declaration. | 651 | .@"usingnamespace" => unreachable, // Top-level declaration. |
| 648 | .test_decl => unreachable, // Top-level declaration. | 652 | .test_decl => unreachable, // Top-level declaration. |
| ... | @@ -752,8 +756,8 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -752,8 +756,8 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 752 | }, | 756 | }, |
| 753 | 757 | ||
| 754 | // zig fmt: off | 758 | // zig fmt: off |
| 755 | .shl => return shiftOp(gz, scope, ri, node, node_datas[node].lhs, node_datas[node].rhs, .shl), | 759 | .shl => return shiftOp(gz, scope, ri, node, tree.nodeData(node).node_and_node[0], tree.nodeData(node).node_and_node[1], .shl), |
| 756 | .shr => return shiftOp(gz, scope, ri, node, node_datas[node].lhs, node_datas[node].rhs, .shr), | 760 | .shr => return shiftOp(gz, scope, ri, node, tree.nodeData(node).node_and_node[0], tree.nodeData(node).node_and_node[1], .shr), |
| 757 | 761 | ||
| 758 | .add => return simpleBinOp(gz, scope, ri, node, .add), | 762 | .add => return simpleBinOp(gz, scope, ri, node, .add), |
| 759 | .add_wrap => return simpleBinOp(gz, scope, ri, node, .addwrap), | 763 | .add_wrap => return simpleBinOp(gz, scope, ri, node, .addwrap), |
| ... | @@ -783,10 +787,11 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -783,10 +787,11 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 783 | // This syntax form does not currently use the result type in the language specification. | 787 | // This syntax form does not currently use the result type in the language specification. |
| 784 | // However, the result type can be used to emit more optimal code for large multiplications by | 788 | // However, the result type can be used to emit more optimal code for large multiplications by |
| 785 | // having Sema perform a coercion before the multiplication operation. | 789 | // having Sema perform a coercion before the multiplication operation. |
| 790 | const lhs_node, const rhs_node = tree.nodeData(node).node_and_node; | ||
| 786 | const result = try gz.addPlNode(.array_mul, node, Zir.Inst.ArrayMul{ | 791 | const result = try gz.addPlNode(.array_mul, node, Zir.Inst.ArrayMul{ |
| 787 | .res_ty = if (try ri.rl.resultType(gz, node)) |t| t else .none, | 792 | .res_ty = if (try ri.rl.resultType(gz, node)) |t| t else .none, |
| 788 | .lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs), | 793 | .lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node), |
| 789 | .rhs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[node].rhs, .array_mul_factor), | 794 | .rhs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, rhs_node, .array_mul_factor), |
| 790 | }); | 795 | }); |
| 791 | return rvalue(gz, ri, result, node); | 796 | return rvalue(gz, ri, result, node); |
| 792 | }, | 797 | }, |
| ... | @@ -797,8 +802,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -797,8 +802,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 797 | .merge_error_sets => .merge_error_sets, | 802 | .merge_error_sets => .merge_error_sets, |
| 798 | else => unreachable, | 803 | else => unreachable, |
| 799 | }; | 804 | }; |
| 800 | const lhs = try reachableTypeExpr(gz, scope, node_datas[node].lhs, node); | 805 | const lhs_node, const rhs_node = tree.nodeData(node).node_and_node; |
| 801 | const rhs = try reachableTypeExpr(gz, scope, node_datas[node].rhs, node); | 806 | const lhs = try reachableTypeExpr(gz, scope, lhs_node, node); |
| 807 | const rhs = try reachableTypeExpr(gz, scope, rhs_node, node); | ||
| 802 | const result = try gz.addPlNode(inst_tag, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }); | 808 | const result = try gz.addPlNode(inst_tag, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }); |
| 803 | return rvalue(gz, ri, result, node); | 809 | return rvalue(gz, ri, result, node); |
| 804 | }, | 810 | }, |
| ... | @@ -806,11 +812,11 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -806,11 +812,11 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 806 | .bool_and => return boolBinOp(gz, scope, ri, node, .bool_br_and), | 812 | .bool_and => return boolBinOp(gz, scope, ri, node, .bool_br_and), |
| 807 | .bool_or => return boolBinOp(gz, scope, ri, node, .bool_br_or), | 813 | .bool_or => return boolBinOp(gz, scope, ri, node, .bool_br_or), |
| 808 | 814 | ||
| 809 | .bool_not => return simpleUnOp(gz, scope, ri, node, coerced_bool_ri, node_datas[node].lhs, .bool_not), | 815 | .bool_not => return simpleUnOp(gz, scope, ri, node, coerced_bool_ri, tree.nodeData(node).node, .bool_not), |
| 810 | .bit_not => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, node_datas[node].lhs, .bit_not), | 816 | .bit_not => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, tree.nodeData(node).node, .bit_not), |
| 811 | 817 | ||
| 812 | .negation => return negation(gz, scope, ri, node), | 818 | .negation => return negation(gz, scope, ri, node), |
| 813 | .negation_wrap => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, node_datas[node].lhs, .negate_wrap), | 819 | .negation_wrap => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, tree.nodeData(node).node, .negate_wrap), |
| 814 | 820 | ||
| 815 | .identifier => return identifier(gz, scope, ri, node, null), | 821 | .identifier => return identifier(gz, scope, ri, node, null), |
| 816 | 822 | ||
| ... | @@ -866,10 +872,11 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -866,10 +872,11 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 866 | const if_full = tree.fullIf(node).?; | 872 | const if_full = tree.fullIf(node).?; |
| 867 | no_switch_on_err: { | 873 | no_switch_on_err: { |
| 868 | const error_token = if_full.error_token orelse break :no_switch_on_err; | 874 | const error_token = if_full.error_token orelse break :no_switch_on_err; |
| 869 | const full_switch = tree.fullSwitch(if_full.ast.else_expr) orelse break :no_switch_on_err; | 875 | const else_node = if_full.ast.else_expr.unwrap() orelse break :no_switch_on_err; |
| 876 | const full_switch = tree.fullSwitch(else_node) orelse break :no_switch_on_err; | ||
| 870 | if (full_switch.label_token != null) break :no_switch_on_err; | 877 | if (full_switch.label_token != null) break :no_switch_on_err; |
| 871 | if (node_tags[full_switch.ast.condition] != .identifier) break :no_switch_on_err; | 878 | if (tree.nodeTag(full_switch.ast.condition) != .identifier) break :no_switch_on_err; |
| 872 | if (!mem.eql(u8, tree.tokenSlice(error_token), tree.tokenSlice(main_tokens[full_switch.ast.condition]))) break :no_switch_on_err; | 879 | if (!mem.eql(u8, tree.tokenSlice(error_token), tree.tokenSlice(tree.nodeMainToken(full_switch.ast.condition)))) break :no_switch_on_err; |
| 873 | return switchExprErrUnion(gz, scope, ri.br(), node, .@"if"); | 880 | return switchExprErrUnion(gz, scope, ri.br(), node, .@"if"); |
| 874 | } | 881 | } |
| 875 | return ifExpr(gz, scope, ri.br(), node, if_full); | 882 | return ifExpr(gz, scope, ri.br(), node, if_full); |
| ... | @@ -887,8 +894,8 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -887,8 +894,8 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 887 | .slice_sentinel, | 894 | .slice_sentinel, |
| 888 | => { | 895 | => { |
| 889 | const full = tree.fullSlice(node).?; | 896 | const full = tree.fullSlice(node).?; |
| 890 | if (full.ast.end != 0 and | 897 | if (full.ast.end != .none and |
| 891 | node_tags[full.ast.sliced] == .slice_open and | 898 | tree.nodeTag(full.ast.sliced) == .slice_open and |
| 892 | nodeIsTriviallyZero(tree, full.ast.start)) | 899 | nodeIsTriviallyZero(tree, full.ast.start)) |
| 893 | { | 900 | { |
| 894 | const lhs_extra = tree.sliceOpen(full.ast.sliced).ast; | 901 | const lhs_extra = tree.sliceOpen(full.ast.sliced).ast; |
| ... | @@ -896,8 +903,8 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -896,8 +903,8 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 896 | const lhs = try expr(gz, scope, .{ .rl = .ref }, lhs_extra.sliced); | 903 | const lhs = try expr(gz, scope, .{ .rl = .ref }, lhs_extra.sliced); |
| 897 | const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, lhs_extra.start); | 904 | const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, lhs_extra.start); |
| 898 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | 905 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); |
| 899 | const len = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, full.ast.end); | 906 | const len = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, full.ast.end.unwrap().?); |
| 900 | const sentinel = if (full.ast.sentinel != 0) try expr(gz, scope, .{ .rl = .none }, full.ast.sentinel) else .none; | 907 | const sentinel = if (full.ast.sentinel.unwrap()) |sentinel| try expr(gz, scope, .{ .rl = .none }, sentinel) else .none; |
| 901 | try emitDbgStmt(gz, cursor); | 908 | try emitDbgStmt(gz, cursor); |
| 902 | const result = try gz.addPlNode(.slice_length, node, Zir.Inst.SliceLength{ | 909 | const result = try gz.addPlNode(.slice_length, node, Zir.Inst.SliceLength{ |
| 903 | .lhs = lhs, | 910 | .lhs = lhs, |
| ... | @@ -912,10 +919,10 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -912,10 +919,10 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 912 | 919 | ||
| 913 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | 920 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); |
| 914 | const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, full.ast.start); | 921 | const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, full.ast.start); |
| 915 | const end = if (full.ast.end != 0) try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, full.ast.end) else .none; | 922 | const end = if (full.ast.end.unwrap()) |end| try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, end) else .none; |
| 916 | const sentinel = if (full.ast.sentinel != 0) s: { | 923 | const sentinel = if (full.ast.sentinel.unwrap()) |sentinel| s: { |
| 917 | const sentinel_ty = try gz.addUnNode(.slice_sentinel_ty, lhs, node); | 924 | const sentinel_ty = try gz.addUnNode(.slice_sentinel_ty, lhs, node); |
| 918 | break :s try expr(gz, scope, .{ .rl = .{ .coerced_ty = sentinel_ty } }, full.ast.sentinel); | 925 | break :s try expr(gz, scope, .{ .rl = .{ .coerced_ty = sentinel_ty } }, sentinel); |
| 919 | } else .none; | 926 | } else .none; |
| 920 | try emitDbgStmt(gz, cursor); | 927 | try emitDbgStmt(gz, cursor); |
| 921 | if (sentinel != .none) { | 928 | if (sentinel != .none) { |
| ... | @@ -943,7 +950,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -943,7 +950,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 943 | }, | 950 | }, |
| 944 | 951 | ||
| 945 | .deref => { | 952 | .deref => { |
| 946 | const lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs); | 953 | const lhs = try expr(gz, scope, .{ .rl = .none }, tree.nodeData(node).node); |
| 947 | _ = try gz.addUnNode(.validate_deref, lhs, node); | 954 | _ = try gz.addUnNode(.validate_deref, lhs, node); |
| 948 | switch (ri.rl) { | 955 | switch (ri.rl) { |
| 949 | .ref, .ref_coerced_ty => return lhs, | 956 | .ref, .ref_coerced_ty => return lhs, |
| ... | @@ -958,17 +965,17 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -958,17 +965,17 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 958 | _ = try gz.addUnTok(.validate_ref_ty, res_ty_inst, tree.firstToken(node)); | 965 | _ = try gz.addUnTok(.validate_ref_ty, res_ty_inst, tree.firstToken(node)); |
| 959 | break :rl .{ .ref_coerced_ty = res_ty_inst }; | 966 | break :rl .{ .ref_coerced_ty = res_ty_inst }; |
| 960 | } else .ref; | 967 | } else .ref; |
| 961 | const result = try expr(gz, scope, .{ .rl = operand_rl }, node_datas[node].lhs); | 968 | const result = try expr(gz, scope, .{ .rl = operand_rl }, tree.nodeData(node).node); |
| 962 | return rvalue(gz, ri, result, node); | 969 | return rvalue(gz, ri, result, node); |
| 963 | }, | 970 | }, |
| 964 | .optional_type => { | 971 | .optional_type => { |
| 965 | const operand = try typeExpr(gz, scope, node_datas[node].lhs); | 972 | const operand = try typeExpr(gz, scope, tree.nodeData(node).node); |
| 966 | const result = try gz.addUnNode(.optional_type, operand, node); | 973 | const result = try gz.addUnNode(.optional_type, operand, node); |
| 967 | return rvalue(gz, ri, result, node); | 974 | return rvalue(gz, ri, result, node); |
| 968 | }, | 975 | }, |
| 969 | .unwrap_optional => switch (ri.rl) { | 976 | .unwrap_optional => switch (ri.rl) { |
| 970 | .ref, .ref_coerced_ty => { | 977 | .ref, .ref_coerced_ty => { |
| 971 | const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs); | 978 | const lhs = try expr(gz, scope, .{ .rl = .ref }, tree.nodeData(node).node_and_token[0]); |
| 972 | 979 | ||
| 973 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | 980 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); |
| 974 | try emitDbgStmt(gz, cursor); | 981 | try emitDbgStmt(gz, cursor); |
| ... | @@ -976,7 +983,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -976,7 +983,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 976 | return gz.addUnNode(.optional_payload_safe_ptr, lhs, node); | 983 | return gz.addUnNode(.optional_payload_safe_ptr, lhs, node); |
| 977 | }, | 984 | }, |
| 978 | else => { | 985 | else => { |
| 979 | const lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs); | 986 | const lhs = try expr(gz, scope, .{ .rl = .none }, tree.nodeData(node).node_and_token[0]); |
| 980 | 987 | ||
| 981 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | 988 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); |
| 982 | try emitDbgStmt(gz, cursor); | 989 | try emitDbgStmt(gz, cursor); |
| ... | @@ -994,7 +1001,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -994,7 +1001,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 994 | return blockExpr(gz, scope, ri, node, statements, .normal); | 1001 | return blockExpr(gz, scope, ri, node, statements, .normal); |
| 995 | }, | 1002 | }, |
| 996 | .enum_literal => if (try ri.rl.resultType(gz, node)) |res_ty| { | 1003 | .enum_literal => if (try ri.rl.resultType(gz, node)) |res_ty| { |
| 997 | const str_index = try astgen.identAsString(main_tokens[node]); | 1004 | const str_index = try astgen.identAsString(tree.nodeMainToken(node)); |
| 998 | const res = try gz.addPlNode(.decl_literal, node, Zir.Inst.Field{ | 1005 | const res = try gz.addPlNode(.decl_literal, node, Zir.Inst.Field{ |
| 999 | .lhs = res_ty, | 1006 | .lhs = res_ty, |
| 1000 | .field_name_start = str_index, | 1007 | .field_name_start = str_index, |
| ... | @@ -1004,8 +1011,8 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -1004,8 +1011,8 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 1004 | .ty, .coerced_ty => return res, // `decl_literal` does the coercion for us | 1011 | .ty, .coerced_ty => return res, // `decl_literal` does the coercion for us |
| 1005 | .ref_coerced_ty, .ptr, .inferred_ptr, .destructure => return rvalue(gz, ri, res, node), | 1012 | .ref_coerced_ty, .ptr, .inferred_ptr, .destructure => return rvalue(gz, ri, res, node), |
| 1006 | } | 1013 | } |
| 1007 | } else return simpleStrTok(gz, ri, main_tokens[node], node, .enum_literal), | 1014 | } else return simpleStrTok(gz, ri, tree.nodeMainToken(node), node, .enum_literal), |
| 1008 | .error_value => return simpleStrTok(gz, ri, node_datas[node].rhs, node, .error_value), | 1015 | .error_value => return simpleStrTok(gz, ri, tree.nodeData(node).opt_token_and_opt_token[1].unwrap().?, node, .error_value), |
| 1009 | // TODO restore this when implementing https://github.com/ziglang/zig/issues/6025 | 1016 | // TODO restore this when implementing https://github.com/ziglang/zig/issues/6025 |
| 1010 | // .anyframe_literal => return rvalue(gz, ri, .anyframe_type, node), | 1017 | // .anyframe_literal => return rvalue(gz, ri, .anyframe_type, node), |
| 1011 | .anyframe_literal => { | 1018 | .anyframe_literal => { |
| ... | @@ -1013,22 +1020,22 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -1013,22 +1020,22 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 1013 | return rvalue(gz, ri, result, node); | 1020 | return rvalue(gz, ri, result, node); |
| 1014 | }, | 1021 | }, |
| 1015 | .anyframe_type => { | 1022 | .anyframe_type => { |
| 1016 | const return_type = try typeExpr(gz, scope, node_datas[node].rhs); | 1023 | const return_type = try typeExpr(gz, scope, tree.nodeData(node).token_and_node[1]); |
| 1017 | const result = try gz.addUnNode(.anyframe_type, return_type, node); | 1024 | const result = try gz.addUnNode(.anyframe_type, return_type, node); |
| 1018 | return rvalue(gz, ri, result, node); | 1025 | return rvalue(gz, ri, result, node); |
| 1019 | }, | 1026 | }, |
| 1020 | .@"catch" => { | 1027 | .@"catch" => { |
| 1021 | const catch_token = main_tokens[node]; | 1028 | const catch_token = tree.nodeMainToken(node); |
| 1022 | const payload_token: ?Ast.TokenIndex = if (token_tags[catch_token + 1] == .pipe) | 1029 | const payload_token: ?Ast.TokenIndex = if (tree.tokenTag(catch_token + 1) == .pipe) |
| 1023 | catch_token + 2 | 1030 | catch_token + 2 |
| 1024 | else | 1031 | else |
| 1025 | null; | 1032 | null; |
| 1026 | no_switch_on_err: { | 1033 | no_switch_on_err: { |
| 1027 | const capture_token = payload_token orelse break :no_switch_on_err; | 1034 | const capture_token = payload_token orelse break :no_switch_on_err; |
| 1028 | const full_switch = tree.fullSwitch(node_datas[node].rhs) orelse break :no_switch_on_err; | 1035 | const full_switch = tree.fullSwitch(tree.nodeData(node).node_and_node[1]) orelse break :no_switch_on_err; |
| 1029 | if (full_switch.label_token != null) break :no_switch_on_err; | 1036 | if (full_switch.label_token != null) break :no_switch_on_err; |
| 1030 | if (node_tags[full_switch.ast.condition] != .identifier) break :no_switch_on_err; | 1037 | if (tree.nodeTag(full_switch.ast.condition) != .identifier) break :no_switch_on_err; |
| 1031 | if (!mem.eql(u8, tree.tokenSlice(capture_token), tree.tokenSlice(main_tokens[full_switch.ast.condition]))) break :no_switch_on_err; | 1038 | if (!mem.eql(u8, tree.tokenSlice(capture_token), tree.tokenSlice(tree.nodeMainToken(full_switch.ast.condition)))) break :no_switch_on_err; |
| 1032 | return switchExprErrUnion(gz, scope, ri.br(), node, .@"catch"); | 1039 | return switchExprErrUnion(gz, scope, ri.br(), node, .@"catch"); |
| 1033 | } | 1040 | } |
| 1034 | switch (ri.rl) { | 1041 | switch (ri.rl) { |
| ... | @@ -1037,11 +1044,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -1037,11 +1044,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 1037 | scope, | 1044 | scope, |
| 1038 | ri, | 1045 | ri, |
| 1039 | node, | 1046 | node, |
| 1040 | node_datas[node].lhs, | ||
| 1041 | .is_non_err_ptr, | 1047 | .is_non_err_ptr, |
| 1042 | .err_union_payload_unsafe_ptr, | 1048 | .err_union_payload_unsafe_ptr, |
| 1043 | .err_union_code_ptr, | 1049 | .err_union_code_ptr, |
| 1044 | node_datas[node].rhs, | ||
| 1045 | payload_token, | 1050 | payload_token, |
| 1046 | ), | 1051 | ), |
| 1047 | else => return orelseCatchExpr( | 1052 | else => return orelseCatchExpr( |
| ... | @@ -1049,11 +1054,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -1049,11 +1054,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 1049 | scope, | 1054 | scope, |
| 1050 | ri, | 1055 | ri, |
| 1051 | node, | 1056 | node, |
| 1052 | node_datas[node].lhs, | ||
| 1053 | .is_non_err, | 1057 | .is_non_err, |
| 1054 | .err_union_payload_unsafe, | 1058 | .err_union_payload_unsafe, |
| 1055 | .err_union_code, | 1059 | .err_union_code, |
| 1056 | node_datas[node].rhs, | ||
| 1057 | payload_token, | 1060 | payload_token, |
| 1058 | ), | 1061 | ), |
| 1059 | } | 1062 | } |
| ... | @@ -1064,11 +1067,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -1064,11 +1067,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 1064 | scope, | 1067 | scope, |
| 1065 | ri, | 1068 | ri, |
| 1066 | node, | 1069 | node, |
| 1067 | node_datas[node].lhs, | ||
| 1068 | .is_non_null_ptr, | 1070 | .is_non_null_ptr, |
| 1069 | .optional_payload_unsafe_ptr, | 1071 | .optional_payload_unsafe_ptr, |
| 1070 | undefined, | 1072 | undefined, |
| 1071 | node_datas[node].rhs, | ||
| 1072 | null, | 1073 | null, |
| 1073 | ), | 1074 | ), |
| 1074 | else => return orelseCatchExpr( | 1075 | else => return orelseCatchExpr( |
| ... | @@ -1076,11 +1077,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -1076,11 +1077,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 1076 | scope, | 1077 | scope, |
| 1077 | ri, | 1078 | ri, |
| 1078 | node, | 1079 | node, |
| 1079 | node_datas[node].lhs, | ||
| 1080 | .is_non_null, | 1080 | .is_non_null, |
| 1081 | .optional_payload_unsafe, | 1081 | .optional_payload_unsafe, |
| 1082 | undefined, | 1082 | undefined, |
| 1083 | node_datas[node].rhs, | ||
| 1084 | null, | 1083 | null, |
| 1085 | ), | 1084 | ), |
| 1086 | }, | 1085 | }, |
| ... | @@ -1110,7 +1109,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -1110,7 +1109,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 1110 | 1109 | ||
| 1111 | .@"break" => return breakExpr(gz, scope, node), | 1110 | .@"break" => return breakExpr(gz, scope, node), |
| 1112 | .@"continue" => return continueExpr(gz, scope, node), | 1111 | .@"continue" => return continueExpr(gz, scope, node), |
| 1113 | .grouped_expression => return expr(gz, scope, ri, node_datas[node].lhs), | 1112 | .grouped_expression => return expr(gz, scope, ri, tree.nodeData(node).node_and_token[0]), |
| 1114 | .array_type => return arrayType(gz, scope, ri, node), | 1113 | .array_type => return arrayType(gz, scope, ri, node), |
| 1115 | .array_type_sentinel => return arrayTypeSentinel(gz, scope, ri, node), | 1114 | .array_type_sentinel => return arrayTypeSentinel(gz, scope, ri, node), |
| 1116 | .char_literal => return charLiteral(gz, ri, node), | 1115 | .char_literal => return charLiteral(gz, ri, node), |
| ... | @@ -1124,7 +1123,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -1124,7 +1123,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 1124 | .@"await" => return awaitExpr(gz, scope, ri, node), | 1123 | .@"await" => return awaitExpr(gz, scope, ri, node), |
| 1125 | .@"resume" => return resumeExpr(gz, scope, ri, node), | 1124 | .@"resume" => return resumeExpr(gz, scope, ri, node), |
| 1126 | 1125 | ||
| 1127 | .@"try" => return tryExpr(gz, scope, ri, node, node_datas[node].lhs), | 1126 | .@"try" => return tryExpr(gz, scope, ri, node, tree.nodeData(node).node), |
| 1128 | 1127 | ||
| 1129 | .array_init_one, | 1128 | .array_init_one, |
| 1130 | .array_init_one_comma, | 1129 | .array_init_one_comma, |
| ... | @@ -1171,16 +1170,14 @@ fn nosuspendExpr( | ... | @@ -1171,16 +1170,14 @@ fn nosuspendExpr( |
| 1171 | ) InnerError!Zir.Inst.Ref { | 1170 | ) InnerError!Zir.Inst.Ref { |
| 1172 | const astgen = gz.astgen; | 1171 | const astgen = gz.astgen; |
| 1173 | const tree = astgen.tree; | 1172 | const tree = astgen.tree; |
| 1174 | const node_datas = tree.nodes.items(.data); | 1173 | const body_node = tree.nodeData(node).node; |
| 1175 | const body_node = node_datas[node].lhs; | 1174 | if (gz.nosuspend_node.unwrap()) |nosuspend_node| { |
| 1176 | assert(body_node != 0); | ||
| 1177 | if (gz.nosuspend_node != 0) { | ||
| 1178 | try astgen.appendErrorNodeNotes(node, "redundant nosuspend block", .{}, &[_]u32{ | 1175 | try astgen.appendErrorNodeNotes(node, "redundant nosuspend block", .{}, &[_]u32{ |
| 1179 | try astgen.errNoteNode(gz.nosuspend_node, "other nosuspend block here", .{}), | 1176 | try astgen.errNoteNode(nosuspend_node, "other nosuspend block here", .{}), |
| 1180 | }); | 1177 | }); |
| 1181 | } | 1178 | } |
| 1182 | gz.nosuspend_node = node; | 1179 | gz.nosuspend_node = node.toOptional(); |
| 1183 | defer gz.nosuspend_node = 0; | 1180 | defer gz.nosuspend_node = .none; |
| 1184 | return expr(gz, scope, ri, body_node); | 1181 | return expr(gz, scope, ri, body_node); |
| 1185 | } | 1182 | } |
| 1186 | 1183 | ||
| ... | @@ -1192,26 +1189,24 @@ fn suspendExpr( | ... | @@ -1192,26 +1189,24 @@ fn suspendExpr( |
| 1192 | const astgen = gz.astgen; | 1189 | const astgen = gz.astgen; |
| 1193 | const gpa = astgen.gpa; | 1190 | const gpa = astgen.gpa; |
| 1194 | const tree = astgen.tree; | 1191 | const tree = astgen.tree; |
| 1195 | const node_datas = tree.nodes.items(.data); | 1192 | const body_node = tree.nodeData(node).node; |
| 1196 | const body_node = node_datas[node].lhs; | ||
| 1197 | 1193 | ||
| 1198 | if (gz.nosuspend_node != 0) { | 1194 | if (gz.nosuspend_node.unwrap()) |nosuspend_node| { |
| 1199 | return astgen.failNodeNotes(node, "suspend inside nosuspend block", .{}, &[_]u32{ | 1195 | return astgen.failNodeNotes(node, "suspend inside nosuspend block", .{}, &[_]u32{ |
| 1200 | try astgen.errNoteNode(gz.nosuspend_node, "nosuspend block here", .{}), | 1196 | try astgen.errNoteNode(nosuspend_node, "nosuspend block here", .{}), |
| 1201 | }); | 1197 | }); |
| 1202 | } | 1198 | } |
| 1203 | if (gz.suspend_node != 0) { | 1199 | if (gz.suspend_node.unwrap()) |suspend_node| { |
| 1204 | return astgen.failNodeNotes(node, "cannot suspend inside suspend block", .{}, &[_]u32{ | 1200 | return astgen.failNodeNotes(node, "cannot suspend inside suspend block", .{}, &[_]u32{ |
| 1205 | try astgen.errNoteNode(gz.suspend_node, "other suspend block here", .{}), | 1201 | try astgen.errNoteNode(suspend_node, "other suspend block here", .{}), |
| 1206 | }); | 1202 | }); |
| 1207 | } | 1203 | } |
| 1208 | assert(body_node != 0); | ||
| 1209 | 1204 | ||
| 1210 | const suspend_inst = try gz.makeBlockInst(.suspend_block, node); | 1205 | const suspend_inst = try gz.makeBlockInst(.suspend_block, node); |
| 1211 | try gz.instructions.append(gpa, suspend_inst); | 1206 | try gz.instructions.append(gpa, suspend_inst); |
| 1212 | 1207 | ||
| 1213 | var suspend_scope = gz.makeSubBlock(scope); | 1208 | var suspend_scope = gz.makeSubBlock(scope); |
| 1214 | suspend_scope.suspend_node = node; | 1209 | suspend_scope.suspend_node = node.toOptional(); |
| 1215 | defer suspend_scope.unstack(); | 1210 | defer suspend_scope.unstack(); |
| 1216 | 1211 | ||
| 1217 | const body_result = try fullBodyExpr(&suspend_scope, &suspend_scope.base, .{ .rl = .none }, body_node, .normal); | 1212 | const body_result = try fullBodyExpr(&suspend_scope, &suspend_scope.base, .{ .rl = .none }, body_node, .normal); |
| ... | @@ -1231,16 +1226,15 @@ fn awaitExpr( | ... | @@ -1231,16 +1226,15 @@ fn awaitExpr( |
| 1231 | ) InnerError!Zir.Inst.Ref { | 1226 | ) InnerError!Zir.Inst.Ref { |
| 1232 | const astgen = gz.astgen; | 1227 | const astgen = gz.astgen; |
| 1233 | const tree = astgen.tree; | 1228 | const tree = astgen.tree; |
| 1234 | const node_datas = tree.nodes.items(.data); | 1229 | const rhs_node = tree.nodeData(node).node; |
| 1235 | const rhs_node = node_datas[node].lhs; | ||
| 1236 | 1230 | ||
| 1237 | if (gz.suspend_node != 0) { | 1231 | if (gz.suspend_node.unwrap()) |suspend_node| { |
| 1238 | return astgen.failNodeNotes(node, "cannot await inside suspend block", .{}, &[_]u32{ | 1232 | return astgen.failNodeNotes(node, "cannot await inside suspend block", .{}, &[_]u32{ |
| 1239 | try astgen.errNoteNode(gz.suspend_node, "suspend block here", .{}), | 1233 | try astgen.errNoteNode(suspend_node, "suspend block here", .{}), |
| 1240 | }); | 1234 | }); |
| 1241 | } | 1235 | } |
| 1242 | const operand = try expr(gz, scope, .{ .rl = .ref }, rhs_node); | 1236 | const operand = try expr(gz, scope, .{ .rl = .ref }, rhs_node); |
| 1243 | const result = if (gz.nosuspend_node != 0) | 1237 | const result = if (gz.nosuspend_node != .none) |
| 1244 | try gz.addExtendedPayload(.await_nosuspend, Zir.Inst.UnNode{ | 1238 | try gz.addExtendedPayload(.await_nosuspend, Zir.Inst.UnNode{ |
| 1245 | .node = gz.nodeIndexToRelative(node), | 1239 | .node = gz.nodeIndexToRelative(node), |
| 1246 | .operand = operand, | 1240 | .operand = operand, |
| ... | @@ -1259,8 +1253,7 @@ fn resumeExpr( | ... | @@ -1259,8 +1253,7 @@ fn resumeExpr( |
| 1259 | ) InnerError!Zir.Inst.Ref { | 1253 | ) InnerError!Zir.Inst.Ref { |
| 1260 | const astgen = gz.astgen; | 1254 | const astgen = gz.astgen; |
| 1261 | const tree = astgen.tree; | 1255 | const tree = astgen.tree; |
| 1262 | const node_datas = tree.nodes.items(.data); | 1256 | const rhs_node = tree.nodeData(node).node; |
| 1263 | const rhs_node = node_datas[node].lhs; | ||
| 1264 | const operand = try expr(gz, scope, .{ .rl = .ref }, rhs_node); | 1257 | const operand = try expr(gz, scope, .{ .rl = .ref }, rhs_node); |
| 1265 | const result = try gz.addUnNode(.@"resume", operand, node); | 1258 | const result = try gz.addUnNode(.@"resume", operand, node); |
| 1266 | return rvalue(gz, ri, result, node); | 1259 | return rvalue(gz, ri, result, node); |
| ... | @@ -1275,33 +1268,33 @@ fn fnProtoExpr( | ... | @@ -1275,33 +1268,33 @@ fn fnProtoExpr( |
| 1275 | ) InnerError!Zir.Inst.Ref { | 1268 | ) InnerError!Zir.Inst.Ref { |
| 1276 | const astgen = gz.astgen; | 1269 | const astgen = gz.astgen; |
| 1277 | const tree = astgen.tree; | 1270 | const tree = astgen.tree; |
| 1278 | const token_tags = tree.tokens.items(.tag); | ||
| 1279 | 1271 | ||
| 1280 | if (fn_proto.name_token) |some| { | 1272 | if (fn_proto.name_token) |some| { |
| 1281 | return astgen.failTok(some, "function type cannot have a name", .{}); | 1273 | return astgen.failTok(some, "function type cannot have a name", .{}); |
| 1282 | } | 1274 | } |
| 1283 | 1275 | ||
| 1284 | if (fn_proto.ast.align_expr != 0) { | 1276 | if (fn_proto.ast.align_expr.unwrap()) |align_expr| { |
| 1285 | return astgen.failNode(fn_proto.ast.align_expr, "function type cannot have an alignment", .{}); | 1277 | return astgen.failNode(align_expr, "function type cannot have an alignment", .{}); |
| 1286 | } | 1278 | } |
| 1287 | 1279 | ||
| 1288 | if (fn_proto.ast.addrspace_expr != 0) { | 1280 | if (fn_proto.ast.addrspace_expr.unwrap()) |addrspace_expr| { |
| 1289 | return astgen.failNode(fn_proto.ast.addrspace_expr, "function type cannot have an addrspace", .{}); | 1281 | return astgen.failNode(addrspace_expr, "function type cannot have an addrspace", .{}); |
| 1290 | } | 1282 | } |
| 1291 | 1283 | ||
| 1292 | if (fn_proto.ast.section_expr != 0) { | 1284 | if (fn_proto.ast.section_expr.unwrap()) |section_expr| { |
| 1293 | return astgen.failNode(fn_proto.ast.section_expr, "function type cannot have a linksection", .{}); | 1285 | return astgen.failNode(section_expr, "function type cannot have a linksection", .{}); |
| 1294 | } | 1286 | } |
| 1295 | 1287 | ||
| 1296 | const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1; | 1288 | const return_type = fn_proto.ast.return_type.unwrap().?; |
| 1297 | const is_inferred_error = token_tags[maybe_bang] == .bang; | 1289 | const maybe_bang = tree.firstToken(return_type) - 1; |
| 1290 | const is_inferred_error = tree.tokenTag(maybe_bang) == .bang; | ||
| 1298 | if (is_inferred_error) { | 1291 | if (is_inferred_error) { |
| 1299 | return astgen.failTok(maybe_bang, "function type cannot have an inferred error set", .{}); | 1292 | return astgen.failTok(maybe_bang, "function type cannot have an inferred error set", .{}); |
| 1300 | } | 1293 | } |
| 1301 | 1294 | ||
| 1302 | const is_extern = blk: { | 1295 | const is_extern = blk: { |
| 1303 | const maybe_extern_token = fn_proto.extern_export_inline_token orelse break :blk false; | 1296 | const maybe_extern_token = fn_proto.extern_export_inline_token orelse break :blk false; |
| 1304 | break :blk token_tags[maybe_extern_token] == .keyword_extern; | 1297 | break :blk tree.tokenTag(maybe_extern_token) == .keyword_extern; |
| 1305 | }; | 1298 | }; |
| 1306 | assert(!is_extern); | 1299 | assert(!is_extern); |
| 1307 | 1300 | ||
| ... | @@ -1318,7 +1311,6 @@ fn fnProtoExprInner( | ... | @@ -1318,7 +1311,6 @@ fn fnProtoExprInner( |
| 1318 | ) InnerError!Zir.Inst.Ref { | 1311 | ) InnerError!Zir.Inst.Ref { |
| 1319 | const astgen = gz.astgen; | 1312 | const astgen = gz.astgen; |
| 1320 | const tree = astgen.tree; | 1313 | const tree = astgen.tree; |
| 1321 | const token_tags = tree.tokens.items(.tag); | ||
| 1322 | 1314 | ||
| 1323 | var block_scope = gz.makeSubBlock(scope); | 1315 | var block_scope = gz.makeSubBlock(scope); |
| 1324 | defer block_scope.unstack(); | 1316 | defer block_scope.unstack(); |
| ... | @@ -1330,7 +1322,7 @@ fn fnProtoExprInner( | ... | @@ -1330,7 +1322,7 @@ fn fnProtoExprInner( |
| 1330 | var param_type_i: usize = 0; | 1322 | var param_type_i: usize = 0; |
| 1331 | var it = fn_proto.iterate(tree); | 1323 | var it = fn_proto.iterate(tree); |
| 1332 | while (it.next()) |param| : (param_type_i += 1) { | 1324 | while (it.next()) |param| : (param_type_i += 1) { |
| 1333 | const is_comptime = if (param.comptime_noalias) |token| switch (token_tags[token]) { | 1325 | const is_comptime = if (param.comptime_noalias) |token| switch (tree.tokenTag(token)) { |
| 1334 | .keyword_noalias => is_comptime: { | 1326 | .keyword_noalias => is_comptime: { |
| 1335 | noalias_bits |= @as(u32, 1) << (std.math.cast(u5, param_type_i) orelse | 1327 | noalias_bits |= @as(u32, 1) << (std.math.cast(u5, param_type_i) orelse |
| 1336 | return astgen.failTok(token, "this compiler implementation only supports 'noalias' on the first 32 parameters", .{})); | 1328 | return astgen.failTok(token, "this compiler implementation only supports 'noalias' on the first 32 parameters", .{})); |
| ... | @@ -1341,7 +1333,7 @@ fn fnProtoExprInner( | ... | @@ -1341,7 +1333,7 @@ fn fnProtoExprInner( |
| 1341 | } else false; | 1333 | } else false; |
| 1342 | 1334 | ||
| 1343 | const is_anytype = if (param.anytype_ellipsis3) |token| blk: { | 1335 | const is_anytype = if (param.anytype_ellipsis3) |token| blk: { |
| 1344 | switch (token_tags[token]) { | 1336 | switch (tree.tokenTag(token)) { |
| 1345 | .keyword_anytype => break :blk true, | 1337 | .keyword_anytype => break :blk true, |
| 1346 | .ellipsis3 => break :is_var_args true, | 1338 | .ellipsis3 => break :is_var_args true, |
| 1347 | else => unreachable, | 1339 | else => unreachable, |
| ... | @@ -1364,16 +1356,14 @@ fn fnProtoExprInner( | ... | @@ -1364,16 +1356,14 @@ fn fnProtoExprInner( |
| 1364 | .param_anytype; | 1356 | .param_anytype; |
| 1365 | _ = try block_scope.addStrTok(tag, param_name, name_token); | 1357 | _ = try block_scope.addStrTok(tag, param_name, name_token); |
| 1366 | } else { | 1358 | } else { |
| 1367 | const param_type_node = param.type_expr; | 1359 | const param_type_node = param.type_expr.?; |
| 1368 | assert(param_type_node != 0); | ||
| 1369 | var param_gz = block_scope.makeSubBlock(scope); | 1360 | var param_gz = block_scope.makeSubBlock(scope); |
| 1370 | defer param_gz.unstack(); | 1361 | defer param_gz.unstack(); |
| 1371 | param_gz.is_comptime = true; | 1362 | param_gz.is_comptime = true; |
| 1372 | const param_type = try fullBodyExpr(&param_gz, scope, coerced_type_ri, param_type_node, .normal); | 1363 | const param_type = try fullBodyExpr(&param_gz, scope, coerced_type_ri, param_type_node, .normal); |
| 1373 | const param_inst_expected: Zir.Inst.Index = @enumFromInt(astgen.instructions.len + 1); | 1364 | const param_inst_expected: Zir.Inst.Index = @enumFromInt(astgen.instructions.len + 1); |
| 1374 | _ = try param_gz.addBreakWithSrcNode(.break_inline, param_inst_expected, param_type, param_type_node); | 1365 | _ = try param_gz.addBreakWithSrcNode(.break_inline, param_inst_expected, param_type, param_type_node); |
| 1375 | const main_tokens = tree.nodes.items(.main_token); | 1366 | const name_token = param.name_token orelse tree.nodeMainToken(param_type_node); |
| 1376 | const name_token = param.name_token orelse main_tokens[param_type_node]; | ||
| 1377 | const tag: Zir.Inst.Tag = if (is_comptime) .param_comptime else .param; | 1367 | const tag: Zir.Inst.Tag = if (is_comptime) .param_comptime else .param; |
| 1378 | // We pass `prev_param_insts` as `&.{}` here because a function prototype can't refer to previous | 1368 | // We pass `prev_param_insts` as `&.{}` here because a function prototype can't refer to previous |
| 1379 | // arguments (we haven't set up scopes here). | 1369 | // arguments (we haven't set up scopes here). |
| ... | @@ -1384,12 +1374,12 @@ fn fnProtoExprInner( | ... | @@ -1384,12 +1374,12 @@ fn fnProtoExprInner( |
| 1384 | break :is_var_args false; | 1374 | break :is_var_args false; |
| 1385 | }; | 1375 | }; |
| 1386 | 1376 | ||
| 1387 | const cc: Zir.Inst.Ref = if (fn_proto.ast.callconv_expr != 0) | 1377 | const cc: Zir.Inst.Ref = if (fn_proto.ast.callconv_expr.unwrap()) |callconv_expr| |
| 1388 | try comptimeExpr( | 1378 | try comptimeExpr( |
| 1389 | &block_scope, | 1379 | &block_scope, |
| 1390 | scope, | 1380 | scope, |
| 1391 | .{ .rl = .{ .coerced_ty = try block_scope.addBuiltinValue(fn_proto.ast.callconv_expr, .calling_convention) } }, | 1381 | .{ .rl = .{ .coerced_ty = try block_scope.addBuiltinValue(callconv_expr, .calling_convention) } }, |
| 1392 | fn_proto.ast.callconv_expr, | 1382 | callconv_expr, |
| 1393 | .@"callconv", | 1383 | .@"callconv", |
| 1394 | ) | 1384 | ) |
| 1395 | else if (implicit_ccc) | 1385 | else if (implicit_ccc) |
| ... | @@ -1397,7 +1387,8 @@ fn fnProtoExprInner( | ... | @@ -1397,7 +1387,8 @@ fn fnProtoExprInner( |
| 1397 | else | 1387 | else |
| 1398 | .none; | 1388 | .none; |
| 1399 | 1389 | ||
| 1400 | const ret_ty = try comptimeExpr(&block_scope, scope, coerced_type_ri, fn_proto.ast.return_type, .function_ret_ty); | 1390 | const ret_ty_node = fn_proto.ast.return_type.unwrap().?; |
| 1391 | const ret_ty = try comptimeExpr(&block_scope, scope, coerced_type_ri, ret_ty_node, .function_ret_ty); | ||
| 1401 | 1392 | ||
| 1402 | const result = try block_scope.addFunc(.{ | 1393 | const result = try block_scope.addFunc(.{ |
| 1403 | .src_node = fn_proto.ast.proto_node, | 1394 | .src_node = fn_proto.ast.proto_node, |
| ... | @@ -1437,33 +1428,32 @@ fn arrayInitExpr( | ... | @@ -1437,33 +1428,32 @@ fn arrayInitExpr( |
| 1437 | ) InnerError!Zir.Inst.Ref { | 1428 | ) InnerError!Zir.Inst.Ref { |
| 1438 | const astgen = gz.astgen; | 1429 | const astgen = gz.astgen; |
| 1439 | const tree = astgen.tree; | 1430 | const tree = astgen.tree; |
| 1440 | const node_tags = tree.nodes.items(.tag); | ||
| 1441 | const main_tokens = tree.nodes.items(.main_token); | ||
| 1442 | 1431 | ||
| 1443 | assert(array_init.ast.elements.len != 0); // Otherwise it would be struct init. | 1432 | assert(array_init.ast.elements.len != 0); // Otherwise it would be struct init. |
| 1444 | 1433 | ||
| 1445 | const array_ty: Zir.Inst.Ref, const elem_ty: Zir.Inst.Ref = inst: { | 1434 | const array_ty: Zir.Inst.Ref, const elem_ty: Zir.Inst.Ref = inst: { |
| 1446 | if (array_init.ast.type_expr == 0) break :inst .{ .none, .none }; | 1435 | const type_expr = array_init.ast.type_expr.unwrap() orelse break :inst .{ .none, .none }; |
| 1447 | 1436 | ||
| 1448 | infer: { | 1437 | infer: { |
| 1449 | const array_type: Ast.full.ArrayType = tree.fullArrayType(array_init.ast.type_expr) orelse break :infer; | 1438 | const array_type: Ast.full.ArrayType = tree.fullArrayType(type_expr) orelse break :infer; |
| 1450 | // This intentionally does not support `@"_"` syntax. | 1439 | // This intentionally does not support `@"_"` syntax. |
| 1451 | if (node_tags[array_type.ast.elem_count] == .identifier and | 1440 | if (tree.nodeTag(array_type.ast.elem_count) == .identifier and |
| 1452 | mem.eql(u8, tree.tokenSlice(main_tokens[array_type.ast.elem_count]), "_")) | 1441 | mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(array_type.ast.elem_count)), "_")) |
| 1453 | { | 1442 | { |
| 1454 | const len_inst = try gz.addInt(array_init.ast.elements.len); | 1443 | const len_inst = try gz.addInt(array_init.ast.elements.len); |
| 1455 | const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type); | 1444 | const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type); |
| 1456 | if (array_type.ast.sentinel == 0) { | 1445 | if (array_type.ast.sentinel == .none) { |
| 1457 | const array_type_inst = try gz.addPlNode(.array_type, array_init.ast.type_expr, Zir.Inst.Bin{ | 1446 | const array_type_inst = try gz.addPlNode(.array_type, type_expr, Zir.Inst.Bin{ |
| 1458 | .lhs = len_inst, | 1447 | .lhs = len_inst, |
| 1459 | .rhs = elem_type, | 1448 | .rhs = elem_type, |
| 1460 | }); | 1449 | }); |
| 1461 | break :inst .{ array_type_inst, elem_type }; | 1450 | break :inst .{ array_type_inst, elem_type }; |
| 1462 | } else { | 1451 | } else { |
| 1463 | const sentinel = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = elem_type } }, array_type.ast.sentinel, .array_sentinel); | 1452 | const sentinel_node = array_type.ast.sentinel.unwrap().?; |
| 1453 | const sentinel = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = elem_type } }, sentinel_node, .array_sentinel); | ||
| 1464 | const array_type_inst = try gz.addPlNode( | 1454 | const array_type_inst = try gz.addPlNode( |
| 1465 | .array_type_sentinel, | 1455 | .array_type_sentinel, |
| 1466 | array_init.ast.type_expr, | 1456 | type_expr, |
| 1467 | Zir.Inst.ArrayTypeSentinel{ | 1457 | Zir.Inst.ArrayTypeSentinel{ |
| 1468 | .len = len_inst, | 1458 | .len = len_inst, |
| 1469 | .elem_type = elem_type, | 1459 | .elem_type = elem_type, |
| ... | @@ -1474,7 +1464,7 @@ fn arrayInitExpr( | ... | @@ -1474,7 +1464,7 @@ fn arrayInitExpr( |
| 1474 | } | 1464 | } |
| 1475 | } | 1465 | } |
| 1476 | } | 1466 | } |
| 1477 | const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr); | 1467 | const array_type_inst = try typeExpr(gz, scope, type_expr); |
| 1478 | _ = try gz.addPlNode(.validate_array_init_ty, node, Zir.Inst.ArrayInit{ | 1468 | _ = try gz.addPlNode(.validate_array_init_ty, node, Zir.Inst.ArrayInit{ |
| 1479 | .ty = array_type_inst, | 1469 | .ty = array_type_inst, |
| 1480 | .init_count = @intCast(array_init.ast.elements.len), | 1470 | .init_count = @intCast(array_init.ast.elements.len), |
| ... | @@ -1682,7 +1672,7 @@ fn structInitExpr( | ... | @@ -1682,7 +1672,7 @@ fn structInitExpr( |
| 1682 | const astgen = gz.astgen; | 1672 | const astgen = gz.astgen; |
| 1683 | const tree = astgen.tree; | 1673 | const tree = astgen.tree; |
| 1684 | 1674 | ||
| 1685 | if (struct_init.ast.type_expr == 0) { | 1675 | if (struct_init.ast.type_expr == .none) { |
| 1686 | if (struct_init.ast.fields.len == 0) { | 1676 | if (struct_init.ast.fields.len == 0) { |
| 1687 | // Anonymous init with no fields. | 1677 | // Anonymous init with no fields. |
| 1688 | switch (ri.rl) { | 1678 | switch (ri.rl) { |
| ... | @@ -1706,32 +1696,32 @@ fn structInitExpr( | ... | @@ -1706,32 +1696,32 @@ fn structInitExpr( |
| 1706 | } | 1696 | } |
| 1707 | } | 1697 | } |
| 1708 | } else array: { | 1698 | } else array: { |
| 1709 | const node_tags = tree.nodes.items(.tag); | 1699 | const type_expr = struct_init.ast.type_expr.unwrap().?; |
| 1710 | const main_tokens = tree.nodes.items(.main_token); | 1700 | const array_type: Ast.full.ArrayType = tree.fullArrayType(type_expr) orelse { |
| 1711 | const array_type: Ast.full.ArrayType = tree.fullArrayType(struct_init.ast.type_expr) orelse { | ||
| 1712 | if (struct_init.ast.fields.len == 0) { | 1701 | if (struct_init.ast.fields.len == 0) { |
| 1713 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); | 1702 | const ty_inst = try typeExpr(gz, scope, type_expr); |
| 1714 | const result = try gz.addUnNode(.struct_init_empty, ty_inst, node); | 1703 | const result = try gz.addUnNode(.struct_init_empty, ty_inst, node); |
| 1715 | return rvalue(gz, ri, result, node); | 1704 | return rvalue(gz, ri, result, node); |
| 1716 | } | 1705 | } |
| 1717 | break :array; | 1706 | break :array; |
| 1718 | }; | 1707 | }; |
| 1719 | const is_inferred_array_len = node_tags[array_type.ast.elem_count] == .identifier and | 1708 | const is_inferred_array_len = tree.nodeTag(array_type.ast.elem_count) == .identifier and |
| 1720 | // This intentionally does not support `@"_"` syntax. | 1709 | // This intentionally does not support `@"_"` syntax. |
| 1721 | mem.eql(u8, tree.tokenSlice(main_tokens[array_type.ast.elem_count]), "_"); | 1710 | mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(array_type.ast.elem_count)), "_"); |
| 1722 | if (struct_init.ast.fields.len == 0) { | 1711 | if (struct_init.ast.fields.len == 0) { |
| 1723 | if (is_inferred_array_len) { | 1712 | if (is_inferred_array_len) { |
| 1724 | const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type); | 1713 | const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type); |
| 1725 | const array_type_inst = if (array_type.ast.sentinel == 0) blk: { | 1714 | const array_type_inst = if (array_type.ast.sentinel == .none) blk: { |
| 1726 | break :blk try gz.addPlNode(.array_type, struct_init.ast.type_expr, Zir.Inst.Bin{ | 1715 | break :blk try gz.addPlNode(.array_type, type_expr, Zir.Inst.Bin{ |
| 1727 | .lhs = .zero_usize, | 1716 | .lhs = .zero_usize, |
| 1728 | .rhs = elem_type, | 1717 | .rhs = elem_type, |
| 1729 | }); | 1718 | }); |
| 1730 | } else blk: { | 1719 | } else blk: { |
| 1731 | const sentinel = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = elem_type } }, array_type.ast.sentinel, .array_sentinel); | 1720 | const sentinel_node = array_type.ast.sentinel.unwrap().?; |
| 1721 | const sentinel = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = elem_type } }, sentinel_node, .array_sentinel); | ||
| 1732 | break :blk try gz.addPlNode( | 1722 | break :blk try gz.addPlNode( |
| 1733 | .array_type_sentinel, | 1723 | .array_type_sentinel, |
| 1734 | struct_init.ast.type_expr, | 1724 | type_expr, |
| 1735 | Zir.Inst.ArrayTypeSentinel{ | 1725 | Zir.Inst.ArrayTypeSentinel{ |
| 1736 | .len = .zero_usize, | 1726 | .len = .zero_usize, |
| 1737 | .elem_type = elem_type, | 1727 | .elem_type = elem_type, |
| ... | @@ -1742,12 +1732,12 @@ fn structInitExpr( | ... | @@ -1742,12 +1732,12 @@ fn structInitExpr( |
| 1742 | const result = try gz.addUnNode(.struct_init_empty, array_type_inst, node); | 1732 | const result = try gz.addUnNode(.struct_init_empty, array_type_inst, node); |
| 1743 | return rvalue(gz, ri, result, node); | 1733 | return rvalue(gz, ri, result, node); |
| 1744 | } | 1734 | } |
| 1745 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); | 1735 | const ty_inst = try typeExpr(gz, scope, type_expr); |
| 1746 | const result = try gz.addUnNode(.struct_init_empty, ty_inst, node); | 1736 | const result = try gz.addUnNode(.struct_init_empty, ty_inst, node); |
| 1747 | return rvalue(gz, ri, result, node); | 1737 | return rvalue(gz, ri, result, node); |
| 1748 | } else { | 1738 | } else { |
| 1749 | return astgen.failNode( | 1739 | return astgen.failNode( |
| 1750 | struct_init.ast.type_expr, | 1740 | type_expr, |
| 1751 | "initializing array with struct syntax", | 1741 | "initializing array with struct syntax", |
| 1752 | .{}, | 1742 | .{}, |
| 1753 | ); | 1743 | ); |
| ... | @@ -1806,9 +1796,9 @@ fn structInitExpr( | ... | @@ -1806,9 +1796,9 @@ fn structInitExpr( |
| 1806 | } | 1796 | } |
| 1807 | } | 1797 | } |
| 1808 | 1798 | ||
| 1809 | if (struct_init.ast.type_expr != 0) { | 1799 | if (struct_init.ast.type_expr.unwrap()) |type_expr| { |
| 1810 | // Typed inits do not use RLS for language simplicity. | 1800 | // Typed inits do not use RLS for language simplicity. |
| 1811 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); | 1801 | const ty_inst = try typeExpr(gz, scope, type_expr); |
| 1812 | _ = try gz.addUnNode(.validate_struct_init_ty, ty_inst, node); | 1802 | _ = try gz.addUnNode(.validate_struct_init_ty, ty_inst, node); |
| 1813 | switch (ri.rl) { | 1803 | switch (ri.rl) { |
| 1814 | .ref => return structInitExprTyped(gz, scope, node, struct_init, ty_inst, true), | 1804 | .ref => return structInitExprTyped(gz, scope, node, struct_init, ty_inst, true), |
| ... | @@ -1997,9 +1987,7 @@ fn comptimeExpr2( | ... | @@ -1997,9 +1987,7 @@ fn comptimeExpr2( |
| 1997 | // no need to wrap it in a block. This is hard to determine in general, but we can identify a | 1987 | // no need to wrap it in a block. This is hard to determine in general, but we can identify a |
| 1998 | // common subset of trivially comptime expressions to take down the size of the ZIR a bit. | 1988 | // common subset of trivially comptime expressions to take down the size of the ZIR a bit. |
| 1999 | const tree = gz.astgen.tree; | 1989 | const tree = gz.astgen.tree; |
| 2000 | const main_tokens = tree.nodes.items(.main_token); | 1990 | switch (tree.nodeTag(node)) { |
| 2001 | const node_tags = tree.nodes.items(.tag); | ||
| 2002 | switch (node_tags[node]) { | ||
| 2003 | .identifier => { | 1991 | .identifier => { |
| 2004 | // Many identifiers can be handled without a `block_comptime`, so `AstGen.identifier` has | 1992 | // Many identifiers can be handled without a `block_comptime`, so `AstGen.identifier` has |
| 2005 | // special handling for this case. | 1993 | // special handling for this case. |
| ... | @@ -2052,8 +2040,7 @@ fn comptimeExpr2( | ... | @@ -2052,8 +2040,7 @@ fn comptimeExpr2( |
| 2052 | // comptime block, because that would be silly! Note that we don't bother doing this for | 2040 | // comptime block, because that would be silly! Note that we don't bother doing this for |
| 2053 | // unlabelled blocks, since they don't generate blocks at comptime anyway (see `blockExpr`). | 2041 | // unlabelled blocks, since they don't generate blocks at comptime anyway (see `blockExpr`). |
| 2054 | .block_two, .block_two_semicolon, .block, .block_semicolon => { | 2042 | .block_two, .block_two_semicolon, .block, .block_semicolon => { |
| 2055 | const token_tags = tree.tokens.items(.tag); | 2043 | const lbrace = tree.nodeMainToken(node); |
| 2056 | const lbrace = main_tokens[node]; | ||
| 2057 | // Careful! We can't pass in the real result location here, since it may | 2044 | // Careful! We can't pass in the real result location here, since it may |
| 2058 | // refer to runtime memory. A runtime-to-comptime boundary has to remove | 2045 | // refer to runtime memory. A runtime-to-comptime boundary has to remove |
| 2059 | // result location information, compute the result, and copy it to the true | 2046 | // result location information, compute the result, and copy it to the true |
| ... | @@ -2065,11 +2052,10 @@ fn comptimeExpr2( | ... | @@ -2065,11 +2052,10 @@ fn comptimeExpr2( |
| 2065 | else | 2052 | else |
| 2066 | .none, | 2053 | .none, |
| 2067 | }; | 2054 | }; |
| 2068 | if (token_tags[lbrace - 1] == .colon and | 2055 | if (tree.isTokenPrecededByTags(lbrace, &.{ .identifier, .colon })) { |
| 2069 | token_tags[lbrace - 2] == .identifier) | ||
| 2070 | { | ||
| 2071 | var buf: [2]Ast.Node.Index = undefined; | 2056 | var buf: [2]Ast.Node.Index = undefined; |
| 2072 | const stmts = tree.blockStatements(&buf, node).?; | 2057 | const stmts = tree.blockStatements(&buf, node).?; |
| 2058 | |||
| 2073 | // Replace result location and copy back later - see above. | 2059 | // Replace result location and copy back later - see above. |
| 2074 | const block_ref = try labeledBlockExpr(gz, scope, ty_only_ri, node, stmts, true, .normal); | 2060 | const block_ref = try labeledBlockExpr(gz, scope, ty_only_ri, node, stmts, true, .normal); |
| 2075 | return rvalue(gz, ri, block_ref, node); | 2061 | return rvalue(gz, ri, block_ref, node); |
| ... | @@ -2117,8 +2103,7 @@ fn comptimeExprAst( | ... | @@ -2117,8 +2103,7 @@ fn comptimeExprAst( |
| 2117 | try astgen.appendErrorNode(node, "redundant comptime keyword in already comptime scope", .{}); | 2103 | try astgen.appendErrorNode(node, "redundant comptime keyword in already comptime scope", .{}); |
| 2118 | } | 2104 | } |
| 2119 | const tree = astgen.tree; | 2105 | const tree = astgen.tree; |
| 2120 | const node_datas = tree.nodes.items(.data); | 2106 | const body_node = tree.nodeData(node).node; |
| 2121 | const body_node = node_datas[node].lhs; | ||
| 2122 | return comptimeExpr2(gz, scope, ri, body_node, node, .comptime_keyword); | 2107 | return comptimeExpr2(gz, scope, ri, body_node, node, .comptime_keyword); |
| 2123 | } | 2108 | } |
| 2124 | 2109 | ||
| ... | @@ -2156,9 +2141,7 @@ fn restoreErrRetIndex( | ... | @@ -2156,9 +2141,7 @@ fn restoreErrRetIndex( |
| 2156 | fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { | 2141 | fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 2157 | const astgen = parent_gz.astgen; | 2142 | const astgen = parent_gz.astgen; |
| 2158 | const tree = astgen.tree; | 2143 | const tree = astgen.tree; |
| 2159 | const node_datas = tree.nodes.items(.data); | 2144 | const opt_break_label, const opt_rhs = tree.nodeData(node).opt_token_and_opt_node; |
| 2160 | const break_label = node_datas[node].lhs; | ||
| 2161 | const rhs = node_datas[node].rhs; | ||
| 2162 | 2145 | ||
| 2163 | // Look for the label in the scope. | 2146 | // Look for the label in the scope. |
| 2164 | var scope = parent_scope; | 2147 | var scope = parent_scope; |
| ... | @@ -2167,11 +2150,11 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -2167,11 +2150,11 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 2167 | .gen_zir => { | 2150 | .gen_zir => { |
| 2168 | const block_gz = scope.cast(GenZir).?; | 2151 | const block_gz = scope.cast(GenZir).?; |
| 2169 | 2152 | ||
| 2170 | if (block_gz.cur_defer_node != 0) { | 2153 | if (block_gz.cur_defer_node.unwrap()) |cur_defer_node| { |
| 2171 | // We are breaking out of a `defer` block. | 2154 | // We are breaking out of a `defer` block. |
| 2172 | return astgen.failNodeNotes(node, "cannot break out of defer expression", .{}, &.{ | 2155 | return astgen.failNodeNotes(node, "cannot break out of defer expression", .{}, &.{ |
| 2173 | try astgen.errNoteNode( | 2156 | try astgen.errNoteNode( |
| 2174 | block_gz.cur_defer_node, | 2157 | cur_defer_node, |
| 2175 | "defer expression here", | 2158 | "defer expression here", |
| 2176 | .{}, | 2159 | .{}, |
| 2177 | ), | 2160 | ), |
| ... | @@ -2179,7 +2162,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -2179,7 +2162,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 2179 | } | 2162 | } |
| 2180 | 2163 | ||
| 2181 | const block_inst = blk: { | 2164 | const block_inst = blk: { |
| 2182 | if (break_label != 0) { | 2165 | if (opt_break_label.unwrap()) |break_label| { |
| 2183 | if (block_gz.label) |*label| { | 2166 | if (block_gz.label) |*label| { |
| 2184 | if (try astgen.tokenIdentEql(label.token, break_label)) { | 2167 | if (try astgen.tokenIdentEql(label.token, break_label)) { |
| 2185 | label.used = true; | 2168 | label.used = true; |
| ... | @@ -2200,7 +2183,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -2200,7 +2183,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 2200 | else | 2183 | else |
| 2201 | .@"break"; | 2184 | .@"break"; |
| 2202 | 2185 | ||
| 2203 | if (rhs == 0) { | 2186 | const rhs = opt_rhs.unwrap() orelse { |
| 2204 | _ = try rvalue(parent_gz, block_gz.break_result_info, .void_value, node); | 2187 | _ = try rvalue(parent_gz, block_gz.break_result_info, .void_value, node); |
| 2205 | 2188 | ||
| 2206 | try genDefers(parent_gz, scope, parent_scope, .normal_only); | 2189 | try genDefers(parent_gz, scope, parent_scope, .normal_only); |
| ... | @@ -2211,7 +2194,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -2211,7 +2194,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 2211 | 2194 | ||
| 2212 | _ = try parent_gz.addBreak(break_tag, block_inst, .void_value); | 2195 | _ = try parent_gz.addBreak(break_tag, block_inst, .void_value); |
| 2213 | return Zir.Inst.Ref.unreachable_value; | 2196 | return Zir.Inst.Ref.unreachable_value; |
| 2214 | } | 2197 | }; |
| 2215 | 2198 | ||
| 2216 | const operand = try reachableExpr(parent_gz, parent_scope, block_gz.break_result_info, rhs, node); | 2199 | const operand = try reachableExpr(parent_gz, parent_scope, block_gz.break_result_info, rhs, node); |
| 2217 | 2200 | ||
| ... | @@ -2243,7 +2226,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -2243,7 +2226,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 2243 | .top => unreachable, | 2226 | .top => unreachable, |
| 2244 | } | 2227 | } |
| 2245 | } | 2228 | } |
| 2246 | if (break_label != 0) { | 2229 | if (opt_break_label.unwrap()) |break_label| { |
| 2247 | const label_name = try astgen.identifierTokenString(break_label); | 2230 | const label_name = try astgen.identifierTokenString(break_label); |
| 2248 | return astgen.failTok(break_label, "label not found: '{s}'", .{label_name}); | 2231 | return astgen.failTok(break_label, "label not found: '{s}'", .{label_name}); |
| 2249 | } else { | 2232 | } else { |
| ... | @@ -2254,11 +2237,9 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -2254,11 +2237,9 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 2254 | fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { | 2237 | fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 2255 | const astgen = parent_gz.astgen; | 2238 | const astgen = parent_gz.astgen; |
| 2256 | const tree = astgen.tree; | 2239 | const tree = astgen.tree; |
| 2257 | const node_datas = tree.nodes.items(.data); | 2240 | const opt_break_label, const opt_rhs = tree.nodeData(node).opt_token_and_opt_node; |
| 2258 | const break_label = node_datas[node].lhs; | ||
| 2259 | const rhs = node_datas[node].rhs; | ||
| 2260 | 2241 | ||
| 2261 | if (break_label == 0 and rhs != 0) { | 2242 | if (opt_break_label == .none and opt_rhs != .none) { |
| 2262 | return astgen.failNode(node, "cannot continue with operand without label", .{}); | 2243 | return astgen.failNode(node, "cannot continue with operand without label", .{}); |
| 2263 | } | 2244 | } |
| 2264 | 2245 | ||
| ... | @@ -2269,10 +2250,10 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) | ... | @@ -2269,10 +2250,10 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) |
| 2269 | .gen_zir => { | 2250 | .gen_zir => { |
| 2270 | const gen_zir = scope.cast(GenZir).?; | 2251 | const gen_zir = scope.cast(GenZir).?; |
| 2271 | 2252 | ||
| 2272 | if (gen_zir.cur_defer_node != 0) { | 2253 | if (gen_zir.cur_defer_node.unwrap()) |cur_defer_node| { |
| 2273 | return astgen.failNodeNotes(node, "cannot continue out of defer expression", .{}, &.{ | 2254 | return astgen.failNodeNotes(node, "cannot continue out of defer expression", .{}, &.{ |
| 2274 | try astgen.errNoteNode( | 2255 | try astgen.errNoteNode( |
| 2275 | gen_zir.cur_defer_node, | 2256 | cur_defer_node, |
| 2276 | "defer expression here", | 2257 | "defer expression here", |
| 2277 | .{}, | 2258 | .{}, |
| 2278 | ), | 2259 | ), |
| ... | @@ -2282,11 +2263,11 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) | ... | @@ -2282,11 +2263,11 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) |
| 2282 | scope = gen_zir.parent; | 2263 | scope = gen_zir.parent; |
| 2283 | continue; | 2264 | continue; |
| 2284 | }; | 2265 | }; |
| 2285 | if (break_label != 0) blk: { | 2266 | if (opt_break_label.unwrap()) |break_label| blk: { |
| 2286 | if (gen_zir.label) |*label| { | 2267 | if (gen_zir.label) |*label| { |
| 2287 | if (try astgen.tokenIdentEql(label.token, break_label)) { | 2268 | if (try astgen.tokenIdentEql(label.token, break_label)) { |
| 2288 | const maybe_switch_tag = astgen.instructions.items(.tag)[@intFromEnum(label.block_inst)]; | 2269 | const maybe_switch_tag = astgen.instructions.items(.tag)[@intFromEnum(label.block_inst)]; |
| 2289 | if (rhs != 0) switch (maybe_switch_tag) { | 2270 | if (opt_rhs != .none) switch (maybe_switch_tag) { |
| 2290 | .switch_block, .switch_block_ref => {}, | 2271 | .switch_block, .switch_block_ref => {}, |
| 2291 | else => return astgen.failNode(node, "cannot continue loop with operand", .{}), | 2272 | else => return astgen.failNode(node, "cannot continue loop with operand", .{}), |
| 2292 | } else switch (maybe_switch_tag) { | 2273 | } else switch (maybe_switch_tag) { |
| ... | @@ -2314,7 +2295,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) | ... | @@ -2314,7 +2295,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) |
| 2314 | } | 2295 | } |
| 2315 | } | 2296 | } |
| 2316 | 2297 | ||
| 2317 | if (rhs != 0) { | 2298 | if (opt_rhs.unwrap()) |rhs| { |
| 2318 | // We need to figure out the result info to use. | 2299 | // We need to figure out the result info to use. |
| 2319 | // The type should match | 2300 | // The type should match |
| 2320 | const operand = try reachableExpr(parent_gz, parent_scope, gen_zir.continue_result_info, rhs, node); | 2301 | const operand = try reachableExpr(parent_gz, parent_scope, gen_zir.continue_result_info, rhs, node); |
| ... | @@ -2353,7 +2334,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) | ... | @@ -2353,7 +2334,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) |
| 2353 | .top => unreachable, | 2334 | .top => unreachable, |
| 2354 | } | 2335 | } |
| 2355 | } | 2336 | } |
| 2356 | if (break_label != 0) { | 2337 | if (opt_break_label.unwrap()) |break_label| { |
| 2357 | const label_name = try astgen.identifierTokenString(break_label); | 2338 | const label_name = try astgen.identifierTokenString(break_label); |
| 2358 | return astgen.failTok(break_label, "label not found: '{s}'", .{label_name}); | 2339 | return astgen.failTok(break_label, "label not found: '{s}'", .{label_name}); |
| 2359 | } else { | 2340 | } else { |
| ... | @@ -2373,15 +2354,14 @@ fn fullBodyExpr( | ... | @@ -2373,15 +2354,14 @@ fn fullBodyExpr( |
| 2373 | block_kind: BlockKind, | 2354 | block_kind: BlockKind, |
| 2374 | ) InnerError!Zir.Inst.Ref { | 2355 | ) InnerError!Zir.Inst.Ref { |
| 2375 | const tree = gz.astgen.tree; | 2356 | const tree = gz.astgen.tree; |
| 2376 | const main_tokens = tree.nodes.items(.main_token); | 2357 | |
| 2377 | const token_tags = tree.tokens.items(.tag); | ||
| 2378 | var stmt_buf: [2]Ast.Node.Index = undefined; | 2358 | var stmt_buf: [2]Ast.Node.Index = undefined; |
| 2379 | const statements = tree.blockStatements(&stmt_buf, node).?; | 2359 | const statements = tree.blockStatements(&stmt_buf, node) orelse |
| 2360 | return expr(gz, scope, ri, node); | ||
| 2380 | 2361 | ||
| 2381 | const lbrace = main_tokens[node]; | 2362 | const lbrace = tree.nodeMainToken(node); |
| 2382 | if (token_tags[lbrace - 1] == .colon and | 2363 | |
| 2383 | token_tags[lbrace - 2] == .identifier) | 2364 | if (tree.isTokenPrecededByTags(lbrace, &.{ .identifier, .colon })) { |
| 2384 | { | ||
| 2385 | // Labeled blocks are tricky - forwarding result location information properly is non-trivial, | 2365 | // Labeled blocks are tricky - forwarding result location information properly is non-trivial, |
| 2386 | // plus if this block is exited with a `break_inline` we aren't allowed multiple breaks. This | 2366 | // plus if this block is exited with a `break_inline` we aren't allowed multiple breaks. This |
| 2387 | // case is rare, so just treat it as a normal expression and create a nested block. | 2367 | // case is rare, so just treat it as a normal expression and create a nested block. |
| ... | @@ -2406,13 +2386,9 @@ fn blockExpr( | ... | @@ -2406,13 +2386,9 @@ fn blockExpr( |
| 2406 | ) InnerError!Zir.Inst.Ref { | 2386 | ) InnerError!Zir.Inst.Ref { |
| 2407 | const astgen = gz.astgen; | 2387 | const astgen = gz.astgen; |
| 2408 | const tree = astgen.tree; | 2388 | const tree = astgen.tree; |
| 2409 | const main_tokens = tree.nodes.items(.main_token); | ||
| 2410 | const token_tags = tree.tokens.items(.tag); | ||
| 2411 | 2389 | ||
| 2412 | const lbrace = main_tokens[block_node]; | 2390 | const lbrace = tree.nodeMainToken(block_node); |
| 2413 | if (token_tags[lbrace - 1] == .colon and | 2391 | if (tree.isTokenPrecededByTags(lbrace, &.{ .identifier, .colon })) { |
| 2414 | token_tags[lbrace - 2] == .identifier) | ||
| 2415 | { | ||
| 2416 | return labeledBlockExpr(gz, scope, ri, block_node, statements, false, kind); | 2392 | return labeledBlockExpr(gz, scope, ri, block_node, statements, false, kind); |
| 2417 | } | 2393 | } |
| 2418 | 2394 | ||
| ... | @@ -2489,12 +2465,10 @@ fn labeledBlockExpr( | ... | @@ -2489,12 +2465,10 @@ fn labeledBlockExpr( |
| 2489 | ) InnerError!Zir.Inst.Ref { | 2465 | ) InnerError!Zir.Inst.Ref { |
| 2490 | const astgen = gz.astgen; | 2466 | const astgen = gz.astgen; |
| 2491 | const tree = astgen.tree; | 2467 | const tree = astgen.tree; |
| 2492 | const main_tokens = tree.nodes.items(.main_token); | ||
| 2493 | const token_tags = tree.tokens.items(.tag); | ||
| 2494 | 2468 | ||
| 2495 | const lbrace = main_tokens[block_node]; | 2469 | const lbrace = tree.nodeMainToken(block_node); |
| 2496 | const label_token = lbrace - 2; | 2470 | const label_token = lbrace - 2; |
| 2497 | assert(token_tags[label_token] == .identifier); | 2471 | assert(tree.tokenTag(label_token) == .identifier); |
| 2498 | 2472 | ||
| 2499 | try astgen.checkLabelRedefinition(parent_scope, label_token); | 2473 | try astgen.checkLabelRedefinition(parent_scope, label_token); |
| 2500 | 2474 | ||
| ... | @@ -2555,8 +2529,6 @@ fn labeledBlockExpr( | ... | @@ -2555,8 +2529,6 @@ fn labeledBlockExpr( |
| 2555 | fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Node.Index, block_kind: BlockKind) !void { | 2529 | fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Node.Index, block_kind: BlockKind) !void { |
| 2556 | const astgen = gz.astgen; | 2530 | const astgen = gz.astgen; |
| 2557 | const tree = astgen.tree; | 2531 | const tree = astgen.tree; |
| 2558 | const node_tags = tree.nodes.items(.tag); | ||
| 2559 | const node_data = tree.nodes.items(.data); | ||
| 2560 | 2532 | ||
| 2561 | if (statements.len == 0) return; | 2533 | if (statements.len == 0) return; |
| 2562 | 2534 | ||
| ... | @@ -2564,17 +2536,17 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod | ... | @@ -2564,17 +2536,17 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod |
| 2564 | defer block_arena.deinit(); | 2536 | defer block_arena.deinit(); |
| 2565 | const block_arena_allocator = block_arena.allocator(); | 2537 | const block_arena_allocator = block_arena.allocator(); |
| 2566 | 2538 | ||
| 2567 | var noreturn_src_node: Ast.Node.Index = 0; | 2539 | var noreturn_src_node: Ast.Node.OptionalIndex = .none; |
| 2568 | var scope = parent_scope; | 2540 | var scope = parent_scope; |
| 2569 | for (statements, 0..) |statement, stmt_idx| { | 2541 | for (statements, 0..) |statement, stmt_idx| { |
| 2570 | if (noreturn_src_node != 0) { | 2542 | if (noreturn_src_node.unwrap()) |src_node| { |
| 2571 | try astgen.appendErrorNodeNotes( | 2543 | try astgen.appendErrorNodeNotes( |
| 2572 | statement, | 2544 | statement, |
| 2573 | "unreachable code", | 2545 | "unreachable code", |
| 2574 | .{}, | 2546 | .{}, |
| 2575 | &[_]u32{ | 2547 | &[_]u32{ |
| 2576 | try astgen.errNoteNode( | 2548 | try astgen.errNoteNode( |
| 2577 | noreturn_src_node, | 2549 | src_node, |
| 2578 | "control flow is diverted here", | 2550 | "control flow is diverted here", |
| 2579 | .{}, | 2551 | .{}, |
| 2580 | ), | 2552 | ), |
| ... | @@ -2587,7 +2559,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod | ... | @@ -2587,7 +2559,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod |
| 2587 | }; | 2559 | }; |
| 2588 | var inner_node = statement; | 2560 | var inner_node = statement; |
| 2589 | while (true) { | 2561 | while (true) { |
| 2590 | switch (node_tags[inner_node]) { | 2562 | switch (tree.nodeTag(inner_node)) { |
| 2591 | // zig fmt: off | 2563 | // zig fmt: off |
| 2592 | .global_var_decl, | 2564 | .global_var_decl, |
| 2593 | .local_var_decl, | 2565 | .local_var_decl, |
| ... | @@ -2617,7 +2589,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod | ... | @@ -2617,7 +2589,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod |
| 2617 | .assign_mul_wrap => try assignOp(gz, scope, statement, .mulwrap), | 2589 | .assign_mul_wrap => try assignOp(gz, scope, statement, .mulwrap), |
| 2618 | 2590 | ||
| 2619 | .grouped_expression => { | 2591 | .grouped_expression => { |
| 2620 | inner_node = node_data[statement].lhs; | 2592 | inner_node = tree.nodeData(statement).node_and_token[0]; |
| 2621 | continue; | 2593 | continue; |
| 2622 | }, | 2594 | }, |
| 2623 | 2595 | ||
| ... | @@ -2649,15 +2621,15 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod | ... | @@ -2649,15 +2621,15 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod |
| 2649 | } | 2621 | } |
| 2650 | } | 2622 | } |
| 2651 | 2623 | ||
| 2652 | if (noreturn_src_node == 0) { | 2624 | if (noreturn_src_node == .none) { |
| 2653 | try genDefers(gz, parent_scope, scope, .normal_only); | 2625 | try genDefers(gz, parent_scope, scope, .normal_only); |
| 2654 | } | 2626 | } |
| 2655 | try checkUsed(gz, parent_scope, scope); | 2627 | try checkUsed(gz, parent_scope, scope); |
| 2656 | } | 2628 | } |
| 2657 | 2629 | ||
| 2658 | /// Returns AST source node of the thing that is noreturn if the statement is | 2630 | /// Returns AST source node of the thing that is noreturn if the statement is |
| 2659 | /// definitely `noreturn`. Otherwise returns 0. | 2631 | /// definitely `noreturn`. Otherwise returns .none. |
| 2660 | fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) InnerError!Ast.Node.Index { | 2632 | fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) InnerError!Ast.Node.OptionalIndex { |
| 2661 | try emitDbgNode(gz, statement); | 2633 | try emitDbgNode(gz, statement); |
| 2662 | // We need to emit an error if the result is not `noreturn` or `void`, but | 2634 | // We need to emit an error if the result is not `noreturn` or `void`, but |
| 2663 | // we want to avoid adding the ZIR instruction if possible for performance. | 2635 | // we want to avoid adding the ZIR instruction if possible for performance. |
| ... | @@ -2665,8 +2637,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner | ... | @@ -2665,8 +2637,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner |
| 2665 | return addEnsureResult(gz, maybe_unused_result, statement); | 2637 | return addEnsureResult(gz, maybe_unused_result, statement); |
| 2666 | } | 2638 | } |
| 2667 | 2639 | ||
| 2668 | fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: Ast.Node.Index) InnerError!Ast.Node.Index { | 2640 | fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: Ast.Node.Index) InnerError!Ast.Node.OptionalIndex { |
| 2669 | var noreturn_src_node: Ast.Node.Index = 0; | 2641 | var noreturn_src_node: Ast.Node.OptionalIndex = .none; |
| 2670 | const elide_check = if (maybe_unused_result.toIndex()) |inst| b: { | 2642 | const elide_check = if (maybe_unused_result.toIndex()) |inst| b: { |
| 2671 | // Note that this array becomes invalid after appending more items to it | 2643 | // Note that this array becomes invalid after appending more items to it |
| 2672 | // in the above while loop. | 2644 | // in the above while loop. |
| ... | @@ -2927,7 +2899,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As | ... | @@ -2927,7 +2899,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2927 | .check_comptime_control_flow, | 2899 | .check_comptime_control_flow, |
| 2928 | .switch_continue, | 2900 | .switch_continue, |
| 2929 | => { | 2901 | => { |
| 2930 | noreturn_src_node = statement; | 2902 | noreturn_src_node = statement.toOptional(); |
| 2931 | break :b true; | 2903 | break :b true; |
| 2932 | }, | 2904 | }, |
| 2933 | 2905 | ||
| ... | @@ -2969,7 +2941,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As | ... | @@ -2969,7 +2941,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2969 | .none => unreachable, | 2941 | .none => unreachable, |
| 2970 | 2942 | ||
| 2971 | .unreachable_value => b: { | 2943 | .unreachable_value => b: { |
| 2972 | noreturn_src_node = statement; | 2944 | noreturn_src_node = statement.toOptional(); |
| 2973 | break :b true; | 2945 | break :b true; |
| 2974 | }, | 2946 | }, |
| 2975 | 2947 | ||
| ... | @@ -3098,23 +3070,23 @@ fn checkUsed(gz: *GenZir, outer_scope: *Scope, inner_scope: *Scope) InnerError!v | ... | @@ -3098,23 +3070,23 @@ fn checkUsed(gz: *GenZir, outer_scope: *Scope, inner_scope: *Scope) InnerError!v |
| 3098 | .gen_zir => scope = scope.cast(GenZir).?.parent, | 3070 | .gen_zir => scope = scope.cast(GenZir).?.parent, |
| 3099 | .local_val => { | 3071 | .local_val => { |
| 3100 | const s = scope.cast(Scope.LocalVal).?; | 3072 | const s = scope.cast(Scope.LocalVal).?; |
| 3101 | if (s.used == 0 and s.discarded == 0) { | 3073 | if (s.used == .none and s.discarded == .none) { |
| 3102 | try astgen.appendErrorTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)}); | 3074 | try astgen.appendErrorTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)}); |
| 3103 | } else if (s.used != 0 and s.discarded != 0) { | 3075 | } else if (s.used != .none and s.discarded != .none) { |
| 3104 | try astgen.appendErrorTokNotes(s.discarded, "pointless discard of {s}", .{@tagName(s.id_cat)}, &[_]u32{ | 3076 | try astgen.appendErrorTokNotes(s.discarded.unwrap().?, "pointless discard of {s}", .{@tagName(s.id_cat)}, &[_]u32{ |
| 3105 | try gz.astgen.errNoteTok(s.used, "used here", .{}), | 3077 | try gz.astgen.errNoteTok(s.used.unwrap().?, "used here", .{}), |
| 3106 | }); | 3078 | }); |
| 3107 | } | 3079 | } |
| 3108 | scope = s.parent; | 3080 | scope = s.parent; |
| 3109 | }, | 3081 | }, |
| 3110 | .local_ptr => { | 3082 | .local_ptr => { |
| 3111 | const s = scope.cast(Scope.LocalPtr).?; | 3083 | const s = scope.cast(Scope.LocalPtr).?; |
| 3112 | if (s.used == 0 and s.discarded == 0) { | 3084 | if (s.used == .none and s.discarded == .none) { |
| 3113 | try astgen.appendErrorTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)}); | 3085 | try astgen.appendErrorTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)}); |
| 3114 | } else { | 3086 | } else { |
| 3115 | if (s.used != 0 and s.discarded != 0) { | 3087 | if (s.used != .none and s.discarded != .none) { |
| 3116 | try astgen.appendErrorTokNotes(s.discarded, "pointless discard of {s}", .{@tagName(s.id_cat)}, &[_]u32{ | 3088 | try astgen.appendErrorTokNotes(s.discarded.unwrap().?, "pointless discard of {s}", .{@tagName(s.id_cat)}, &[_]u32{ |
| 3117 | try astgen.errNoteTok(s.used, "used here", .{}), | 3089 | try astgen.errNoteTok(s.used.unwrap().?, "used here", .{}), |
| 3118 | }); | 3090 | }); |
| 3119 | } | 3091 | } |
| 3120 | if (s.id_cat == .@"local variable" and !s.used_as_lvalue) { | 3092 | if (s.id_cat == .@"local variable" and !s.used_as_lvalue) { |
| ... | @@ -3141,19 +3113,15 @@ fn deferStmt( | ... | @@ -3141,19 +3113,15 @@ fn deferStmt( |
| 3141 | scope_tag: Scope.Tag, | 3113 | scope_tag: Scope.Tag, |
| 3142 | ) InnerError!*Scope { | 3114 | ) InnerError!*Scope { |
| 3143 | var defer_gen = gz.makeSubBlock(scope); | 3115 | var defer_gen = gz.makeSubBlock(scope); |
| 3144 | defer_gen.cur_defer_node = node; | 3116 | defer_gen.cur_defer_node = node.toOptional(); |
| 3145 | defer_gen.any_defer_node = node; | 3117 | defer_gen.any_defer_node = node.toOptional(); |
| 3146 | defer defer_gen.unstack(); | 3118 | defer defer_gen.unstack(); |
| 3147 | 3119 | ||
| 3148 | const tree = gz.astgen.tree; | 3120 | const tree = gz.astgen.tree; |
| 3149 | const node_datas = tree.nodes.items(.data); | ||
| 3150 | const expr_node = node_datas[node].rhs; | ||
| 3151 | |||
| 3152 | const payload_token = node_datas[node].lhs; | ||
| 3153 | var local_val_scope: Scope.LocalVal = undefined; | 3121 | var local_val_scope: Scope.LocalVal = undefined; |
| 3154 | var opt_remapped_err_code: Zir.Inst.OptionalIndex = .none; | 3122 | var opt_remapped_err_code: Zir.Inst.OptionalIndex = .none; |
| 3155 | const have_err_code = scope_tag == .defer_error and payload_token != 0; | 3123 | const sub_scope = if (scope_tag != .defer_error) &defer_gen.base else blk: { |
| 3156 | const sub_scope = if (!have_err_code) &defer_gen.base else blk: { | 3124 | const payload_token = tree.nodeData(node).opt_token_and_node[0].unwrap() orelse break :blk &defer_gen.base; |
| 3157 | const ident_name = try gz.astgen.identAsString(payload_token); | 3125 | const ident_name = try gz.astgen.identAsString(payload_token); |
| 3158 | if (std.mem.eql(u8, tree.tokenSlice(payload_token), "_")) { | 3126 | if (std.mem.eql(u8, tree.tokenSlice(payload_token), "_")) { |
| 3159 | try gz.astgen.appendErrorTok(payload_token, "discard of error capture; omit it instead", .{}); | 3127 | try gz.astgen.appendErrorTok(payload_token, "discard of error capture; omit it instead", .{}); |
| ... | @@ -3181,6 +3149,11 @@ fn deferStmt( | ... | @@ -3181,6 +3149,11 @@ fn deferStmt( |
| 3181 | try gz.addDbgVar(.dbg_var_val, ident_name, remapped_err_code_ref); | 3149 | try gz.addDbgVar(.dbg_var_val, ident_name, remapped_err_code_ref); |
| 3182 | break :blk &local_val_scope.base; | 3150 | break :blk &local_val_scope.base; |
| 3183 | }; | 3151 | }; |
| 3152 | const expr_node = switch (scope_tag) { | ||
| 3153 | .defer_normal => tree.nodeData(node).node, | ||
| 3154 | .defer_error => tree.nodeData(node).opt_token_and_node[1], | ||
| 3155 | else => unreachable, | ||
| 3156 | }; | ||
| 3184 | _ = try unusedResultExpr(&defer_gen, sub_scope, expr_node); | 3157 | _ = try unusedResultExpr(&defer_gen, sub_scope, expr_node); |
| 3185 | try checkUsed(gz, scope, sub_scope); | 3158 | try checkUsed(gz, scope, sub_scope); |
| 3186 | _ = try defer_gen.addBreak(.break_inline, @enumFromInt(0), .void_value); | 3159 | _ = try defer_gen.addBreak(.break_inline, @enumFromInt(0), .void_value); |
| ... | @@ -3215,8 +3188,6 @@ fn varDecl( | ... | @@ -3215,8 +3188,6 @@ fn varDecl( |
| 3215 | try emitDbgNode(gz, node); | 3188 | try emitDbgNode(gz, node); |
| 3216 | const astgen = gz.astgen; | 3189 | const astgen = gz.astgen; |
| 3217 | const tree = astgen.tree; | 3190 | const tree = astgen.tree; |
| 3218 | const token_tags = tree.tokens.items(.tag); | ||
| 3219 | const main_tokens = tree.nodes.items(.main_token); | ||
| 3220 | 3191 | ||
| 3221 | const name_token = var_decl.ast.mut_token + 1; | 3192 | const name_token = var_decl.ast.mut_token + 1; |
| 3222 | const ident_name_raw = tree.tokenSlice(name_token); | 3193 | const ident_name_raw = tree.tokenSlice(name_token); |
| ... | @@ -3230,27 +3201,27 @@ fn varDecl( | ... | @@ -3230,27 +3201,27 @@ fn varDecl( |
| 3230 | ident_name, | 3201 | ident_name, |
| 3231 | name_token, | 3202 | name_token, |
| 3232 | ident_name_raw, | 3203 | ident_name_raw, |
| 3233 | if (token_tags[var_decl.ast.mut_token] == .keyword_const) .@"local constant" else .@"local variable", | 3204 | if (tree.tokenTag(var_decl.ast.mut_token) == .keyword_const) .@"local constant" else .@"local variable", |
| 3234 | ); | 3205 | ); |
| 3235 | 3206 | ||
| 3236 | if (var_decl.ast.init_node == 0) { | 3207 | const init_node = var_decl.ast.init_node.unwrap() orelse { |
| 3237 | return astgen.failNode(node, "variables must be initialized", .{}); | 3208 | return astgen.failNode(node, "variables must be initialized", .{}); |
| 3238 | } | 3209 | }; |
| 3239 | 3210 | ||
| 3240 | if (var_decl.ast.addrspace_node != 0) { | 3211 | if (var_decl.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 3241 | return astgen.failTok(main_tokens[var_decl.ast.addrspace_node], "cannot set address space of local variable '{s}'", .{ident_name_raw}); | 3212 | return astgen.failTok(tree.nodeMainToken(addrspace_node), "cannot set address space of local variable '{s}'", .{ident_name_raw}); |
| 3242 | } | 3213 | } |
| 3243 | 3214 | ||
| 3244 | if (var_decl.ast.section_node != 0) { | 3215 | if (var_decl.ast.section_node.unwrap()) |section_node| { |
| 3245 | return astgen.failTok(main_tokens[var_decl.ast.section_node], "cannot set section of local variable '{s}'", .{ident_name_raw}); | 3216 | return astgen.failTok(tree.nodeMainToken(section_node), "cannot set section of local variable '{s}'", .{ident_name_raw}); |
| 3246 | } | 3217 | } |
| 3247 | 3218 | ||
| 3248 | const align_inst: Zir.Inst.Ref = if (var_decl.ast.align_node != 0) | 3219 | const align_inst: Zir.Inst.Ref = if (var_decl.ast.align_node.unwrap()) |align_node| |
| 3249 | try expr(gz, scope, coerced_align_ri, var_decl.ast.align_node) | 3220 | try expr(gz, scope, coerced_align_ri, align_node) |
| 3250 | else | 3221 | else |
| 3251 | .none; | 3222 | .none; |
| 3252 | 3223 | ||
| 3253 | switch (token_tags[var_decl.ast.mut_token]) { | 3224 | switch (tree.tokenTag(var_decl.ast.mut_token)) { |
| 3254 | .keyword_const => { | 3225 | .keyword_const => { |
| 3255 | if (var_decl.comptime_token) |comptime_token| { | 3226 | if (var_decl.comptime_token) |comptime_token| { |
| 3256 | try astgen.appendErrorTok(comptime_token, "'comptime const' is redundant; instead wrap the initialization expression with 'comptime'", .{}); | 3227 | try astgen.appendErrorTok(comptime_token, "'comptime const' is redundant; instead wrap the initialization expression with 'comptime'", .{}); |
| ... | @@ -3262,25 +3233,24 @@ fn varDecl( | ... | @@ -3262,25 +3233,24 @@ fn varDecl( |
| 3262 | // Depending on the type of AST the initialization expression is, we may need an lvalue | 3233 | // Depending on the type of AST the initialization expression is, we may need an lvalue |
| 3263 | // or an rvalue as a result location. If it is an rvalue, we can use the instruction as | 3234 | // or an rvalue as a result location. If it is an rvalue, we can use the instruction as |
| 3264 | // the variable, no memory location needed. | 3235 | // the variable, no memory location needed. |
| 3265 | const type_node = var_decl.ast.type_node; | ||
| 3266 | if (align_inst == .none and | 3236 | if (align_inst == .none and |
| 3267 | !astgen.nodes_need_rl.contains(node)) | 3237 | !astgen.nodes_need_rl.contains(node)) |
| 3268 | { | 3238 | { |
| 3269 | const result_info: ResultInfo = if (type_node != 0) .{ | 3239 | const result_info: ResultInfo = if (var_decl.ast.type_node.unwrap()) |type_node| .{ |
| 3270 | .rl = .{ .ty = try typeExpr(gz, scope, type_node) }, | 3240 | .rl = .{ .ty = try typeExpr(gz, scope, type_node) }, |
| 3271 | .ctx = .const_init, | 3241 | .ctx = .const_init, |
| 3272 | } else .{ .rl = .none, .ctx = .const_init }; | 3242 | } else .{ .rl = .none, .ctx = .const_init }; |
| 3273 | const prev_anon_name_strategy = gz.anon_name_strategy; | 3243 | const prev_anon_name_strategy = gz.anon_name_strategy; |
| 3274 | gz.anon_name_strategy = .dbg_var; | 3244 | gz.anon_name_strategy = .dbg_var; |
| 3275 | const init_inst = try reachableExprComptime(gz, scope, result_info, var_decl.ast.init_node, node, if (force_comptime) .comptime_keyword else null); | 3245 | const init_inst = try reachableExprComptime(gz, scope, result_info, init_node, node, if (force_comptime) .comptime_keyword else null); |
| 3276 | gz.anon_name_strategy = prev_anon_name_strategy; | 3246 | gz.anon_name_strategy = prev_anon_name_strategy; |
| 3277 | 3247 | ||
| 3278 | _ = try gz.addUnNode(.validate_const, init_inst, var_decl.ast.init_node); | 3248 | _ = try gz.addUnNode(.validate_const, init_inst, init_node); |
| 3279 | try gz.addDbgVar(.dbg_var_val, ident_name, init_inst); | 3249 | try gz.addDbgVar(.dbg_var_val, ident_name, init_inst); |
| 3280 | 3250 | ||
| 3281 | // The const init expression may have modified the error return trace, so signal | 3251 | // The const init expression may have modified the error return trace, so signal |
| 3282 | // to Sema that it should save the new index for restoring later. | 3252 | // to Sema that it should save the new index for restoring later. |
| 3283 | if (nodeMayAppendToErrorTrace(tree, var_decl.ast.init_node)) | 3253 | if (nodeMayAppendToErrorTrace(tree, init_node)) |
| 3284 | _ = try gz.addSaveErrRetIndex(.{ .if_of_error_type = init_inst }); | 3254 | _ = try gz.addSaveErrRetIndex(.{ .if_of_error_type = init_inst }); |
| 3285 | 3255 | ||
| 3286 | const sub_scope = try block_arena.create(Scope.LocalVal); | 3256 | const sub_scope = try block_arena.create(Scope.LocalVal); |
| ... | @@ -3296,9 +3266,9 @@ fn varDecl( | ... | @@ -3296,9 +3266,9 @@ fn varDecl( |
| 3296 | } | 3266 | } |
| 3297 | 3267 | ||
| 3298 | const is_comptime = gz.is_comptime or | 3268 | const is_comptime = gz.is_comptime or |
| 3299 | tree.nodes.items(.tag)[var_decl.ast.init_node] == .@"comptime"; | 3269 | tree.nodeTag(init_node) == .@"comptime"; |
| 3300 | 3270 | ||
| 3301 | const init_rl: ResultInfo.Loc = if (type_node != 0) init_rl: { | 3271 | const init_rl: ResultInfo.Loc = if (var_decl.ast.type_node.unwrap()) |type_node| init_rl: { |
| 3302 | const type_inst = try typeExpr(gz, scope, type_node); | 3272 | const type_inst = try typeExpr(gz, scope, type_node); |
| 3303 | if (align_inst == .none) { | 3273 | if (align_inst == .none) { |
| 3304 | break :init_rl .{ .ptr = .{ .inst = try gz.addUnNode(.alloc, type_inst, node) } }; | 3274 | break :init_rl .{ .ptr = .{ .inst = try gz.addUnNode(.alloc, type_inst, node) } }; |
| ... | @@ -3339,11 +3309,11 @@ fn varDecl( | ... | @@ -3339,11 +3309,11 @@ fn varDecl( |
| 3339 | const prev_anon_name_strategy = gz.anon_name_strategy; | 3309 | const prev_anon_name_strategy = gz.anon_name_strategy; |
| 3340 | gz.anon_name_strategy = .dbg_var; | 3310 | gz.anon_name_strategy = .dbg_var; |
| 3341 | defer gz.anon_name_strategy = prev_anon_name_strategy; | 3311 | defer gz.anon_name_strategy = prev_anon_name_strategy; |
| 3342 | const init_inst = try reachableExprComptime(gz, scope, init_result_info, var_decl.ast.init_node, node, if (force_comptime) .comptime_keyword else null); | 3312 | const init_inst = try reachableExprComptime(gz, scope, init_result_info, init_node, node, if (force_comptime) .comptime_keyword else null); |
| 3343 | 3313 | ||
| 3344 | // The const init expression may have modified the error return trace, so signal | 3314 | // The const init expression may have modified the error return trace, so signal |
| 3345 | // to Sema that it should save the new index for restoring later. | 3315 | // to Sema that it should save the new index for restoring later. |
| 3346 | if (nodeMayAppendToErrorTrace(tree, var_decl.ast.init_node)) | 3316 | if (nodeMayAppendToErrorTrace(tree, init_node)) |
| 3347 | _ = try gz.addSaveErrRetIndex(.{ .if_of_error_type = init_inst }); | 3317 | _ = try gz.addSaveErrRetIndex(.{ .if_of_error_type = init_inst }); |
| 3348 | 3318 | ||
| 3349 | const const_ptr = if (resolve_inferred) | 3319 | const const_ptr = if (resolve_inferred) |
| ... | @@ -3369,8 +3339,8 @@ fn varDecl( | ... | @@ -3369,8 +3339,8 @@ fn varDecl( |
| 3369 | if (var_decl.comptime_token != null and gz.is_comptime) | 3339 | if (var_decl.comptime_token != null and gz.is_comptime) |
| 3370 | return astgen.failTok(var_decl.comptime_token.?, "'comptime var' is redundant in comptime scope", .{}); | 3340 | return astgen.failTok(var_decl.comptime_token.?, "'comptime var' is redundant in comptime scope", .{}); |
| 3371 | const is_comptime = var_decl.comptime_token != null or gz.is_comptime; | 3341 | const is_comptime = var_decl.comptime_token != null or gz.is_comptime; |
| 3372 | const alloc: Zir.Inst.Ref, const resolve_inferred: bool, const result_info: ResultInfo = if (var_decl.ast.type_node != 0) a: { | 3342 | const alloc: Zir.Inst.Ref, const resolve_inferred: bool, const result_info: ResultInfo = if (var_decl.ast.type_node.unwrap()) |type_node| a: { |
| 3373 | const type_inst = try typeExpr(gz, scope, var_decl.ast.type_node); | 3343 | const type_inst = try typeExpr(gz, scope, type_node); |
| 3374 | const alloc = alloc: { | 3344 | const alloc = alloc: { |
| 3375 | if (align_inst == .none) { | 3345 | if (align_inst == .none) { |
| 3376 | const tag: Zir.Inst.Tag = if (is_comptime) | 3346 | const tag: Zir.Inst.Tag = if (is_comptime) |
| ... | @@ -3415,7 +3385,7 @@ fn varDecl( | ... | @@ -3415,7 +3385,7 @@ fn varDecl( |
| 3415 | gz, | 3385 | gz, |
| 3416 | scope, | 3386 | scope, |
| 3417 | result_info, | 3387 | result_info, |
| 3418 | var_decl.ast.init_node, | 3388 | init_node, |
| 3419 | node, | 3389 | node, |
| 3420 | if (var_decl.comptime_token != null) .comptime_keyword else null, | 3390 | if (var_decl.comptime_token != null) .comptime_keyword else null, |
| 3421 | ); | 3391 | ); |
| ... | @@ -3458,15 +3428,11 @@ fn assign(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerError!voi | ... | @@ -3458,15 +3428,11 @@ fn assign(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerError!voi |
| 3458 | try emitDbgNode(gz, infix_node); | 3428 | try emitDbgNode(gz, infix_node); |
| 3459 | const astgen = gz.astgen; | 3429 | const astgen = gz.astgen; |
| 3460 | const tree = astgen.tree; | 3430 | const tree = astgen.tree; |
| 3461 | const node_datas = tree.nodes.items(.data); | ||
| 3462 | const main_tokens = tree.nodes.items(.main_token); | ||
| 3463 | const node_tags = tree.nodes.items(.tag); | ||
| 3464 | 3431 | ||
| 3465 | const lhs = node_datas[infix_node].lhs; | 3432 | const lhs, const rhs = tree.nodeData(infix_node).node_and_node; |
| 3466 | const rhs = node_datas[infix_node].rhs; | 3433 | if (tree.nodeTag(lhs) == .identifier) { |
| 3467 | if (node_tags[lhs] == .identifier) { | ||
| 3468 | // This intentionally does not support `@"_"` syntax. | 3434 | // This intentionally does not support `@"_"` syntax. |
| 3469 | const ident_name = tree.tokenSlice(main_tokens[lhs]); | 3435 | const ident_name = tree.tokenSlice(tree.nodeMainToken(lhs)); |
| 3470 | if (mem.eql(u8, ident_name, "_")) { | 3436 | if (mem.eql(u8, ident_name, "_")) { |
| 3471 | _ = try expr(gz, scope, .{ .rl = .discard, .ctx = .assignment }, rhs); | 3437 | _ = try expr(gz, scope, .{ .rl = .discard, .ctx = .assignment }, rhs); |
| 3472 | return; | 3438 | return; |
| ... | @@ -3484,8 +3450,6 @@ fn assignDestructure(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerErro | ... | @@ -3484,8 +3450,6 @@ fn assignDestructure(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerErro |
| 3484 | try emitDbgNode(gz, node); | 3450 | try emitDbgNode(gz, node); |
| 3485 | const astgen = gz.astgen; | 3451 | const astgen = gz.astgen; |
| 3486 | const tree = astgen.tree; | 3452 | const tree = astgen.tree; |
| 3487 | const main_tokens = tree.nodes.items(.main_token); | ||
| 3488 | const node_tags = tree.nodes.items(.tag); | ||
| 3489 | 3453 | ||
| 3490 | const full = tree.assignDestructure(node); | 3454 | const full = tree.assignDestructure(node); |
| 3491 | if (full.comptime_token != null and gz.is_comptime) { | 3455 | if (full.comptime_token != null and gz.is_comptime) { |
| ... | @@ -3503,9 +3467,9 @@ fn assignDestructure(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerErro | ... | @@ -3503,9 +3467,9 @@ fn assignDestructure(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerErro |
| 3503 | 3467 | ||
| 3504 | const rl_components = try astgen.arena.alloc(ResultInfo.Loc.DestructureComponent, full.ast.variables.len); | 3468 | const rl_components = try astgen.arena.alloc(ResultInfo.Loc.DestructureComponent, full.ast.variables.len); |
| 3505 | for (rl_components, full.ast.variables) |*variable_rl, variable_node| { | 3469 | for (rl_components, full.ast.variables) |*variable_rl, variable_node| { |
| 3506 | if (node_tags[variable_node] == .identifier) { | 3470 | if (tree.nodeTag(variable_node) == .identifier) { |
| 3507 | // This intentionally does not support `@"_"` syntax. | 3471 | // This intentionally does not support `@"_"` syntax. |
| 3508 | const ident_name = tree.tokenSlice(main_tokens[variable_node]); | 3472 | const ident_name = tree.tokenSlice(tree.nodeMainToken(variable_node)); |
| 3509 | if (mem.eql(u8, ident_name, "_")) { | 3473 | if (mem.eql(u8, ident_name, "_")) { |
| 3510 | variable_rl.* = .discard; | 3474 | variable_rl.* = .discard; |
| 3511 | continue; | 3475 | continue; |
| ... | @@ -3542,9 +3506,6 @@ fn assignDestructureMaybeDecls( | ... | @@ -3542,9 +3506,6 @@ fn assignDestructureMaybeDecls( |
| 3542 | try emitDbgNode(gz, node); | 3506 | try emitDbgNode(gz, node); |
| 3543 | const astgen = gz.astgen; | 3507 | const astgen = gz.astgen; |
| 3544 | const tree = astgen.tree; | 3508 | const tree = astgen.tree; |
| 3545 | const token_tags = tree.tokens.items(.tag); | ||
| 3546 | const main_tokens = tree.nodes.items(.main_token); | ||
| 3547 | const node_tags = tree.nodes.items(.tag); | ||
| 3548 | 3509 | ||
| 3549 | const full = tree.assignDestructure(node); | 3510 | const full = tree.assignDestructure(node); |
| 3550 | if (full.comptime_token != null and gz.is_comptime) { | 3511 | if (full.comptime_token != null and gz.is_comptime) { |
| ... | @@ -3552,7 +3513,7 @@ fn assignDestructureMaybeDecls( | ... | @@ -3552,7 +3513,7 @@ fn assignDestructureMaybeDecls( |
| 3552 | } | 3513 | } |
| 3553 | 3514 | ||
| 3554 | const is_comptime = full.comptime_token != null or gz.is_comptime; | 3515 | const is_comptime = full.comptime_token != null or gz.is_comptime; |
| 3555 | const value_is_comptime = node_tags[full.ast.value_expr] == .@"comptime"; | 3516 | const value_is_comptime = tree.nodeTag(full.ast.value_expr) == .@"comptime"; |
| 3556 | 3517 | ||
| 3557 | // When declaring consts via a destructure, we always use a result pointer. | 3518 | // When declaring consts via a destructure, we always use a result pointer. |
| 3558 | // This avoids the need to create tuple types, and is also likely easier to | 3519 | // This avoids the need to create tuple types, and is also likely easier to |
| ... | @@ -3565,10 +3526,10 @@ fn assignDestructureMaybeDecls( | ... | @@ -3565,10 +3526,10 @@ fn assignDestructureMaybeDecls( |
| 3565 | var any_non_const_variables = false; | 3526 | var any_non_const_variables = false; |
| 3566 | var any_lvalue_expr = false; | 3527 | var any_lvalue_expr = false; |
| 3567 | for (rl_components, full.ast.variables) |*variable_rl, variable_node| { | 3528 | for (rl_components, full.ast.variables) |*variable_rl, variable_node| { |
| 3568 | switch (node_tags[variable_node]) { | 3529 | switch (tree.nodeTag(variable_node)) { |
| 3569 | .identifier => { | 3530 | .identifier => { |
| 3570 | // This intentionally does not support `@"_"` syntax. | 3531 | // This intentionally does not support `@"_"` syntax. |
| 3571 | const ident_name = tree.tokenSlice(main_tokens[variable_node]); | 3532 | const ident_name = tree.tokenSlice(tree.nodeMainToken(variable_node)); |
| 3572 | if (mem.eql(u8, ident_name, "_")) { | 3533 | if (mem.eql(u8, ident_name, "_")) { |
| 3573 | any_non_const_variables = true; | 3534 | any_non_const_variables = true; |
| 3574 | variable_rl.* = .discard; | 3535 | variable_rl.* = .discard; |
| ... | @@ -3586,14 +3547,14 @@ fn assignDestructureMaybeDecls( | ... | @@ -3586,14 +3547,14 @@ fn assignDestructureMaybeDecls( |
| 3586 | 3547 | ||
| 3587 | // We detect shadowing in the second pass over these, while we're creating scopes. | 3548 | // We detect shadowing in the second pass over these, while we're creating scopes. |
| 3588 | 3549 | ||
| 3589 | if (full_var_decl.ast.addrspace_node != 0) { | 3550 | if (full_var_decl.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 3590 | return astgen.failTok(main_tokens[full_var_decl.ast.addrspace_node], "cannot set address space of local variable '{s}'", .{ident_name_raw}); | 3551 | return astgen.failTok(tree.nodeMainToken(addrspace_node), "cannot set address space of local variable '{s}'", .{ident_name_raw}); |
| 3591 | } | 3552 | } |
| 3592 | if (full_var_decl.ast.section_node != 0) { | 3553 | if (full_var_decl.ast.section_node.unwrap()) |section_node| { |
| 3593 | return astgen.failTok(main_tokens[full_var_decl.ast.section_node], "cannot set section of local variable '{s}'", .{ident_name_raw}); | 3554 | return astgen.failTok(tree.nodeMainToken(section_node), "cannot set section of local variable '{s}'", .{ident_name_raw}); |
| 3594 | } | 3555 | } |
| 3595 | 3556 | ||
| 3596 | const is_const = switch (token_tags[full_var_decl.ast.mut_token]) { | 3557 | const is_const = switch (tree.tokenTag(full_var_decl.ast.mut_token)) { |
| 3597 | .keyword_var => false, | 3558 | .keyword_var => false, |
| 3598 | .keyword_const => true, | 3559 | .keyword_const => true, |
| 3599 | else => unreachable, | 3560 | else => unreachable, |
| ... | @@ -3603,14 +3564,14 @@ fn assignDestructureMaybeDecls( | ... | @@ -3603,14 +3564,14 @@ fn assignDestructureMaybeDecls( |
| 3603 | // We also mark `const`s as comptime if the RHS is definitely comptime-known. | 3564 | // We also mark `const`s as comptime if the RHS is definitely comptime-known. |
| 3604 | const this_variable_comptime = is_comptime or (is_const and value_is_comptime); | 3565 | const this_variable_comptime = is_comptime or (is_const and value_is_comptime); |
| 3605 | 3566 | ||
| 3606 | const align_inst: Zir.Inst.Ref = if (full_var_decl.ast.align_node != 0) | 3567 | const align_inst: Zir.Inst.Ref = if (full_var_decl.ast.align_node.unwrap()) |align_node| |
| 3607 | try expr(gz, scope, coerced_align_ri, full_var_decl.ast.align_node) | 3568 | try expr(gz, scope, coerced_align_ri, align_node) |
| 3608 | else | 3569 | else |
| 3609 | .none; | 3570 | .none; |
| 3610 | 3571 | ||
| 3611 | if (full_var_decl.ast.type_node != 0) { | 3572 | if (full_var_decl.ast.type_node.unwrap()) |type_node| { |
| 3612 | // Typed alloc | 3573 | // Typed alloc |
| 3613 | const type_inst = try typeExpr(gz, scope, full_var_decl.ast.type_node); | 3574 | const type_inst = try typeExpr(gz, scope, type_node); |
| 3614 | const ptr = if (align_inst == .none) ptr: { | 3575 | const ptr = if (align_inst == .none) ptr: { |
| 3615 | const tag: Zir.Inst.Tag = if (is_const) | 3576 | const tag: Zir.Inst.Tag = if (is_const) |
| 3616 | .alloc | 3577 | .alloc |
| ... | @@ -3679,7 +3640,7 @@ fn assignDestructureMaybeDecls( | ... | @@ -3679,7 +3640,7 @@ fn assignDestructureMaybeDecls( |
| 3679 | // evaluate the lvalues from within the possible block_comptime. | 3640 | // evaluate the lvalues from within the possible block_comptime. |
| 3680 | for (rl_components, full.ast.variables) |*variable_rl, variable_node| { | 3641 | for (rl_components, full.ast.variables) |*variable_rl, variable_node| { |
| 3681 | if (variable_rl.* != .typed_ptr) continue; | 3642 | if (variable_rl.* != .typed_ptr) continue; |
| 3682 | switch (node_tags[variable_node]) { | 3643 | switch (tree.nodeTag(variable_node)) { |
| 3683 | .global_var_decl, .local_var_decl, .simple_var_decl, .aligned_var_decl => continue, | 3644 | .global_var_decl, .local_var_decl, .simple_var_decl, .aligned_var_decl => continue, |
| 3684 | else => {}, | 3645 | else => {}, |
| 3685 | } | 3646 | } |
| ... | @@ -3708,7 +3669,7 @@ fn assignDestructureMaybeDecls( | ... | @@ -3708,7 +3669,7 @@ fn assignDestructureMaybeDecls( |
| 3708 | // If there were any `const` decls, make the pointer constant. | 3669 | // If there were any `const` decls, make the pointer constant. |
| 3709 | var cur_scope = scope; | 3670 | var cur_scope = scope; |
| 3710 | for (rl_components, full.ast.variables) |variable_rl, variable_node| { | 3671 | for (rl_components, full.ast.variables) |variable_rl, variable_node| { |
| 3711 | switch (node_tags[variable_node]) { | 3672 | switch (tree.nodeTag(variable_node)) { |
| 3712 | .local_var_decl, .simple_var_decl, .aligned_var_decl => {}, | 3673 | .local_var_decl, .simple_var_decl, .aligned_var_decl => {}, |
| 3713 | else => continue, // We were mutating an existing lvalue - nothing to do | 3674 | else => continue, // We were mutating an existing lvalue - nothing to do |
| 3714 | } | 3675 | } |
| ... | @@ -3718,7 +3679,7 @@ fn assignDestructureMaybeDecls( | ... | @@ -3718,7 +3679,7 @@ fn assignDestructureMaybeDecls( |
| 3718 | .typed_ptr => |typed_ptr| .{ typed_ptr.inst, false }, | 3679 | .typed_ptr => |typed_ptr| .{ typed_ptr.inst, false }, |
| 3719 | .inferred_ptr => |ptr_inst| .{ ptr_inst, true }, | 3680 | .inferred_ptr => |ptr_inst| .{ ptr_inst, true }, |
| 3720 | }; | 3681 | }; |
| 3721 | const is_const = switch (token_tags[full_var_decl.ast.mut_token]) { | 3682 | const is_const = switch (tree.tokenTag(full_var_decl.ast.mut_token)) { |
| 3722 | .keyword_var => false, | 3683 | .keyword_var => false, |
| 3723 | .keyword_const => true, | 3684 | .keyword_const => true, |
| 3724 | else => unreachable, | 3685 | else => unreachable, |
| ... | @@ -3769,9 +3730,9 @@ fn assignOp( | ... | @@ -3769,9 +3730,9 @@ fn assignOp( |
| 3769 | try emitDbgNode(gz, infix_node); | 3730 | try emitDbgNode(gz, infix_node); |
| 3770 | const astgen = gz.astgen; | 3731 | const astgen = gz.astgen; |
| 3771 | const tree = astgen.tree; | 3732 | const tree = astgen.tree; |
| 3772 | const node_datas = tree.nodes.items(.data); | ||
| 3773 | 3733 | ||
| 3774 | const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs); | 3734 | const lhs_node, const rhs_node = tree.nodeData(infix_node).node_and_node; |
| 3735 | const lhs_ptr = try lvalExpr(gz, scope, lhs_node); | ||
| 3775 | 3736 | ||
| 3776 | const cursor = switch (op_inst_tag) { | 3737 | const cursor = switch (op_inst_tag) { |
| 3777 | .add, .sub, .mul, .div, .mod_rem => maybeAdvanceSourceCursorToMainToken(gz, infix_node), | 3738 | .add, .sub, .mul, .div, .mod_rem => maybeAdvanceSourceCursorToMainToken(gz, infix_node), |
| ... | @@ -3797,7 +3758,7 @@ fn assignOp( | ... | @@ -3797,7 +3758,7 @@ fn assignOp( |
| 3797 | else => try gz.addUnNode(.typeof, lhs, infix_node), // same as LHS type | 3758 | else => try gz.addUnNode(.typeof, lhs, infix_node), // same as LHS type |
| 3798 | }; | 3759 | }; |
| 3799 | // Not `coerced_ty` since `add`/etc won't coerce to this type. | 3760 | // Not `coerced_ty` since `add`/etc won't coerce to this type. |
| 3800 | const rhs = try expr(gz, scope, .{ .rl = .{ .ty = rhs_res_ty } }, node_datas[infix_node].rhs); | 3761 | const rhs = try expr(gz, scope, .{ .rl = .{ .ty = rhs_res_ty } }, rhs_node); |
| 3801 | 3762 | ||
| 3802 | switch (op_inst_tag) { | 3763 | switch (op_inst_tag) { |
| 3803 | .add, .sub, .mul, .div, .mod_rem => { | 3764 | .add, .sub, .mul, .div, .mod_rem => { |
| ... | @@ -3824,12 +3785,12 @@ fn assignShift( | ... | @@ -3824,12 +3785,12 @@ fn assignShift( |
| 3824 | try emitDbgNode(gz, infix_node); | 3785 | try emitDbgNode(gz, infix_node); |
| 3825 | const astgen = gz.astgen; | 3786 | const astgen = gz.astgen; |
| 3826 | const tree = astgen.tree; | 3787 | const tree = astgen.tree; |
| 3827 | const node_datas = tree.nodes.items(.data); | ||
| 3828 | 3788 | ||
| 3829 | const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs); | 3789 | const lhs_node, const rhs_node = tree.nodeData(infix_node).node_and_node; |
| 3790 | const lhs_ptr = try lvalExpr(gz, scope, lhs_node); | ||
| 3830 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); | 3791 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); |
| 3831 | const rhs_type = try gz.addUnNode(.typeof_log2_int_type, lhs, infix_node); | 3792 | const rhs_type = try gz.addUnNode(.typeof_log2_int_type, lhs, infix_node); |
| 3832 | const rhs = try expr(gz, scope, .{ .rl = .{ .ty = rhs_type } }, node_datas[infix_node].rhs); | 3793 | const rhs = try expr(gz, scope, .{ .rl = .{ .ty = rhs_type } }, rhs_node); |
| 3833 | 3794 | ||
| 3834 | const result = try gz.addPlNode(op_inst_tag, infix_node, Zir.Inst.Bin{ | 3795 | const result = try gz.addPlNode(op_inst_tag, infix_node, Zir.Inst.Bin{ |
| 3835 | .lhs = lhs, | 3796 | .lhs = lhs, |
| ... | @@ -3845,12 +3806,12 @@ fn assignShiftSat(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerE | ... | @@ -3845,12 +3806,12 @@ fn assignShiftSat(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerE |
| 3845 | try emitDbgNode(gz, infix_node); | 3806 | try emitDbgNode(gz, infix_node); |
| 3846 | const astgen = gz.astgen; | 3807 | const astgen = gz.astgen; |
| 3847 | const tree = astgen.tree; | 3808 | const tree = astgen.tree; |
| 3848 | const node_datas = tree.nodes.items(.data); | ||
| 3849 | 3809 | ||
| 3850 | const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs); | 3810 | const lhs_node, const rhs_node = tree.nodeData(infix_node).node_and_node; |
| 3811 | const lhs_ptr = try lvalExpr(gz, scope, lhs_node); | ||
| 3851 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); | 3812 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); |
| 3852 | // Saturating shift-left allows any integer type for both the LHS and RHS. | 3813 | // Saturating shift-left allows any integer type for both the LHS and RHS. |
| 3853 | const rhs = try expr(gz, scope, .{ .rl = .none }, node_datas[infix_node].rhs); | 3814 | const rhs = try expr(gz, scope, .{ .rl = .none }, rhs_node); |
| 3854 | 3815 | ||
| 3855 | const result = try gz.addPlNode(.shl_sat, infix_node, Zir.Inst.Bin{ | 3816 | const result = try gz.addPlNode(.shl_sat, infix_node, Zir.Inst.Bin{ |
| 3856 | .lhs = lhs, | 3817 | .lhs = lhs, |
| ... | @@ -3885,7 +3846,7 @@ fn ptrType( | ... | @@ -3885,7 +3846,7 @@ fn ptrType( |
| 3885 | var bit_end_ref: Zir.Inst.Ref = .none; | 3846 | var bit_end_ref: Zir.Inst.Ref = .none; |
| 3886 | var trailing_count: u32 = 0; | 3847 | var trailing_count: u32 = 0; |
| 3887 | 3848 | ||
| 3888 | if (ptr_info.ast.sentinel != 0) { | 3849 | if (ptr_info.ast.sentinel.unwrap()) |sentinel| { |
| 3889 | // These attributes can appear in any order and they all come before the | 3850 | // These attributes can appear in any order and they all come before the |
| 3890 | // element type so we need to reset the source cursor before generating them. | 3851 | // element type so we need to reset the source cursor before generating them. |
| 3891 | gz.astgen.source_offset = source_offset; | 3852 | gz.astgen.source_offset = source_offset; |
| ... | @@ -3896,7 +3857,7 @@ fn ptrType( | ... | @@ -3896,7 +3857,7 @@ fn ptrType( |
| 3896 | gz, | 3857 | gz, |
| 3897 | scope, | 3858 | scope, |
| 3898 | .{ .rl = .{ .ty = elem_type } }, | 3859 | .{ .rl = .{ .ty = elem_type } }, |
| 3899 | ptr_info.ast.sentinel, | 3860 | sentinel, |
| 3900 | switch (ptr_info.size) { | 3861 | switch (ptr_info.size) { |
| 3901 | .slice => .slice_sentinel, | 3862 | .slice => .slice_sentinel, |
| 3902 | else => .pointer_sentinel, | 3863 | else => .pointer_sentinel, |
| ... | @@ -3904,27 +3865,27 @@ fn ptrType( | ... | @@ -3904,27 +3865,27 @@ fn ptrType( |
| 3904 | ); | 3865 | ); |
| 3905 | trailing_count += 1; | 3866 | trailing_count += 1; |
| 3906 | } | 3867 | } |
| 3907 | if (ptr_info.ast.addrspace_node != 0) { | 3868 | if (ptr_info.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 3908 | gz.astgen.source_offset = source_offset; | 3869 | gz.astgen.source_offset = source_offset; |
| 3909 | gz.astgen.source_line = source_line; | 3870 | gz.astgen.source_line = source_line; |
| 3910 | gz.astgen.source_column = source_column; | 3871 | gz.astgen.source_column = source_column; |
| 3911 | 3872 | ||
| 3912 | const addrspace_ty = try gz.addBuiltinValue(ptr_info.ast.addrspace_node, .address_space); | 3873 | const addrspace_ty = try gz.addBuiltinValue(addrspace_node, .address_space); |
| 3913 | addrspace_ref = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = addrspace_ty } }, ptr_info.ast.addrspace_node, .@"addrspace"); | 3874 | addrspace_ref = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = addrspace_ty } }, addrspace_node, .@"addrspace"); |
| 3914 | trailing_count += 1; | 3875 | trailing_count += 1; |
| 3915 | } | 3876 | } |
| 3916 | if (ptr_info.ast.align_node != 0) { | 3877 | if (ptr_info.ast.align_node.unwrap()) |align_node| { |
| 3917 | gz.astgen.source_offset = source_offset; | 3878 | gz.astgen.source_offset = source_offset; |
| 3918 | gz.astgen.source_line = source_line; | 3879 | gz.astgen.source_line = source_line; |
| 3919 | gz.astgen.source_column = source_column; | 3880 | gz.astgen.source_column = source_column; |
| 3920 | 3881 | ||
| 3921 | align_ref = try comptimeExpr(gz, scope, coerced_align_ri, ptr_info.ast.align_node, .@"align"); | 3882 | align_ref = try comptimeExpr(gz, scope, coerced_align_ri, align_node, .@"align"); |
| 3922 | trailing_count += 1; | 3883 | trailing_count += 1; |
| 3923 | } | 3884 | } |
| 3924 | if (ptr_info.ast.bit_range_start != 0) { | 3885 | if (ptr_info.ast.bit_range_start.unwrap()) |bit_range_start| { |
| 3925 | assert(ptr_info.ast.bit_range_end != 0); | 3886 | const bit_range_end = ptr_info.ast.bit_range_end.unwrap().?; |
| 3926 | bit_start_ref = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, ptr_info.ast.bit_range_start, .type); | 3887 | bit_start_ref = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, bit_range_start, .type); |
| 3927 | bit_end_ref = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, ptr_info.ast.bit_range_end, .type); | 3888 | bit_end_ref = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, bit_range_end, .type); |
| 3928 | trailing_count += 2; | 3889 | trailing_count += 2; |
| 3929 | } | 3890 | } |
| 3930 | 3891 | ||
| ... | @@ -3977,18 +3938,15 @@ fn ptrType( | ... | @@ -3977,18 +3938,15 @@ fn ptrType( |
| 3977 | fn arrayType(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) !Zir.Inst.Ref { | 3938 | fn arrayType(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) !Zir.Inst.Ref { |
| 3978 | const astgen = gz.astgen; | 3939 | const astgen = gz.astgen; |
| 3979 | const tree = astgen.tree; | 3940 | const tree = astgen.tree; |
| 3980 | const node_datas = tree.nodes.items(.data); | ||
| 3981 | const node_tags = tree.nodes.items(.tag); | ||
| 3982 | const main_tokens = tree.nodes.items(.main_token); | ||
| 3983 | 3941 | ||
| 3984 | const len_node = node_datas[node].lhs; | 3942 | const len_node, const elem_type_node = tree.nodeData(node).node_and_node; |
| 3985 | if (node_tags[len_node] == .identifier and | 3943 | if (tree.nodeTag(len_node) == .identifier and |
| 3986 | mem.eql(u8, tree.tokenSlice(main_tokens[len_node]), "_")) | 3944 | mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(len_node)), "_")) |
| 3987 | { | 3945 | { |
| 3988 | return astgen.failNode(len_node, "unable to infer array size", .{}); | 3946 | return astgen.failNode(len_node, "unable to infer array size", .{}); |
| 3989 | } | 3947 | } |
| 3990 | const len = try reachableExprComptime(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, len_node, node, .type); | 3948 | const len = try reachableExprComptime(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, len_node, node, .type); |
| 3991 | const elem_type = try typeExpr(gz, scope, node_datas[node].rhs); | 3949 | const elem_type = try typeExpr(gz, scope, elem_type_node); |
| 3992 | 3950 | ||
| 3993 | const result = try gz.addPlNode(.array_type, node, Zir.Inst.Bin{ | 3951 | const result = try gz.addPlNode(.array_type, node, Zir.Inst.Bin{ |
| 3994 | .lhs = len, | 3952 | .lhs = len, |
| ... | @@ -4000,14 +3958,12 @@ fn arrayType(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) ! | ... | @@ -4000,14 +3958,12 @@ fn arrayType(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) ! |
| 4000 | fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) !Zir.Inst.Ref { | 3958 | fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) !Zir.Inst.Ref { |
| 4001 | const astgen = gz.astgen; | 3959 | const astgen = gz.astgen; |
| 4002 | const tree = astgen.tree; | 3960 | const tree = astgen.tree; |
| 4003 | const node_datas = tree.nodes.items(.data); | 3961 | |
| 4004 | const node_tags = tree.nodes.items(.tag); | 3962 | const len_node, const extra_index = tree.nodeData(node).node_and_extra; |
| 4005 | const main_tokens = tree.nodes.items(.main_token); | 3963 | const extra = tree.extraData(extra_index, Ast.Node.ArrayTypeSentinel); |
| 4006 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.ArrayTypeSentinel); | 3964 | |
| 4007 | 3965 | if (tree.nodeTag(len_node) == .identifier and | |
| 4008 | const len_node = node_datas[node].lhs; | 3966 | mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(len_node)), "_")) |
| 4009 | if (node_tags[len_node] == .identifier and | ||
| 4010 | mem.eql(u8, tree.tokenSlice(main_tokens[len_node]), "_")) | ||
| 4011 | { | 3967 | { |
| 4012 | return astgen.failNode(len_node, "unable to infer array size", .{}); | 3968 | return astgen.failNode(len_node, "unable to infer array size", .{}); |
| 4013 | } | 3969 | } |
| ... | @@ -4107,11 +4063,10 @@ fn fnDecl( | ... | @@ -4107,11 +4063,10 @@ fn fnDecl( |
| 4107 | scope: *Scope, | 4063 | scope: *Scope, |
| 4108 | wip_members: *WipMembers, | 4064 | wip_members: *WipMembers, |
| 4109 | decl_node: Ast.Node.Index, | 4065 | decl_node: Ast.Node.Index, |
| 4110 | body_node: Ast.Node.Index, | 4066 | body_node: Ast.Node.OptionalIndex, |
| 4111 | fn_proto: Ast.full.FnProto, | 4067 | fn_proto: Ast.full.FnProto, |
| 4112 | ) InnerError!void { | 4068 | ) InnerError!void { |
| 4113 | const tree = astgen.tree; | 4069 | const tree = astgen.tree; |
| 4114 | const token_tags = tree.tokens.items(.tag); | ||
| 4115 | 4070 | ||
| 4116 | const old_hasher = astgen.src_hasher; | 4071 | const old_hasher = astgen.src_hasher; |
| 4117 | defer astgen.src_hasher = old_hasher; | 4072 | defer astgen.src_hasher = old_hasher; |
| ... | @@ -4140,15 +4095,15 @@ fn fnDecl( | ... | @@ -4140,15 +4095,15 @@ fn fnDecl( |
| 4140 | const is_pub = fn_proto.visib_token != null; | 4095 | const is_pub = fn_proto.visib_token != null; |
| 4141 | const is_export = blk: { | 4096 | const is_export = blk: { |
| 4142 | const maybe_export_token = fn_proto.extern_export_inline_token orelse break :blk false; | 4097 | const maybe_export_token = fn_proto.extern_export_inline_token orelse break :blk false; |
| 4143 | break :blk token_tags[maybe_export_token] == .keyword_export; | 4098 | break :blk tree.tokenTag(maybe_export_token) == .keyword_export; |
| 4144 | }; | 4099 | }; |
| 4145 | const is_extern = blk: { | 4100 | const is_extern = blk: { |
| 4146 | const maybe_extern_token = fn_proto.extern_export_inline_token orelse break :blk false; | 4101 | const maybe_extern_token = fn_proto.extern_export_inline_token orelse break :blk false; |
| 4147 | break :blk token_tags[maybe_extern_token] == .keyword_extern; | 4102 | break :blk tree.tokenTag(maybe_extern_token) == .keyword_extern; |
| 4148 | }; | 4103 | }; |
| 4149 | const has_inline_keyword = blk: { | 4104 | const has_inline_keyword = blk: { |
| 4150 | const maybe_inline_token = fn_proto.extern_export_inline_token orelse break :blk false; | 4105 | const maybe_inline_token = fn_proto.extern_export_inline_token orelse break :blk false; |
| 4151 | break :blk token_tags[maybe_inline_token] == .keyword_inline; | 4106 | break :blk tree.tokenTag(maybe_inline_token) == .keyword_inline; |
| 4152 | }; | 4107 | }; |
| 4153 | const lib_name = if (fn_proto.lib_name) |lib_name_token| blk: { | 4108 | const lib_name = if (fn_proto.lib_name) |lib_name_token| blk: { |
| 4154 | const lib_name_str = try astgen.strLitAsString(lib_name_token); | 4109 | const lib_name_str = try astgen.strLitAsString(lib_name_token); |
| ... | @@ -4160,16 +4115,18 @@ fn fnDecl( | ... | @@ -4160,16 +4115,18 @@ fn fnDecl( |
| 4160 | } | 4115 | } |
| 4161 | break :blk lib_name_str.index; | 4116 | break :blk lib_name_str.index; |
| 4162 | } else .empty; | 4117 | } else .empty; |
| 4163 | if (fn_proto.ast.callconv_expr != 0 and has_inline_keyword) { | 4118 | if (fn_proto.ast.callconv_expr != .none and has_inline_keyword) { |
| 4164 | return astgen.failNode( | 4119 | return astgen.failNode( |
| 4165 | fn_proto.ast.callconv_expr, | 4120 | fn_proto.ast.callconv_expr.unwrap().?, |
| 4166 | "explicit callconv incompatible with inline keyword", | 4121 | "explicit callconv incompatible with inline keyword", |
| 4167 | .{}, | 4122 | .{}, |
| 4168 | ); | 4123 | ); |
| 4169 | } | 4124 | } |
| 4170 | const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1; | 4125 | |
| 4171 | const is_inferred_error = token_tags[maybe_bang] == .bang; | 4126 | const return_type = fn_proto.ast.return_type.unwrap().?; |
| 4172 | if (body_node == 0) { | 4127 | const maybe_bang = tree.firstToken(return_type) - 1; |
| 4128 | const is_inferred_error = tree.tokenTag(maybe_bang) == .bang; | ||
| 4129 | if (body_node == .none) { | ||
| 4173 | if (!is_extern) { | 4130 | if (!is_extern) { |
| 4174 | return astgen.failTok(fn_proto.ast.fn_token, "non-extern function has no body", .{}); | 4131 | return astgen.failTok(fn_proto.ast.fn_token, "non-extern function has no body", .{}); |
| 4175 | } | 4132 | } |
| ... | @@ -4202,28 +4159,28 @@ fn fnDecl( | ... | @@ -4202,28 +4159,28 @@ fn fnDecl( |
| 4202 | var align_gz = type_gz.makeSubBlock(scope); | 4159 | var align_gz = type_gz.makeSubBlock(scope); |
| 4203 | defer align_gz.unstack(); | 4160 | defer align_gz.unstack(); |
| 4204 | 4161 | ||
| 4205 | if (fn_proto.ast.align_expr != 0) { | 4162 | if (fn_proto.ast.align_expr.unwrap()) |align_expr| { |
| 4206 | astgen.restoreSourceCursor(saved_cursor); | 4163 | astgen.restoreSourceCursor(saved_cursor); |
| 4207 | const inst = try expr(&align_gz, &align_gz.base, coerced_align_ri, fn_proto.ast.align_expr); | 4164 | const inst = try expr(&align_gz, &align_gz.base, coerced_align_ri, align_expr); |
| 4208 | _ = try align_gz.addBreakWithSrcNode(.break_inline, decl_inst, inst, decl_node); | 4165 | _ = try align_gz.addBreakWithSrcNode(.break_inline, decl_inst, inst, decl_node); |
| 4209 | } | 4166 | } |
| 4210 | 4167 | ||
| 4211 | var linksection_gz = align_gz.makeSubBlock(scope); | 4168 | var linksection_gz = align_gz.makeSubBlock(scope); |
| 4212 | defer linksection_gz.unstack(); | 4169 | defer linksection_gz.unstack(); |
| 4213 | 4170 | ||
| 4214 | if (fn_proto.ast.section_expr != 0) { | 4171 | if (fn_proto.ast.section_expr.unwrap()) |section_expr| { |
| 4215 | astgen.restoreSourceCursor(saved_cursor); | 4172 | astgen.restoreSourceCursor(saved_cursor); |
| 4216 | const inst = try expr(&linksection_gz, &linksection_gz.base, coerced_linksection_ri, fn_proto.ast.section_expr); | 4173 | const inst = try expr(&linksection_gz, &linksection_gz.base, coerced_linksection_ri, section_expr); |
| 4217 | _ = try linksection_gz.addBreakWithSrcNode(.break_inline, decl_inst, inst, decl_node); | 4174 | _ = try linksection_gz.addBreakWithSrcNode(.break_inline, decl_inst, inst, decl_node); |
| 4218 | } | 4175 | } |
| 4219 | 4176 | ||
| 4220 | var addrspace_gz = linksection_gz.makeSubBlock(scope); | 4177 | var addrspace_gz = linksection_gz.makeSubBlock(scope); |
| 4221 | defer addrspace_gz.unstack(); | 4178 | defer addrspace_gz.unstack(); |
| 4222 | 4179 | ||
| 4223 | if (fn_proto.ast.addrspace_expr != 0) { | 4180 | if (fn_proto.ast.addrspace_expr.unwrap()) |addrspace_expr| { |
| 4224 | astgen.restoreSourceCursor(saved_cursor); | 4181 | astgen.restoreSourceCursor(saved_cursor); |
| 4225 | const addrspace_ty = try addrspace_gz.addBuiltinValue(fn_proto.ast.addrspace_expr, .address_space); | 4182 | const addrspace_ty = try addrspace_gz.addBuiltinValue(addrspace_expr, .address_space); |
| 4226 | const inst = try expr(&addrspace_gz, &addrspace_gz.base, .{ .rl = .{ .coerced_ty = addrspace_ty } }, fn_proto.ast.addrspace_expr); | 4183 | const inst = try expr(&addrspace_gz, &addrspace_gz.base, .{ .rl = .{ .coerced_ty = addrspace_ty } }, addrspace_expr); |
| 4227 | _ = try addrspace_gz.addBreakWithSrcNode(.break_inline, decl_inst, inst, decl_node); | 4184 | _ = try addrspace_gz.addBreakWithSrcNode(.break_inline, decl_inst, inst, decl_node); |
| 4228 | } | 4185 | } |
| 4229 | 4186 | ||
| ... | @@ -4233,7 +4190,7 @@ fn fnDecl( | ... | @@ -4233,7 +4190,7 @@ fn fnDecl( |
| 4233 | if (!is_extern) { | 4190 | if (!is_extern) { |
| 4234 | // We include a function *value*, not a type. | 4191 | // We include a function *value*, not a type. |
| 4235 | astgen.restoreSourceCursor(saved_cursor); | 4192 | astgen.restoreSourceCursor(saved_cursor); |
| 4236 | try astgen.fnDeclInner(&value_gz, &value_gz.base, saved_cursor, decl_inst, decl_node, body_node, fn_proto); | 4193 | try astgen.fnDeclInner(&value_gz, &value_gz.base, saved_cursor, decl_inst, decl_node, body_node.unwrap().?, fn_proto); |
| 4237 | } | 4194 | } |
| 4238 | 4195 | ||
| 4239 | // *Now* we can incorporate the full source code into the hasher. | 4196 | // *Now* we can incorporate the full source code into the hasher. |
| ... | @@ -4272,18 +4229,19 @@ fn fnDeclInner( | ... | @@ -4272,18 +4229,19 @@ fn fnDeclInner( |
| 4272 | fn_proto: Ast.full.FnProto, | 4229 | fn_proto: Ast.full.FnProto, |
| 4273 | ) InnerError!void { | 4230 | ) InnerError!void { |
| 4274 | const tree = astgen.tree; | 4231 | const tree = astgen.tree; |
| 4275 | const token_tags = tree.tokens.items(.tag); | ||
| 4276 | 4232 | ||
| 4277 | const is_noinline = blk: { | 4233 | const is_noinline = blk: { |
| 4278 | const maybe_noinline_token = fn_proto.extern_export_inline_token orelse break :blk false; | 4234 | const maybe_noinline_token = fn_proto.extern_export_inline_token orelse break :blk false; |
| 4279 | break :blk token_tags[maybe_noinline_token] == .keyword_noinline; | 4235 | break :blk tree.tokenTag(maybe_noinline_token) == .keyword_noinline; |
| 4280 | }; | 4236 | }; |
| 4281 | const has_inline_keyword = blk: { | 4237 | const has_inline_keyword = blk: { |
| 4282 | const maybe_inline_token = fn_proto.extern_export_inline_token orelse break :blk false; | 4238 | const maybe_inline_token = fn_proto.extern_export_inline_token orelse break :blk false; |
| 4283 | break :blk token_tags[maybe_inline_token] == .keyword_inline; | 4239 | break :blk tree.tokenTag(maybe_inline_token) == .keyword_inline; |
| 4284 | }; | 4240 | }; |
| 4285 | const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1; | 4241 | |
| 4286 | const is_inferred_error = token_tags[maybe_bang] == .bang; | 4242 | const return_type = fn_proto.ast.return_type.unwrap().?; |
| 4243 | const maybe_bang = tree.firstToken(return_type) - 1; | ||
| 4244 | const is_inferred_error = tree.tokenTag(maybe_bang) == .bang; | ||
| 4287 | 4245 | ||
| 4288 | // Note that the capacity here may not be sufficient, as this does not include `anytype` parameters. | 4246 | // Note that the capacity here may not be sufficient, as this does not include `anytype` parameters. |
| 4289 | var param_insts: std.ArrayListUnmanaged(Zir.Inst.Index) = try .initCapacity(astgen.arena, fn_proto.ast.params.len); | 4247 | var param_insts: std.ArrayListUnmanaged(Zir.Inst.Index) = try .initCapacity(astgen.arena, fn_proto.ast.params.len); |
| ... | @@ -4297,7 +4255,7 @@ fn fnDeclInner( | ... | @@ -4297,7 +4255,7 @@ fn fnDeclInner( |
| 4297 | var param_type_i: usize = 0; | 4255 | var param_type_i: usize = 0; |
| 4298 | var it = fn_proto.iterate(tree); | 4256 | var it = fn_proto.iterate(tree); |
| 4299 | while (it.next()) |param| : (param_type_i += 1) { | 4257 | while (it.next()) |param| : (param_type_i += 1) { |
| 4300 | const is_comptime = if (param.comptime_noalias) |token| switch (token_tags[token]) { | 4258 | const is_comptime = if (param.comptime_noalias) |token| switch (tree.tokenTag(token)) { |
| 4301 | .keyword_noalias => is_comptime: { | 4259 | .keyword_noalias => is_comptime: { |
| 4302 | noalias_bits |= @as(u32, 1) << (std.math.cast(u5, param_type_i) orelse | 4260 | noalias_bits |= @as(u32, 1) << (std.math.cast(u5, param_type_i) orelse |
| 4303 | return astgen.failTok(token, "this compiler implementation only supports 'noalias' on the first 32 parameters", .{})); | 4261 | return astgen.failTok(token, "this compiler implementation only supports 'noalias' on the first 32 parameters", .{})); |
| ... | @@ -4308,7 +4266,7 @@ fn fnDeclInner( | ... | @@ -4308,7 +4266,7 @@ fn fnDeclInner( |
| 4308 | } else false; | 4266 | } else false; |
| 4309 | 4267 | ||
| 4310 | const is_anytype = if (param.anytype_ellipsis3) |token| blk: { | 4268 | const is_anytype = if (param.anytype_ellipsis3) |token| blk: { |
| 4311 | switch (token_tags[token]) { | 4269 | switch (tree.tokenTag(token)) { |
| 4312 | .keyword_anytype => break :blk true, | 4270 | .keyword_anytype => break :blk true, |
| 4313 | .ellipsis3 => break :is_var_args true, | 4271 | .ellipsis3 => break :is_var_args true, |
| 4314 | else => unreachable, | 4272 | else => unreachable, |
| ... | @@ -4327,30 +4285,31 @@ fn fnDeclInner( | ... | @@ -4327,30 +4285,31 @@ fn fnDeclInner( |
| 4327 | if (param.anytype_ellipsis3) |tok| { | 4285 | if (param.anytype_ellipsis3) |tok| { |
| 4328 | return astgen.failTok(tok, "missing parameter name", .{}); | 4286 | return astgen.failTok(tok, "missing parameter name", .{}); |
| 4329 | } else { | 4287 | } else { |
| 4288 | const type_expr = param.type_expr.?; | ||
| 4330 | ambiguous: { | 4289 | ambiguous: { |
| 4331 | if (tree.nodes.items(.tag)[param.type_expr] != .identifier) break :ambiguous; | 4290 | if (tree.nodeTag(type_expr) != .identifier) break :ambiguous; |
| 4332 | const main_token = tree.nodes.items(.main_token)[param.type_expr]; | 4291 | const main_token = tree.nodeMainToken(type_expr); |
| 4333 | const identifier_str = tree.tokenSlice(main_token); | 4292 | const identifier_str = tree.tokenSlice(main_token); |
| 4334 | if (isPrimitive(identifier_str)) break :ambiguous; | 4293 | if (isPrimitive(identifier_str)) break :ambiguous; |
| 4335 | return astgen.failNodeNotes( | 4294 | return astgen.failNodeNotes( |
| 4336 | param.type_expr, | 4295 | type_expr, |
| 4337 | "missing parameter name or type", | 4296 | "missing parameter name or type", |
| 4338 | .{}, | 4297 | .{}, |
| 4339 | &[_]u32{ | 4298 | &[_]u32{ |
| 4340 | try astgen.errNoteNode( | 4299 | try astgen.errNoteNode( |
| 4341 | param.type_expr, | 4300 | type_expr, |
| 4342 | "if this is a name, annotate its type '{s}: T'", | 4301 | "if this is a name, annotate its type '{s}: T'", |
| 4343 | .{identifier_str}, | 4302 | .{identifier_str}, |
| 4344 | ), | 4303 | ), |
| 4345 | try astgen.errNoteNode( | 4304 | try astgen.errNoteNode( |
| 4346 | param.type_expr, | 4305 | type_expr, |
| 4347 | "if this is a type, give it a name '<name>: {s}'", | 4306 | "if this is a type, give it a name '<name>: {s}'", |
| 4348 | .{identifier_str}, | 4307 | .{identifier_str}, |
| 4349 | ), | 4308 | ), |
| 4350 | }, | 4309 | }, |
| 4351 | ); | 4310 | ); |
| 4352 | } | 4311 | } |
| 4353 | return astgen.failNode(param.type_expr, "missing parameter name", .{}); | 4312 | return astgen.failNode(type_expr, "missing parameter name", .{}); |
| 4354 | } | 4313 | } |
| 4355 | }; | 4314 | }; |
| 4356 | 4315 | ||
| ... | @@ -4362,8 +4321,7 @@ fn fnDeclInner( | ... | @@ -4362,8 +4321,7 @@ fn fnDeclInner( |
| 4362 | .param_anytype; | 4321 | .param_anytype; |
| 4363 | break :param try decl_gz.addStrTok(tag, param_name, name_token); | 4322 | break :param try decl_gz.addStrTok(tag, param_name, name_token); |
| 4364 | } else param: { | 4323 | } else param: { |
| 4365 | const param_type_node = param.type_expr; | 4324 | const param_type_node = param.type_expr.?; |
| 4366 | assert(param_type_node != 0); | ||
| 4367 | any_param_used = false; // we will check this later | 4325 | any_param_used = false; // we will check this later |
| 4368 | var param_gz = decl_gz.makeSubBlock(scope); | 4326 | var param_gz = decl_gz.makeSubBlock(scope); |
| 4369 | defer param_gz.unstack(); | 4327 | defer param_gz.unstack(); |
| ... | @@ -4372,8 +4330,7 @@ fn fnDeclInner( | ... | @@ -4372,8 +4330,7 @@ fn fnDeclInner( |
| 4372 | _ = try param_gz.addBreakWithSrcNode(.break_inline, param_inst_expected, param_type, param_type_node); | 4330 | _ = try param_gz.addBreakWithSrcNode(.break_inline, param_inst_expected, param_type, param_type_node); |
| 4373 | const param_type_is_generic = any_param_used; | 4331 | const param_type_is_generic = any_param_used; |
| 4374 | 4332 | ||
| 4375 | const main_tokens = tree.nodes.items(.main_token); | 4333 | const name_token = param.name_token orelse tree.nodeMainToken(param_type_node); |
| 4376 | const name_token = param.name_token orelse main_tokens[param_type_node]; | ||
| 4377 | const tag: Zir.Inst.Tag = if (is_comptime) .param_comptime else .param; | 4334 | const tag: Zir.Inst.Tag = if (is_comptime) .param_comptime else .param; |
| 4378 | const param_inst = try decl_gz.addParam(&param_gz, param_insts.items, param_type_is_generic, tag, name_token, param_name); | 4335 | const param_inst = try decl_gz.addParam(&param_gz, param_insts.items, param_type_is_generic, tag, name_token, param_name); |
| 4379 | assert(param_inst_expected == param_inst); | 4336 | assert(param_inst_expected == param_inst); |
| ... | @@ -4409,7 +4366,7 @@ fn fnDeclInner( | ... | @@ -4409,7 +4366,7 @@ fn fnDeclInner( |
| 4409 | // Parameters are in scope for the return type, so we use `params_scope` here. | 4366 | // Parameters are in scope for the return type, so we use `params_scope` here. |
| 4410 | // The calling convention will not have parameters in scope, so we'll just use `scope`. | 4367 | // The calling convention will not have parameters in scope, so we'll just use `scope`. |
| 4411 | // See #22263 for a proposal to solve the inconsistency here. | 4368 | // See #22263 for a proposal to solve the inconsistency here. |
| 4412 | const inst = try fullBodyExpr(&ret_gz, params_scope, coerced_type_ri, fn_proto.ast.return_type, .normal); | 4369 | const inst = try fullBodyExpr(&ret_gz, params_scope, coerced_type_ri, fn_proto.ast.return_type.unwrap().?, .normal); |
| 4413 | if (ret_gz.instructionsSlice().len == 0) { | 4370 | if (ret_gz.instructionsSlice().len == 0) { |
| 4414 | // In this case we will send a len=0 body which can be encoded more efficiently. | 4371 | // In this case we will send a len=0 body which can be encoded more efficiently. |
| 4415 | break :inst inst; | 4372 | break :inst inst; |
| ... | @@ -4426,12 +4383,12 @@ fn fnDeclInner( | ... | @@ -4426,12 +4383,12 @@ fn fnDeclInner( |
| 4426 | var cc_gz = decl_gz.makeSubBlock(scope); | 4383 | var cc_gz = decl_gz.makeSubBlock(scope); |
| 4427 | defer cc_gz.unstack(); | 4384 | defer cc_gz.unstack(); |
| 4428 | const cc_ref: Zir.Inst.Ref = blk: { | 4385 | const cc_ref: Zir.Inst.Ref = blk: { |
| 4429 | if (fn_proto.ast.callconv_expr != 0) { | 4386 | if (fn_proto.ast.callconv_expr.unwrap()) |callconv_expr| { |
| 4430 | const inst = try expr( | 4387 | const inst = try expr( |
| 4431 | &cc_gz, | 4388 | &cc_gz, |
| 4432 | scope, | 4389 | scope, |
| 4433 | .{ .rl = .{ .coerced_ty = try cc_gz.addBuiltinValue(fn_proto.ast.callconv_expr, .calling_convention) } }, | 4390 | .{ .rl = .{ .coerced_ty = try cc_gz.addBuiltinValue(callconv_expr, .calling_convention) } }, |
| 4434 | fn_proto.ast.callconv_expr, | 4391 | callconv_expr, |
| 4435 | ); | 4392 | ); |
| 4436 | if (cc_gz.instructionsSlice().len == 0) { | 4393 | if (cc_gz.instructionsSlice().len == 0) { |
| 4437 | // In this case we will send a len=0 body which can be encoded more efficiently. | 4394 | // In this case we will send a len=0 body which can be encoded more efficiently. |
| ... | @@ -4470,7 +4427,7 @@ fn fnDeclInner( | ... | @@ -4470,7 +4427,7 @@ fn fnDeclInner( |
| 4470 | // Leave `astgen.src_hasher` unmodified; this will be used for hashing | 4427 | // Leave `astgen.src_hasher` unmodified; this will be used for hashing |
| 4471 | // the *whole* function declaration, including its body. | 4428 | // the *whole* function declaration, including its body. |
| 4472 | var proto_hasher = astgen.src_hasher; | 4429 | var proto_hasher = astgen.src_hasher; |
| 4473 | const proto_node = tree.nodes.items(.data)[decl_node].lhs; | 4430 | const proto_node = tree.nodeData(decl_node).node_and_node[0]; |
| 4474 | proto_hasher.update(tree.getNodeSource(proto_node)); | 4431 | proto_hasher.update(tree.getNodeSource(proto_node)); |
| 4475 | var proto_hash: std.zig.SrcHash = undefined; | 4432 | var proto_hash: std.zig.SrcHash = undefined; |
| 4476 | proto_hasher.final(&proto_hash); | 4433 | proto_hasher.final(&proto_hash); |
| ... | @@ -4540,7 +4497,6 @@ fn globalVarDecl( | ... | @@ -4540,7 +4497,6 @@ fn globalVarDecl( |
| 4540 | var_decl: Ast.full.VarDecl, | 4497 | var_decl: Ast.full.VarDecl, |
| 4541 | ) InnerError!void { | 4498 | ) InnerError!void { |
| 4542 | const tree = astgen.tree; | 4499 | const tree = astgen.tree; |
| 4543 | const token_tags = tree.tokens.items(.tag); | ||
| 4544 | 4500 | ||
| 4545 | const old_hasher = astgen.src_hasher; | 4501 | const old_hasher = astgen.src_hasher; |
| 4546 | defer astgen.src_hasher = old_hasher; | 4502 | defer astgen.src_hasher = old_hasher; |
| ... | @@ -4548,16 +4504,16 @@ fn globalVarDecl( | ... | @@ -4548,16 +4504,16 @@ fn globalVarDecl( |
| 4548 | astgen.src_hasher.update(tree.getNodeSource(node)); | 4504 | astgen.src_hasher.update(tree.getNodeSource(node)); |
| 4549 | astgen.src_hasher.update(std.mem.asBytes(&astgen.source_column)); | 4505 | astgen.src_hasher.update(std.mem.asBytes(&astgen.source_column)); |
| 4550 | 4506 | ||
| 4551 | const is_mutable = token_tags[var_decl.ast.mut_token] == .keyword_var; | 4507 | const is_mutable = tree.tokenTag(var_decl.ast.mut_token) == .keyword_var; |
| 4552 | const name_token = var_decl.ast.mut_token + 1; | 4508 | const name_token = var_decl.ast.mut_token + 1; |
| 4553 | const is_pub = var_decl.visib_token != null; | 4509 | const is_pub = var_decl.visib_token != null; |
| 4554 | const is_export = blk: { | 4510 | const is_export = blk: { |
| 4555 | const maybe_export_token = var_decl.extern_export_token orelse break :blk false; | 4511 | const maybe_export_token = var_decl.extern_export_token orelse break :blk false; |
| 4556 | break :blk token_tags[maybe_export_token] == .keyword_export; | 4512 | break :blk tree.tokenTag(maybe_export_token) == .keyword_export; |
| 4557 | }; | 4513 | }; |
| 4558 | const is_extern = blk: { | 4514 | const is_extern = blk: { |
| 4559 | const maybe_extern_token = var_decl.extern_export_token orelse break :blk false; | 4515 | const maybe_extern_token = var_decl.extern_export_token orelse break :blk false; |
| 4560 | break :blk token_tags[maybe_extern_token] == .keyword_extern; | 4516 | break :blk tree.tokenTag(maybe_extern_token) == .keyword_extern; |
| 4561 | }; | 4517 | }; |
| 4562 | const is_threadlocal = if (var_decl.threadlocal_token) |tok| blk: { | 4518 | const is_threadlocal = if (var_decl.threadlocal_token) |tok| blk: { |
| 4563 | if (!is_mutable) { | 4519 | if (!is_mutable) { |
| ... | @@ -4583,10 +4539,10 @@ fn globalVarDecl( | ... | @@ -4583,10 +4539,10 @@ fn globalVarDecl( |
| 4583 | const decl_inst = try gz.makeDeclaration(node); | 4539 | const decl_inst = try gz.makeDeclaration(node); |
| 4584 | wip_members.nextDecl(decl_inst); | 4540 | wip_members.nextDecl(decl_inst); |
| 4585 | 4541 | ||
| 4586 | if (var_decl.ast.init_node != 0) { | 4542 | if (var_decl.ast.init_node.unwrap()) |init_node| { |
| 4587 | if (is_extern) { | 4543 | if (is_extern) { |
| 4588 | return astgen.failNode( | 4544 | return astgen.failNode( |
| 4589 | var_decl.ast.init_node, | 4545 | init_node, |
| 4590 | "extern variables have no initializers", | 4546 | "extern variables have no initializers", |
| 4591 | .{}, | 4547 | .{}, |
| 4592 | ); | 4548 | ); |
| ... | @@ -4597,7 +4553,7 @@ fn globalVarDecl( | ... | @@ -4597,7 +4553,7 @@ fn globalVarDecl( |
| 4597 | } | 4553 | } |
| 4598 | } | 4554 | } |
| 4599 | 4555 | ||
| 4600 | if (is_extern and var_decl.ast.type_node == 0) { | 4556 | if (is_extern and var_decl.ast.type_node == .none) { |
| 4601 | return astgen.failNode(node, "unable to infer variable type", .{}); | 4557 | return astgen.failNode(node, "unable to infer variable type", .{}); |
| 4602 | } | 4558 | } |
| 4603 | 4559 | ||
| ... | @@ -4614,45 +4570,45 @@ fn globalVarDecl( | ... | @@ -4614,45 +4570,45 @@ fn globalVarDecl( |
| 4614 | }; | 4570 | }; |
| 4615 | defer type_gz.unstack(); | 4571 | defer type_gz.unstack(); |
| 4616 | 4572 | ||
| 4617 | if (var_decl.ast.type_node != 0) { | 4573 | if (var_decl.ast.type_node.unwrap()) |type_node| { |
| 4618 | const type_inst = try expr(&type_gz, &type_gz.base, coerced_type_ri, var_decl.ast.type_node); | 4574 | const type_inst = try expr(&type_gz, &type_gz.base, coerced_type_ri, type_node); |
| 4619 | _ = try type_gz.addBreakWithSrcNode(.break_inline, decl_inst, type_inst, node); | 4575 | _ = try type_gz.addBreakWithSrcNode(.break_inline, decl_inst, type_inst, node); |
| 4620 | } | 4576 | } |
| 4621 | 4577 | ||
| 4622 | var align_gz = type_gz.makeSubBlock(scope); | 4578 | var align_gz = type_gz.makeSubBlock(scope); |
| 4623 | defer align_gz.unstack(); | 4579 | defer align_gz.unstack(); |
| 4624 | 4580 | ||
| 4625 | if (var_decl.ast.align_node != 0) { | 4581 | if (var_decl.ast.align_node.unwrap()) |align_node| { |
| 4626 | const align_inst = try expr(&align_gz, &align_gz.base, coerced_align_ri, var_decl.ast.align_node); | 4582 | const align_inst = try expr(&align_gz, &align_gz.base, coerced_align_ri, align_node); |
| 4627 | _ = try align_gz.addBreakWithSrcNode(.break_inline, decl_inst, align_inst, node); | 4583 | _ = try align_gz.addBreakWithSrcNode(.break_inline, decl_inst, align_inst, node); |
| 4628 | } | 4584 | } |
| 4629 | 4585 | ||
| 4630 | var linksection_gz = type_gz.makeSubBlock(scope); | 4586 | var linksection_gz = type_gz.makeSubBlock(scope); |
| 4631 | defer linksection_gz.unstack(); | 4587 | defer linksection_gz.unstack(); |
| 4632 | 4588 | ||
| 4633 | if (var_decl.ast.section_node != 0) { | 4589 | if (var_decl.ast.section_node.unwrap()) |section_node| { |
| 4634 | const linksection_inst = try expr(&linksection_gz, &linksection_gz.base, coerced_linksection_ri, var_decl.ast.section_node); | 4590 | const linksection_inst = try expr(&linksection_gz, &linksection_gz.base, coerced_linksection_ri, section_node); |
| 4635 | _ = try linksection_gz.addBreakWithSrcNode(.break_inline, decl_inst, linksection_inst, node); | 4591 | _ = try linksection_gz.addBreakWithSrcNode(.break_inline, decl_inst, linksection_inst, node); |
| 4636 | } | 4592 | } |
| 4637 | 4593 | ||
| 4638 | var addrspace_gz = type_gz.makeSubBlock(scope); | 4594 | var addrspace_gz = type_gz.makeSubBlock(scope); |
| 4639 | defer addrspace_gz.unstack(); | 4595 | defer addrspace_gz.unstack(); |
| 4640 | 4596 | ||
| 4641 | if (var_decl.ast.addrspace_node != 0) { | 4597 | if (var_decl.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 4642 | const addrspace_ty = try addrspace_gz.addBuiltinValue(var_decl.ast.addrspace_node, .address_space); | 4598 | const addrspace_ty = try addrspace_gz.addBuiltinValue(addrspace_node, .address_space); |
| 4643 | const addrspace_inst = try expr(&addrspace_gz, &addrspace_gz.base, .{ .rl = .{ .coerced_ty = addrspace_ty } }, var_decl.ast.addrspace_node); | 4599 | const addrspace_inst = try expr(&addrspace_gz, &addrspace_gz.base, .{ .rl = .{ .coerced_ty = addrspace_ty } }, addrspace_node); |
| 4644 | _ = try addrspace_gz.addBreakWithSrcNode(.break_inline, decl_inst, addrspace_inst, node); | 4600 | _ = try addrspace_gz.addBreakWithSrcNode(.break_inline, decl_inst, addrspace_inst, node); |
| 4645 | } | 4601 | } |
| 4646 | 4602 | ||
| 4647 | var init_gz = type_gz.makeSubBlock(scope); | 4603 | var init_gz = type_gz.makeSubBlock(scope); |
| 4648 | defer init_gz.unstack(); | 4604 | defer init_gz.unstack(); |
| 4649 | 4605 | ||
| 4650 | if (var_decl.ast.init_node != 0) { | 4606 | if (var_decl.ast.init_node.unwrap()) |init_node| { |
| 4651 | init_gz.anon_name_strategy = .parent; | 4607 | init_gz.anon_name_strategy = .parent; |
| 4652 | const init_ri: ResultInfo = if (var_decl.ast.type_node != 0) .{ | 4608 | const init_ri: ResultInfo = if (var_decl.ast.type_node != .none) .{ |
| 4653 | .rl = .{ .coerced_ty = decl_inst.toRef() }, | 4609 | .rl = .{ .coerced_ty = decl_inst.toRef() }, |
| 4654 | } else .{ .rl = .none }; | 4610 | } else .{ .rl = .none }; |
| 4655 | const init_inst = try expr(&init_gz, &init_gz.base, init_ri, var_decl.ast.init_node); | 4611 | const init_inst = try expr(&init_gz, &init_gz.base, init_ri, init_node); |
| 4656 | _ = try init_gz.addBreakWithSrcNode(.break_inline, decl_inst, init_inst, node); | 4612 | _ = try init_gz.addBreakWithSrcNode(.break_inline, decl_inst, init_inst, node); |
| 4657 | } | 4613 | } |
| 4658 | 4614 | ||
| ... | @@ -4686,8 +4642,7 @@ fn comptimeDecl( | ... | @@ -4686,8 +4642,7 @@ fn comptimeDecl( |
| 4686 | node: Ast.Node.Index, | 4642 | node: Ast.Node.Index, |
| 4687 | ) InnerError!void { | 4643 | ) InnerError!void { |
| 4688 | const tree = astgen.tree; | 4644 | const tree = astgen.tree; |
| 4689 | const node_datas = tree.nodes.items(.data); | 4645 | const body_node = tree.nodeData(node).node; |
| 4690 | const body_node = node_datas[node].lhs; | ||
| 4691 | 4646 | ||
| 4692 | const old_hasher = astgen.src_hasher; | 4647 | const old_hasher = astgen.src_hasher; |
| 4693 | defer astgen.src_hasher = old_hasher; | 4648 | defer astgen.src_hasher = old_hasher; |
| ... | @@ -4750,7 +4705,6 @@ fn usingnamespaceDecl( | ... | @@ -4750,7 +4705,6 @@ fn usingnamespaceDecl( |
| 4750 | node: Ast.Node.Index, | 4705 | node: Ast.Node.Index, |
| 4751 | ) InnerError!void { | 4706 | ) InnerError!void { |
| 4752 | const tree = astgen.tree; | 4707 | const tree = astgen.tree; |
| 4753 | const node_datas = tree.nodes.items(.data); | ||
| 4754 | 4708 | ||
| 4755 | const old_hasher = astgen.src_hasher; | 4709 | const old_hasher = astgen.src_hasher; |
| 4756 | defer astgen.src_hasher = old_hasher; | 4710 | defer astgen.src_hasher = old_hasher; |
| ... | @@ -4758,13 +4712,9 @@ fn usingnamespaceDecl( | ... | @@ -4758,13 +4712,9 @@ fn usingnamespaceDecl( |
| 4758 | astgen.src_hasher.update(tree.getNodeSource(node)); | 4712 | astgen.src_hasher.update(tree.getNodeSource(node)); |
| 4759 | astgen.src_hasher.update(std.mem.asBytes(&astgen.source_column)); | 4713 | astgen.src_hasher.update(std.mem.asBytes(&astgen.source_column)); |
| 4760 | 4714 | ||
| 4761 | const type_expr = node_datas[node].lhs; | 4715 | const type_expr = tree.nodeData(node).node; |
| 4762 | const is_pub = blk: { | 4716 | const is_pub = tree.isTokenPrecededByTags(tree.nodeMainToken(node), &.{.keyword_pub}); |
| 4763 | const main_tokens = tree.nodes.items(.main_token); | 4717 | |
| 4764 | const token_tags = tree.tokens.items(.tag); | ||
| 4765 | const main_token = main_tokens[node]; | ||
| 4766 | break :blk (main_token > 0 and token_tags[main_token - 1] == .keyword_pub); | ||
| 4767 | }; | ||
| 4768 | // Up top so the ZIR instruction index marks the start range of this | 4718 | // Up top so the ZIR instruction index marks the start range of this |
| 4769 | // top-level declaration. | 4719 | // top-level declaration. |
| 4770 | const decl_inst = try gz.makeDeclaration(node); | 4720 | const decl_inst = try gz.makeDeclaration(node); |
| ... | @@ -4818,8 +4768,7 @@ fn testDecl( | ... | @@ -4818,8 +4768,7 @@ fn testDecl( |
| 4818 | node: Ast.Node.Index, | 4768 | node: Ast.Node.Index, |
| 4819 | ) InnerError!void { | 4769 | ) InnerError!void { |
| 4820 | const tree = astgen.tree; | 4770 | const tree = astgen.tree; |
| 4821 | const node_datas = tree.nodes.items(.data); | 4771 | _, const body_node = tree.nodeData(node).opt_token_and_node; |
| 4822 | const body_node = node_datas[node].rhs; | ||
| 4823 | 4772 | ||
| 4824 | const old_hasher = astgen.src_hasher; | 4773 | const old_hasher = astgen.src_hasher; |
| 4825 | defer astgen.src_hasher = old_hasher; | 4774 | defer astgen.src_hasher = old_hasher; |
| ... | @@ -4851,12 +4800,10 @@ fn testDecl( | ... | @@ -4851,12 +4800,10 @@ fn testDecl( |
| 4851 | 4800 | ||
| 4852 | const decl_column = astgen.source_column; | 4801 | const decl_column = astgen.source_column; |
| 4853 | 4802 | ||
| 4854 | const main_tokens = tree.nodes.items(.main_token); | 4803 | const test_token = tree.nodeMainToken(node); |
| 4855 | const token_tags = tree.tokens.items(.tag); | ||
| 4856 | const test_token = main_tokens[node]; | ||
| 4857 | 4804 | ||
| 4858 | const test_name_token = test_token + 1; | 4805 | const test_name_token = test_token + 1; |
| 4859 | const test_name: Zir.NullTerminatedString = switch (token_tags[test_name_token]) { | 4806 | const test_name: Zir.NullTerminatedString = switch (tree.tokenTag(test_name_token)) { |
| 4860 | else => .empty, | 4807 | else => .empty, |
| 4861 | .string_literal => name: { | 4808 | .string_literal => name: { |
| 4862 | const name = try astgen.strLitAsString(test_name_token); | 4809 | const name = try astgen.strLitAsString(test_name_token); |
| ... | @@ -4888,7 +4835,7 @@ fn testDecl( | ... | @@ -4888,7 +4835,7 @@ fn testDecl( |
| 4888 | .local_val => { | 4835 | .local_val => { |
| 4889 | const local_val = s.cast(Scope.LocalVal).?; | 4836 | const local_val = s.cast(Scope.LocalVal).?; |
| 4890 | if (local_val.name == name_str_index) { | 4837 | if (local_val.name == name_str_index) { |
| 4891 | local_val.used = test_name_token; | 4838 | local_val.used = .fromToken(test_name_token); |
| 4892 | return astgen.failTokNotes(test_name_token, "cannot test a {s}", .{ | 4839 | return astgen.failTokNotes(test_name_token, "cannot test a {s}", .{ |
| 4893 | @tagName(local_val.id_cat), | 4840 | @tagName(local_val.id_cat), |
| 4894 | }, &[_]u32{ | 4841 | }, &[_]u32{ |
| ... | @@ -4902,7 +4849,7 @@ fn testDecl( | ... | @@ -4902,7 +4849,7 @@ fn testDecl( |
| 4902 | .local_ptr => { | 4849 | .local_ptr => { |
| 4903 | const local_ptr = s.cast(Scope.LocalPtr).?; | 4850 | const local_ptr = s.cast(Scope.LocalPtr).?; |
| 4904 | if (local_ptr.name == name_str_index) { | 4851 | if (local_ptr.name == name_str_index) { |
| 4905 | local_ptr.used = test_name_token; | 4852 | local_ptr.used = .fromToken(test_name_token); |
| 4906 | return astgen.failTokNotes(test_name_token, "cannot test a {s}", .{ | 4853 | return astgen.failTokNotes(test_name_token, "cannot test a {s}", .{ |
| 4907 | @tagName(local_ptr.id_cat), | 4854 | @tagName(local_ptr.id_cat), |
| 4908 | }, &[_]u32{ | 4855 | }, &[_]u32{ |
| ... | @@ -5013,7 +4960,7 @@ fn testDecl( | ... | @@ -5013,7 +4960,7 @@ fn testDecl( |
| 5013 | .src_line = decl_block.decl_line, | 4960 | .src_line = decl_block.decl_line, |
| 5014 | .src_column = decl_column, | 4961 | .src_column = decl_column, |
| 5015 | 4962 | ||
| 5016 | .kind = switch (token_tags[test_name_token]) { | 4963 | .kind = switch (tree.tokenTag(test_name_token)) { |
| 5017 | .string_literal => .@"test", | 4964 | .string_literal => .@"test", |
| 5018 | .identifier => .decltest, | 4965 | .identifier => .decltest, |
| 5019 | else => .unnamed_test, | 4966 | else => .unnamed_test, |
| ... | @@ -5037,7 +4984,7 @@ fn structDeclInner( | ... | @@ -5037,7 +4984,7 @@ fn structDeclInner( |
| 5037 | node: Ast.Node.Index, | 4984 | node: Ast.Node.Index, |
| 5038 | container_decl: Ast.full.ContainerDecl, | 4985 | container_decl: Ast.full.ContainerDecl, |
| 5039 | layout: std.builtin.Type.ContainerLayout, | 4986 | layout: std.builtin.Type.ContainerLayout, |
| 5040 | backing_int_node: Ast.Node.Index, | 4987 | backing_int_node: Ast.Node.OptionalIndex, |
| 5041 | ) InnerError!Zir.Inst.Ref { | 4988 | ) InnerError!Zir.Inst.Ref { |
| 5042 | const astgen = gz.astgen; | 4989 | const astgen = gz.astgen; |
| 5043 | const gpa = astgen.gpa; | 4990 | const gpa = astgen.gpa; |
| ... | @@ -5049,7 +4996,7 @@ fn structDeclInner( | ... | @@ -5049,7 +4996,7 @@ fn structDeclInner( |
| 5049 | if (container_field.ast.tuple_like) break member_node; | 4996 | if (container_field.ast.tuple_like) break member_node; |
| 5050 | } else break :is_tuple; | 4997 | } else break :is_tuple; |
| 5051 | 4998 | ||
| 5052 | if (node == 0) { | 4999 | if (node == .root) { |
| 5053 | return astgen.failNode(tuple_field_node, "file cannot be a tuple", .{}); | 5000 | return astgen.failNode(tuple_field_node, "file cannot be a tuple", .{}); |
| 5054 | } else { | 5001 | } else { |
| 5055 | return tupleDecl(gz, scope, node, container_decl, layout, backing_int_node); | 5002 | return tupleDecl(gz, scope, node, container_decl, layout, backing_int_node); |
| ... | @@ -5058,7 +5005,7 @@ fn structDeclInner( | ... | @@ -5058,7 +5005,7 @@ fn structDeclInner( |
| 5058 | 5005 | ||
| 5059 | const decl_inst = try gz.reserveInstructionIndex(); | 5006 | const decl_inst = try gz.reserveInstructionIndex(); |
| 5060 | 5007 | ||
| 5061 | if (container_decl.ast.members.len == 0 and backing_int_node == 0) { | 5008 | if (container_decl.ast.members.len == 0 and backing_int_node == .none) { |
| 5062 | try gz.setStruct(decl_inst, .{ | 5009 | try gz.setStruct(decl_inst, .{ |
| 5063 | .src_node = node, | 5010 | .src_node = node, |
| 5064 | .layout = layout, | 5011 | .layout = layout, |
| ... | @@ -5105,11 +5052,11 @@ fn structDeclInner( | ... | @@ -5105,11 +5052,11 @@ fn structDeclInner( |
| 5105 | 5052 | ||
| 5106 | var backing_int_body_len: usize = 0; | 5053 | var backing_int_body_len: usize = 0; |
| 5107 | const backing_int_ref: Zir.Inst.Ref = blk: { | 5054 | const backing_int_ref: Zir.Inst.Ref = blk: { |
| 5108 | if (backing_int_node != 0) { | 5055 | if (backing_int_node.unwrap()) |arg| { |
| 5109 | if (layout != .@"packed") { | 5056 | if (layout != .@"packed") { |
| 5110 | return astgen.failNode(backing_int_node, "non-packed struct does not support backing integer type", .{}); | 5057 | return astgen.failNode(arg, "non-packed struct does not support backing integer type", .{}); |
| 5111 | } else { | 5058 | } else { |
| 5112 | const backing_int_ref = try typeExpr(&block_scope, &namespace.base, backing_int_node); | 5059 | const backing_int_ref = try typeExpr(&block_scope, &namespace.base, arg); |
| 5113 | if (!block_scope.isEmpty()) { | 5060 | if (!block_scope.isEmpty()) { |
| 5114 | if (!block_scope.endsWithNoReturn()) { | 5061 | if (!block_scope.endsWithNoReturn()) { |
| 5115 | _ = try block_scope.addBreak(.break_inline, decl_inst, backing_int_ref); | 5062 | _ = try block_scope.addBreak(.break_inline, decl_inst, backing_int_ref); |
| ... | @@ -5154,8 +5101,8 @@ fn structDeclInner( | ... | @@ -5154,8 +5101,8 @@ fn structDeclInner( |
| 5154 | defer astgen.src_hasher = old_hasher; | 5101 | defer astgen.src_hasher = old_hasher; |
| 5155 | astgen.src_hasher = std.zig.SrcHasher.init(.{}); | 5102 | astgen.src_hasher = std.zig.SrcHasher.init(.{}); |
| 5156 | astgen.src_hasher.update(@tagName(layout)); | 5103 | astgen.src_hasher.update(@tagName(layout)); |
| 5157 | if (backing_int_node != 0) { | 5104 | if (backing_int_node.unwrap()) |arg| { |
| 5158 | astgen.src_hasher.update(tree.getNodeSource(backing_int_node)); | 5105 | astgen.src_hasher.update(tree.getNodeSource(arg)); |
| 5159 | } | 5106 | } |
| 5160 | 5107 | ||
| 5161 | var known_non_opv = false; | 5108 | var known_non_opv = false; |
| ... | @@ -5172,18 +5119,18 @@ fn structDeclInner( | ... | @@ -5172,18 +5119,18 @@ fn structDeclInner( |
| 5172 | astgen.src_hasher.update(tree.getNodeSource(member_node)); | 5119 | astgen.src_hasher.update(tree.getNodeSource(member_node)); |
| 5173 | 5120 | ||
| 5174 | const field_name = try astgen.identAsString(member.ast.main_token); | 5121 | const field_name = try astgen.identAsString(member.ast.main_token); |
| 5175 | member.convertToNonTupleLike(astgen.tree.nodes); | 5122 | member.convertToNonTupleLike(astgen.tree); |
| 5176 | assert(!member.ast.tuple_like); | 5123 | assert(!member.ast.tuple_like); |
| 5177 | wip_members.appendToField(@intFromEnum(field_name)); | 5124 | wip_members.appendToField(@intFromEnum(field_name)); |
| 5178 | 5125 | ||
| 5179 | if (member.ast.type_expr == 0) { | 5126 | const type_expr = member.ast.type_expr.unwrap() orelse { |
| 5180 | return astgen.failTok(member.ast.main_token, "struct field missing type", .{}); | 5127 | return astgen.failTok(member.ast.main_token, "struct field missing type", .{}); |
| 5181 | } | 5128 | }; |
| 5182 | 5129 | ||
| 5183 | const field_type = try typeExpr(&block_scope, &namespace.base, member.ast.type_expr); | 5130 | const field_type = try typeExpr(&block_scope, &namespace.base, type_expr); |
| 5184 | const have_type_body = !block_scope.isEmpty(); | 5131 | const have_type_body = !block_scope.isEmpty(); |
| 5185 | const have_align = member.ast.align_expr != 0; | 5132 | const have_align = member.ast.align_expr != .none; |
| 5186 | const have_value = member.ast.value_expr != 0; | 5133 | const have_value = member.ast.value_expr != .none; |
| 5187 | const is_comptime = member.comptime_token != null; | 5134 | const is_comptime = member.comptime_token != null; |
| 5188 | 5135 | ||
| 5189 | if (is_comptime) { | 5136 | if (is_comptime) { |
| ... | @@ -5193,9 +5140,9 @@ fn structDeclInner( | ... | @@ -5193,9 +5140,9 @@ fn structDeclInner( |
| 5193 | } | 5140 | } |
| 5194 | } else { | 5141 | } else { |
| 5195 | known_non_opv = known_non_opv or | 5142 | known_non_opv = known_non_opv or |
| 5196 | nodeImpliesMoreThanOnePossibleValue(tree, member.ast.type_expr); | 5143 | nodeImpliesMoreThanOnePossibleValue(tree, type_expr); |
| 5197 | known_comptime_only = known_comptime_only or | 5144 | known_comptime_only = known_comptime_only or |
| 5198 | nodeImpliesComptimeOnly(tree, member.ast.type_expr); | 5145 | nodeImpliesComptimeOnly(tree, type_expr); |
| 5199 | } | 5146 | } |
| 5200 | wip_members.nextField(bits_per_field, .{ have_align, have_value, is_comptime, have_type_body }); | 5147 | wip_members.nextField(bits_per_field, .{ have_align, have_value, is_comptime, have_type_body }); |
| 5201 | 5148 | ||
| ... | @@ -5213,12 +5160,12 @@ fn structDeclInner( | ... | @@ -5213,12 +5160,12 @@ fn structDeclInner( |
| 5213 | wip_members.appendToField(@intFromEnum(field_type)); | 5160 | wip_members.appendToField(@intFromEnum(field_type)); |
| 5214 | } | 5161 | } |
| 5215 | 5162 | ||
| 5216 | if (have_align) { | 5163 | if (member.ast.align_expr.unwrap()) |align_expr| { |
| 5217 | if (layout == .@"packed") { | 5164 | if (layout == .@"packed") { |
| 5218 | return astgen.failNode(member.ast.align_expr, "unable to override alignment of packed struct fields", .{}); | 5165 | return astgen.failNode(align_expr, "unable to override alignment of packed struct fields", .{}); |
| 5219 | } | 5166 | } |
| 5220 | any_aligned_fields = true; | 5167 | any_aligned_fields = true; |
| 5221 | const align_ref = try expr(&block_scope, &namespace.base, coerced_align_ri, member.ast.align_expr); | 5168 | const align_ref = try expr(&block_scope, &namespace.base, coerced_align_ri, align_expr); |
| 5222 | if (!block_scope.endsWithNoReturn()) { | 5169 | if (!block_scope.endsWithNoReturn()) { |
| 5223 | _ = try block_scope.addBreak(.break_inline, decl_inst, align_ref); | 5170 | _ = try block_scope.addBreak(.break_inline, decl_inst, align_ref); |
| 5224 | } | 5171 | } |
| ... | @@ -5230,14 +5177,14 @@ fn structDeclInner( | ... | @@ -5230,14 +5177,14 @@ fn structDeclInner( |
| 5230 | block_scope.instructions.items.len = block_scope.instructions_top; | 5177 | block_scope.instructions.items.len = block_scope.instructions_top; |
| 5231 | } | 5178 | } |
| 5232 | 5179 | ||
| 5233 | if (have_value) { | 5180 | if (member.ast.value_expr.unwrap()) |value_expr| { |
| 5234 | any_default_inits = true; | 5181 | any_default_inits = true; |
| 5235 | 5182 | ||
| 5236 | // The decl_inst is used as here so that we can easily reconstruct a mapping | 5183 | // The decl_inst is used as here so that we can easily reconstruct a mapping |
| 5237 | // between it and the field type when the fields inits are analyzed. | 5184 | // between it and the field type when the fields inits are analyzed. |
| 5238 | const ri: ResultInfo = .{ .rl = if (field_type == .none) .none else .{ .coerced_ty = decl_inst.toRef() } }; | 5185 | const ri: ResultInfo = .{ .rl = if (field_type == .none) .none else .{ .coerced_ty = decl_inst.toRef() } }; |
| 5239 | 5186 | ||
| 5240 | const default_inst = try expr(&block_scope, &namespace.base, ri, member.ast.value_expr); | 5187 | const default_inst = try expr(&block_scope, &namespace.base, ri, value_expr); |
| 5241 | if (!block_scope.endsWithNoReturn()) { | 5188 | if (!block_scope.endsWithNoReturn()) { |
| 5242 | _ = try block_scope.addBreak(.break_inline, decl_inst, default_inst); | 5189 | _ = try block_scope.addBreak(.break_inline, decl_inst, default_inst); |
| 5243 | } | 5190 | } |
| ... | @@ -5300,21 +5247,19 @@ fn tupleDecl( | ... | @@ -5300,21 +5247,19 @@ fn tupleDecl( |
| 5300 | node: Ast.Node.Index, | 5247 | node: Ast.Node.Index, |
| 5301 | container_decl: Ast.full.ContainerDecl, | 5248 | container_decl: Ast.full.ContainerDecl, |
| 5302 | layout: std.builtin.Type.ContainerLayout, | 5249 | layout: std.builtin.Type.ContainerLayout, |
| 5303 | backing_int_node: Ast.Node.Index, | 5250 | backing_int_node: Ast.Node.OptionalIndex, |
| 5304 | ) InnerError!Zir.Inst.Ref { | 5251 | ) InnerError!Zir.Inst.Ref { |
| 5305 | const astgen = gz.astgen; | 5252 | const astgen = gz.astgen; |
| 5306 | const gpa = astgen.gpa; | 5253 | const gpa = astgen.gpa; |
| 5307 | const tree = astgen.tree; | 5254 | const tree = astgen.tree; |
| 5308 | 5255 | ||
| 5309 | const node_tags = tree.nodes.items(.tag); | ||
| 5310 | |||
| 5311 | switch (layout) { | 5256 | switch (layout) { |
| 5312 | .auto => {}, | 5257 | .auto => {}, |
| 5313 | .@"extern", .@"packed" => return astgen.failNode(node, "{s} tuples are not supported", .{@tagName(layout)}), | 5258 | .@"extern", .@"packed" => return astgen.failNode(node, "{s} tuples are not supported", .{@tagName(layout)}), |
| 5314 | } | 5259 | } |
| 5315 | 5260 | ||
| 5316 | if (backing_int_node != 0) { | 5261 | if (backing_int_node.unwrap()) |arg| { |
| 5317 | return astgen.failNode(backing_int_node, "tuple does not support backing integer type", .{}); | 5262 | return astgen.failNode(arg, "tuple does not support backing integer type", .{}); |
| 5318 | } | 5263 | } |
| 5319 | 5264 | ||
| 5320 | // We will use the scratch buffer, starting here, for the field data: | 5265 | // We will use the scratch buffer, starting here, for the field data: |
| ... | @@ -5329,7 +5274,7 @@ fn tupleDecl( | ... | @@ -5329,7 +5274,7 @@ fn tupleDecl( |
| 5329 | 5274 | ||
| 5330 | for (container_decl.ast.members) |member_node| { | 5275 | for (container_decl.ast.members) |member_node| { |
| 5331 | const field = tree.fullContainerField(member_node) orelse { | 5276 | const field = tree.fullContainerField(member_node) orelse { |
| 5332 | const tuple_member = for (container_decl.ast.members) |maybe_tuple| switch (node_tags[maybe_tuple]) { | 5277 | const tuple_member = for (container_decl.ast.members) |maybe_tuple| switch (tree.nodeTag(maybe_tuple)) { |
| 5333 | .container_field_init, | 5278 | .container_field_init, |
| 5334 | .container_field_align, | 5279 | .container_field_align, |
| 5335 | .container_field, | 5280 | .container_field, |
| ... | @@ -5348,23 +5293,23 @@ fn tupleDecl( | ... | @@ -5348,23 +5293,23 @@ fn tupleDecl( |
| 5348 | return astgen.failTok(field.ast.main_token, "tuple field has a name", .{}); | 5293 | return astgen.failTok(field.ast.main_token, "tuple field has a name", .{}); |
| 5349 | } | 5294 | } |
| 5350 | 5295 | ||
| 5351 | if (field.ast.align_expr != 0) { | 5296 | if (field.ast.align_expr != .none) { |
| 5352 | return astgen.failTok(field.ast.main_token, "tuple field has alignment", .{}); | 5297 | return astgen.failTok(field.ast.main_token, "tuple field has alignment", .{}); |
| 5353 | } | 5298 | } |
| 5354 | 5299 | ||
| 5355 | if (field.ast.value_expr != 0 and field.comptime_token == null) { | 5300 | if (field.ast.value_expr != .none and field.comptime_token == null) { |
| 5356 | return astgen.failTok(field.ast.main_token, "non-comptime tuple field has default initialization value", .{}); | 5301 | return astgen.failTok(field.ast.main_token, "non-comptime tuple field has default initialization value", .{}); |
| 5357 | } | 5302 | } |
| 5358 | 5303 | ||
| 5359 | if (field.ast.value_expr == 0 and field.comptime_token != null) { | 5304 | if (field.ast.value_expr == .none and field.comptime_token != null) { |
| 5360 | return astgen.failTok(field.comptime_token.?, "comptime field without default initialization value", .{}); | 5305 | return astgen.failTok(field.comptime_token.?, "comptime field without default initialization value", .{}); |
| 5361 | } | 5306 | } |
| 5362 | 5307 | ||
| 5363 | const field_type_ref = try typeExpr(gz, scope, field.ast.type_expr); | 5308 | const field_type_ref = try typeExpr(gz, scope, field.ast.type_expr.unwrap().?); |
| 5364 | astgen.scratch.appendAssumeCapacity(@intFromEnum(field_type_ref)); | 5309 | astgen.scratch.appendAssumeCapacity(@intFromEnum(field_type_ref)); |
| 5365 | 5310 | ||
| 5366 | if (field.ast.value_expr != 0) { | 5311 | if (field.ast.value_expr.unwrap()) |value_expr| { |
| 5367 | const field_init_ref = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = field_type_ref } }, field.ast.value_expr, .tuple_field_default_value); | 5312 | const field_init_ref = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = field_type_ref } }, value_expr, .tuple_field_default_value); |
| 5368 | astgen.scratch.appendAssumeCapacity(@intFromEnum(field_init_ref)); | 5313 | astgen.scratch.appendAssumeCapacity(@intFromEnum(field_init_ref)); |
| 5369 | } else { | 5314 | } else { |
| 5370 | astgen.scratch.appendAssumeCapacity(@intFromEnum(Zir.Inst.Ref.none)); | 5315 | astgen.scratch.appendAssumeCapacity(@intFromEnum(Zir.Inst.Ref.none)); |
| ... | @@ -5399,7 +5344,7 @@ fn unionDeclInner( | ... | @@ -5399,7 +5344,7 @@ fn unionDeclInner( |
| 5399 | node: Ast.Node.Index, | 5344 | node: Ast.Node.Index, |
| 5400 | members: []const Ast.Node.Index, | 5345 | members: []const Ast.Node.Index, |
| 5401 | layout: std.builtin.Type.ContainerLayout, | 5346 | layout: std.builtin.Type.ContainerLayout, |
| 5402 | arg_node: Ast.Node.Index, | 5347 | opt_arg_node: Ast.Node.OptionalIndex, |
| 5403 | auto_enum_tok: ?Ast.TokenIndex, | 5348 | auto_enum_tok: ?Ast.TokenIndex, |
| 5404 | ) InnerError!Zir.Inst.Ref { | 5349 | ) InnerError!Zir.Inst.Ref { |
| 5405 | const decl_inst = try gz.reserveInstructionIndex(); | 5350 | const decl_inst = try gz.reserveInstructionIndex(); |
| ... | @@ -5434,15 +5379,15 @@ fn unionDeclInner( | ... | @@ -5434,15 +5379,15 @@ fn unionDeclInner( |
| 5434 | const decl_count = try astgen.scanContainer(&namespace, members, .@"union"); | 5379 | const decl_count = try astgen.scanContainer(&namespace, members, .@"union"); |
| 5435 | const field_count: u32 = @intCast(members.len - decl_count); | 5380 | const field_count: u32 = @intCast(members.len - decl_count); |
| 5436 | 5381 | ||
| 5437 | if (layout != .auto and (auto_enum_tok != null or arg_node != 0)) { | 5382 | if (layout != .auto and (auto_enum_tok != null or opt_arg_node != .none)) { |
| 5438 | if (arg_node != 0) { | 5383 | if (opt_arg_node.unwrap()) |arg_node| { |
| 5439 | return astgen.failNode(arg_node, "{s} union does not support enum tag type", .{@tagName(layout)}); | 5384 | return astgen.failNode(arg_node, "{s} union does not support enum tag type", .{@tagName(layout)}); |
| 5440 | } else { | 5385 | } else { |
| 5441 | return astgen.failTok(auto_enum_tok.?, "{s} union does not support enum tag type", .{@tagName(layout)}); | 5386 | return astgen.failTok(auto_enum_tok.?, "{s} union does not support enum tag type", .{@tagName(layout)}); |
| 5442 | } | 5387 | } |
| 5443 | } | 5388 | } |
| 5444 | 5389 | ||
| 5445 | const arg_inst: Zir.Inst.Ref = if (arg_node != 0) | 5390 | const arg_inst: Zir.Inst.Ref = if (opt_arg_node.unwrap()) |arg_node| |
| 5446 | try typeExpr(&block_scope, &namespace.base, arg_node) | 5391 | try typeExpr(&block_scope, &namespace.base, arg_node) |
| 5447 | else | 5392 | else |
| 5448 | .none; | 5393 | .none; |
| ... | @@ -5458,7 +5403,7 @@ fn unionDeclInner( | ... | @@ -5458,7 +5403,7 @@ fn unionDeclInner( |
| 5458 | astgen.src_hasher = std.zig.SrcHasher.init(.{}); | 5403 | astgen.src_hasher = std.zig.SrcHasher.init(.{}); |
| 5459 | astgen.src_hasher.update(@tagName(layout)); | 5404 | astgen.src_hasher.update(@tagName(layout)); |
| 5460 | astgen.src_hasher.update(&.{@intFromBool(auto_enum_tok != null)}); | 5405 | astgen.src_hasher.update(&.{@intFromBool(auto_enum_tok != null)}); |
| 5461 | if (arg_node != 0) { | 5406 | if (opt_arg_node.unwrap()) |arg_node| { |
| 5462 | astgen.src_hasher.update(astgen.tree.getNodeSource(arg_node)); | 5407 | astgen.src_hasher.update(astgen.tree.getNodeSource(arg_node)); |
| 5463 | } | 5408 | } |
| 5464 | 5409 | ||
| ... | @@ -5468,7 +5413,7 @@ fn unionDeclInner( | ... | @@ -5468,7 +5413,7 @@ fn unionDeclInner( |
| 5468 | .field => |field| field, | 5413 | .field => |field| field, |
| 5469 | }; | 5414 | }; |
| 5470 | astgen.src_hasher.update(astgen.tree.getNodeSource(member_node)); | 5415 | astgen.src_hasher.update(astgen.tree.getNodeSource(member_node)); |
| 5471 | member.convertToNonTupleLike(astgen.tree.nodes); | 5416 | member.convertToNonTupleLike(astgen.tree); |
| 5472 | if (member.ast.tuple_like) { | 5417 | if (member.ast.tuple_like) { |
| 5473 | return astgen.failTok(member.ast.main_token, "union field missing name", .{}); | 5418 | return astgen.failTok(member.ast.main_token, "union field missing name", .{}); |
| 5474 | } | 5419 | } |
| ... | @@ -5479,24 +5424,24 @@ fn unionDeclInner( | ... | @@ -5479,24 +5424,24 @@ fn unionDeclInner( |
| 5479 | const field_name = try astgen.identAsString(member.ast.main_token); | 5424 | const field_name = try astgen.identAsString(member.ast.main_token); |
| 5480 | wip_members.appendToField(@intFromEnum(field_name)); | 5425 | wip_members.appendToField(@intFromEnum(field_name)); |
| 5481 | 5426 | ||
| 5482 | const have_type = member.ast.type_expr != 0; | 5427 | const have_type = member.ast.type_expr != .none; |
| 5483 | const have_align = member.ast.align_expr != 0; | 5428 | const have_align = member.ast.align_expr != .none; |
| 5484 | const have_value = member.ast.value_expr != 0; | 5429 | const have_value = member.ast.value_expr != .none; |
| 5485 | const unused = false; | 5430 | const unused = false; |
| 5486 | wip_members.nextField(bits_per_field, .{ have_type, have_align, have_value, unused }); | 5431 | wip_members.nextField(bits_per_field, .{ have_type, have_align, have_value, unused }); |
| 5487 | 5432 | ||
| 5488 | if (have_type) { | 5433 | if (member.ast.type_expr.unwrap()) |type_expr| { |
| 5489 | const field_type = try typeExpr(&block_scope, &namespace.base, member.ast.type_expr); | 5434 | const field_type = try typeExpr(&block_scope, &namespace.base, type_expr); |
| 5490 | wip_members.appendToField(@intFromEnum(field_type)); | 5435 | wip_members.appendToField(@intFromEnum(field_type)); |
| 5491 | } else if (arg_inst == .none and auto_enum_tok == null) { | 5436 | } else if (arg_inst == .none and auto_enum_tok == null) { |
| 5492 | return astgen.failNode(member_node, "union field missing type", .{}); | 5437 | return astgen.failNode(member_node, "union field missing type", .{}); |
| 5493 | } | 5438 | } |
| 5494 | if (have_align) { | 5439 | if (member.ast.align_expr.unwrap()) |align_expr| { |
| 5495 | const align_inst = try expr(&block_scope, &block_scope.base, coerced_align_ri, member.ast.align_expr); | 5440 | const align_inst = try expr(&block_scope, &block_scope.base, coerced_align_ri, align_expr); |
| 5496 | wip_members.appendToField(@intFromEnum(align_inst)); | 5441 | wip_members.appendToField(@intFromEnum(align_inst)); |
| 5497 | any_aligned_fields = true; | 5442 | any_aligned_fields = true; |
| 5498 | } | 5443 | } |
| 5499 | if (have_value) { | 5444 | if (member.ast.value_expr.unwrap()) |value_expr| { |
| 5500 | if (arg_inst == .none) { | 5445 | if (arg_inst == .none) { |
| 5501 | return astgen.failNodeNotes( | 5446 | return astgen.failNodeNotes( |
| 5502 | node, | 5447 | node, |
| ... | @@ -5504,7 +5449,7 @@ fn unionDeclInner( | ... | @@ -5504,7 +5449,7 @@ fn unionDeclInner( |
| 5504 | .{}, | 5449 | .{}, |
| 5505 | &[_]u32{ | 5450 | &[_]u32{ |
| 5506 | try astgen.errNoteNode( | 5451 | try astgen.errNoteNode( |
| 5507 | member.ast.value_expr, | 5452 | value_expr, |
| 5508 | "tag value specified here", | 5453 | "tag value specified here", |
| 5509 | .{}, | 5454 | .{}, |
| 5510 | ), | 5455 | ), |
| ... | @@ -5518,14 +5463,14 @@ fn unionDeclInner( | ... | @@ -5518,14 +5463,14 @@ fn unionDeclInner( |
| 5518 | .{}, | 5463 | .{}, |
| 5519 | &[_]u32{ | 5464 | &[_]u32{ |
| 5520 | try astgen.errNoteNode( | 5465 | try astgen.errNoteNode( |
| 5521 | member.ast.value_expr, | 5466 | value_expr, |
| 5522 | "tag value specified here", | 5467 | "tag value specified here", |
| 5523 | .{}, | 5468 | .{}, |
| 5524 | ), | 5469 | ), |
| 5525 | }, | 5470 | }, |
| 5526 | ); | 5471 | ); |
| 5527 | } | 5472 | } |
| 5528 | const tag_value = try expr(&block_scope, &block_scope.base, .{ .rl = .{ .ty = arg_inst } }, member.ast.value_expr); | 5473 | const tag_value = try expr(&block_scope, &block_scope.base, .{ .rl = .{ .ty = arg_inst } }, value_expr); |
| 5529 | wip_members.appendToField(@intFromEnum(tag_value)); | 5474 | wip_members.appendToField(@intFromEnum(tag_value)); |
| 5530 | } | 5475 | } |
| 5531 | } | 5476 | } |
| ... | @@ -5577,7 +5522,6 @@ fn containerDecl( | ... | @@ -5577,7 +5522,6 @@ fn containerDecl( |
| 5577 | const astgen = gz.astgen; | 5522 | const astgen = gz.astgen; |
| 5578 | const gpa = astgen.gpa; | 5523 | const gpa = astgen.gpa; |
| 5579 | const tree = astgen.tree; | 5524 | const tree = astgen.tree; |
| 5580 | const token_tags = tree.tokens.items(.tag); | ||
| 5581 | 5525 | ||
| 5582 | const prev_fn_block = astgen.fn_block; | 5526 | const prev_fn_block = astgen.fn_block; |
| 5583 | astgen.fn_block = null; | 5527 | astgen.fn_block = null; |
| ... | @@ -5586,9 +5530,9 @@ fn containerDecl( | ... | @@ -5586,9 +5530,9 @@ fn containerDecl( |
| 5586 | // We must not create any types until Sema. Here the goal is only to generate | 5530 | // We must not create any types until Sema. Here the goal is only to generate |
| 5587 | // ZIR for all the field types, alignments, and default value expressions. | 5531 | // ZIR for all the field types, alignments, and default value expressions. |
| 5588 | 5532 | ||
| 5589 | switch (token_tags[container_decl.ast.main_token]) { | 5533 | switch (tree.tokenTag(container_decl.ast.main_token)) { |
| 5590 | .keyword_struct => { | 5534 | .keyword_struct => { |
| 5591 | const layout: std.builtin.Type.ContainerLayout = if (container_decl.layout_token) |t| switch (token_tags[t]) { | 5535 | const layout: std.builtin.Type.ContainerLayout = if (container_decl.layout_token) |t| switch (tree.tokenTag(t)) { |
| 5592 | .keyword_packed => .@"packed", | 5536 | .keyword_packed => .@"packed", |
| 5593 | .keyword_extern => .@"extern", | 5537 | .keyword_extern => .@"extern", |
| 5594 | else => unreachable, | 5538 | else => unreachable, |
| ... | @@ -5598,7 +5542,7 @@ fn containerDecl( | ... | @@ -5598,7 +5542,7 @@ fn containerDecl( |
| 5598 | return rvalue(gz, ri, result, node); | 5542 | return rvalue(gz, ri, result, node); |
| 5599 | }, | 5543 | }, |
| 5600 | .keyword_union => { | 5544 | .keyword_union => { |
| 5601 | const layout: std.builtin.Type.ContainerLayout = if (container_decl.layout_token) |t| switch (token_tags[t]) { | 5545 | const layout: std.builtin.Type.ContainerLayout = if (container_decl.layout_token) |t| switch (tree.tokenTag(t)) { |
| 5602 | .keyword_packed => .@"packed", | 5546 | .keyword_packed => .@"packed", |
| 5603 | .keyword_extern => .@"extern", | 5547 | .keyword_extern => .@"extern", |
| 5604 | else => unreachable, | 5548 | else => unreachable, |
| ... | @@ -5616,23 +5560,23 @@ fn containerDecl( | ... | @@ -5616,23 +5560,23 @@ fn containerDecl( |
| 5616 | var values: usize = 0; | 5560 | var values: usize = 0; |
| 5617 | var total_fields: usize = 0; | 5561 | var total_fields: usize = 0; |
| 5618 | var decls: usize = 0; | 5562 | var decls: usize = 0; |
| 5619 | var nonexhaustive_node: Ast.Node.Index = 0; | 5563 | var opt_nonexhaustive_node: Ast.Node.OptionalIndex = .none; |
| 5620 | var nonfinal_nonexhaustive = false; | 5564 | var nonfinal_nonexhaustive = false; |
| 5621 | for (container_decl.ast.members) |member_node| { | 5565 | for (container_decl.ast.members) |member_node| { |
| 5622 | var member = tree.fullContainerField(member_node) orelse { | 5566 | var member = tree.fullContainerField(member_node) orelse { |
| 5623 | decls += 1; | 5567 | decls += 1; |
| 5624 | continue; | 5568 | continue; |
| 5625 | }; | 5569 | }; |
| 5626 | member.convertToNonTupleLike(astgen.tree.nodes); | 5570 | member.convertToNonTupleLike(astgen.tree); |
| 5627 | if (member.ast.tuple_like) { | 5571 | if (member.ast.tuple_like) { |
| 5628 | return astgen.failTok(member.ast.main_token, "enum field missing name", .{}); | 5572 | return astgen.failTok(member.ast.main_token, "enum field missing name", .{}); |
| 5629 | } | 5573 | } |
| 5630 | if (member.comptime_token) |comptime_token| { | 5574 | if (member.comptime_token) |comptime_token| { |
| 5631 | return astgen.failTok(comptime_token, "enum fields cannot be marked comptime", .{}); | 5575 | return astgen.failTok(comptime_token, "enum fields cannot be marked comptime", .{}); |
| 5632 | } | 5576 | } |
| 5633 | if (member.ast.type_expr != 0) { | 5577 | if (member.ast.type_expr.unwrap()) |type_expr| { |
| 5634 | return astgen.failNodeNotes( | 5578 | return astgen.failNodeNotes( |
| 5635 | member.ast.type_expr, | 5579 | type_expr, |
| 5636 | "enum fields do not have types", | 5580 | "enum fields do not have types", |
| 5637 | .{}, | 5581 | .{}, |
| 5638 | &[_]u32{ | 5582 | &[_]u32{ |
| ... | @@ -5644,13 +5588,13 @@ fn containerDecl( | ... | @@ -5644,13 +5588,13 @@ fn containerDecl( |
| 5644 | }, | 5588 | }, |
| 5645 | ); | 5589 | ); |
| 5646 | } | 5590 | } |
| 5647 | if (member.ast.align_expr != 0) { | 5591 | if (member.ast.align_expr.unwrap()) |align_expr| { |
| 5648 | return astgen.failNode(member.ast.align_expr, "enum fields cannot be aligned", .{}); | 5592 | return astgen.failNode(align_expr, "enum fields cannot be aligned", .{}); |
| 5649 | } | 5593 | } |
| 5650 | 5594 | ||
| 5651 | const name_token = member.ast.main_token; | 5595 | const name_token = member.ast.main_token; |
| 5652 | if (mem.eql(u8, tree.tokenSlice(name_token), "_")) { | 5596 | if (mem.eql(u8, tree.tokenSlice(name_token), "_")) { |
| 5653 | if (nonexhaustive_node != 0) { | 5597 | if (opt_nonexhaustive_node.unwrap()) |nonexhaustive_node| { |
| 5654 | return astgen.failNodeNotes( | 5598 | return astgen.failNodeNotes( |
| 5655 | member_node, | 5599 | member_node, |
| 5656 | "redundant non-exhaustive enum mark", | 5600 | "redundant non-exhaustive enum mark", |
| ... | @@ -5664,40 +5608,41 @@ fn containerDecl( | ... | @@ -5664,40 +5608,41 @@ fn containerDecl( |
| 5664 | }, | 5608 | }, |
| 5665 | ); | 5609 | ); |
| 5666 | } | 5610 | } |
| 5667 | nonexhaustive_node = member_node; | 5611 | opt_nonexhaustive_node = member_node.toOptional(); |
| 5668 | if (member.ast.value_expr != 0) { | 5612 | if (member.ast.value_expr.unwrap()) |value_expr| { |
| 5669 | return astgen.failNode(member.ast.value_expr, "'_' is used to mark an enum as non-exhaustive and cannot be assigned a value", .{}); | 5613 | return astgen.failNode(value_expr, "'_' is used to mark an enum as non-exhaustive and cannot be assigned a value", .{}); |
| 5670 | } | 5614 | } |
| 5671 | continue; | 5615 | continue; |
| 5672 | } else if (nonexhaustive_node != 0) { | 5616 | } else if (opt_nonexhaustive_node != .none) { |
| 5673 | nonfinal_nonexhaustive = true; | 5617 | nonfinal_nonexhaustive = true; |
| 5674 | } | 5618 | } |
| 5675 | total_fields += 1; | 5619 | total_fields += 1; |
| 5676 | if (member.ast.value_expr != 0) { | 5620 | if (member.ast.value_expr.unwrap()) |value_expr| { |
| 5677 | if (container_decl.ast.arg == 0) { | 5621 | if (container_decl.ast.arg == .none) { |
| 5678 | return astgen.failNode(member.ast.value_expr, "value assigned to enum tag with inferred tag type", .{}); | 5622 | return astgen.failNode(value_expr, "value assigned to enum tag with inferred tag type", .{}); |
| 5679 | } | 5623 | } |
| 5680 | values += 1; | 5624 | values += 1; |
| 5681 | } | 5625 | } |
| 5682 | } | 5626 | } |
| 5683 | if (nonfinal_nonexhaustive) { | 5627 | if (nonfinal_nonexhaustive) { |
| 5684 | return astgen.failNode(nonexhaustive_node, "'_' field of non-exhaustive enum must be last", .{}); | 5628 | return astgen.failNode(opt_nonexhaustive_node.unwrap().?, "'_' field of non-exhaustive enum must be last", .{}); |
| 5685 | } | 5629 | } |
| 5686 | break :blk .{ | 5630 | break :blk .{ |
| 5687 | .total_fields = total_fields, | 5631 | .total_fields = total_fields, |
| 5688 | .values = values, | 5632 | .values = values, |
| 5689 | .decls = decls, | 5633 | .decls = decls, |
| 5690 | .nonexhaustive_node = nonexhaustive_node, | 5634 | .nonexhaustive_node = opt_nonexhaustive_node, |
| 5691 | }; | 5635 | }; |
| 5692 | }; | 5636 | }; |
| 5693 | if (counts.nonexhaustive_node != 0 and container_decl.ast.arg == 0) { | 5637 | if (counts.nonexhaustive_node != .none and container_decl.ast.arg == .none) { |
| 5638 | const nonexhaustive_node = counts.nonexhaustive_node.unwrap().?; | ||
| 5694 | return astgen.failNodeNotes( | 5639 | return astgen.failNodeNotes( |
| 5695 | node, | 5640 | node, |
| 5696 | "non-exhaustive enum missing integer tag type", | 5641 | "non-exhaustive enum missing integer tag type", |
| 5697 | .{}, | 5642 | .{}, |
| 5698 | &[_]u32{ | 5643 | &[_]u32{ |
| 5699 | try astgen.errNoteNode( | 5644 | try astgen.errNoteNode( |
| 5700 | counts.nonexhaustive_node, | 5645 | nonexhaustive_node, |
| 5701 | "marked non-exhaustive here", | 5646 | "marked non-exhaustive here", |
| 5702 | .{}, | 5647 | .{}, |
| 5703 | ), | 5648 | ), |
| ... | @@ -5706,7 +5651,7 @@ fn containerDecl( | ... | @@ -5706,7 +5651,7 @@ fn containerDecl( |
| 5706 | } | 5651 | } |
| 5707 | // In this case we must generate ZIR code for the tag values, similar to | 5652 | // In this case we must generate ZIR code for the tag values, similar to |
| 5708 | // how structs are handled above. | 5653 | // how structs are handled above. |
| 5709 | const nonexhaustive = counts.nonexhaustive_node != 0; | 5654 | const nonexhaustive = counts.nonexhaustive_node != .none; |
| 5710 | 5655 | ||
| 5711 | const decl_inst = try gz.reserveInstructionIndex(); | 5656 | const decl_inst = try gz.reserveInstructionIndex(); |
| 5712 | 5657 | ||
| ... | @@ -5736,8 +5681,8 @@ fn containerDecl( | ... | @@ -5736,8 +5681,8 @@ fn containerDecl( |
| 5736 | _ = try astgen.scanContainer(&namespace, container_decl.ast.members, .@"enum"); | 5681 | _ = try astgen.scanContainer(&namespace, container_decl.ast.members, .@"enum"); |
| 5737 | namespace.base.tag = .namespace; | 5682 | namespace.base.tag = .namespace; |
| 5738 | 5683 | ||
| 5739 | const arg_inst: Zir.Inst.Ref = if (container_decl.ast.arg != 0) | 5684 | const arg_inst: Zir.Inst.Ref = if (container_decl.ast.arg.unwrap()) |arg| |
| 5740 | try comptimeExpr(&block_scope, &namespace.base, coerced_type_ri, container_decl.ast.arg, .type) | 5685 | try comptimeExpr(&block_scope, &namespace.base, coerced_type_ri, arg, .type) |
| 5741 | else | 5686 | else |
| 5742 | .none; | 5687 | .none; |
| 5743 | 5688 | ||
| ... | @@ -5749,31 +5694,31 @@ fn containerDecl( | ... | @@ -5749,31 +5694,31 @@ fn containerDecl( |
| 5749 | const old_hasher = astgen.src_hasher; | 5694 | const old_hasher = astgen.src_hasher; |
| 5750 | defer astgen.src_hasher = old_hasher; | 5695 | defer astgen.src_hasher = old_hasher; |
| 5751 | astgen.src_hasher = std.zig.SrcHasher.init(.{}); | 5696 | astgen.src_hasher = std.zig.SrcHasher.init(.{}); |
| 5752 | if (container_decl.ast.arg != 0) { | 5697 | if (container_decl.ast.arg.unwrap()) |arg| { |
| 5753 | astgen.src_hasher.update(tree.getNodeSource(container_decl.ast.arg)); | 5698 | astgen.src_hasher.update(tree.getNodeSource(arg)); |
| 5754 | } | 5699 | } |
| 5755 | astgen.src_hasher.update(&.{@intFromBool(nonexhaustive)}); | 5700 | astgen.src_hasher.update(&.{@intFromBool(nonexhaustive)}); |
| 5756 | 5701 | ||
| 5757 | for (container_decl.ast.members) |member_node| { | 5702 | for (container_decl.ast.members) |member_node| { |
| 5758 | if (member_node == counts.nonexhaustive_node) | 5703 | if (member_node.toOptional() == counts.nonexhaustive_node) |
| 5759 | continue; | 5704 | continue; |
| 5760 | astgen.src_hasher.update(tree.getNodeSource(member_node)); | 5705 | astgen.src_hasher.update(tree.getNodeSource(member_node)); |
| 5761 | var member = switch (try containerMember(&block_scope, &namespace.base, &wip_members, member_node)) { | 5706 | var member = switch (try containerMember(&block_scope, &namespace.base, &wip_members, member_node)) { |
| 5762 | .decl => continue, | 5707 | .decl => continue, |
| 5763 | .field => |field| field, | 5708 | .field => |field| field, |
| 5764 | }; | 5709 | }; |
| 5765 | member.convertToNonTupleLike(astgen.tree.nodes); | 5710 | member.convertToNonTupleLike(astgen.tree); |
| 5766 | assert(member.comptime_token == null); | 5711 | assert(member.comptime_token == null); |
| 5767 | assert(member.ast.type_expr == 0); | 5712 | assert(member.ast.type_expr == .none); |
| 5768 | assert(member.ast.align_expr == 0); | 5713 | assert(member.ast.align_expr == .none); |
| 5769 | 5714 | ||
| 5770 | const field_name = try astgen.identAsString(member.ast.main_token); | 5715 | const field_name = try astgen.identAsString(member.ast.main_token); |
| 5771 | wip_members.appendToField(@intFromEnum(field_name)); | 5716 | wip_members.appendToField(@intFromEnum(field_name)); |
| 5772 | 5717 | ||
| 5773 | const have_value = member.ast.value_expr != 0; | 5718 | const have_value = member.ast.value_expr != .none; |
| 5774 | wip_members.nextField(bits_per_field, .{have_value}); | 5719 | wip_members.nextField(bits_per_field, .{have_value}); |
| 5775 | 5720 | ||
| 5776 | if (have_value) { | 5721 | if (member.ast.value_expr.unwrap()) |value_expr| { |
| 5777 | if (arg_inst == .none) { | 5722 | if (arg_inst == .none) { |
| 5778 | return astgen.failNodeNotes( | 5723 | return astgen.failNodeNotes( |
| 5779 | node, | 5724 | node, |
| ... | @@ -5781,14 +5726,14 @@ fn containerDecl( | ... | @@ -5781,14 +5726,14 @@ fn containerDecl( |
| 5781 | .{}, | 5726 | .{}, |
| 5782 | &[_]u32{ | 5727 | &[_]u32{ |
| 5783 | try astgen.errNoteNode( | 5728 | try astgen.errNoteNode( |
| 5784 | member.ast.value_expr, | 5729 | value_expr, |
| 5785 | "tag value specified here", | 5730 | "tag value specified here", |
| 5786 | .{}, | 5731 | .{}, |
| 5787 | ), | 5732 | ), |
| 5788 | }, | 5733 | }, |
| 5789 | ); | 5734 | ); |
| 5790 | } | 5735 | } |
| 5791 | const tag_value_inst = try expr(&block_scope, &namespace.base, .{ .rl = .{ .ty = arg_inst } }, member.ast.value_expr); | 5736 | const tag_value_inst = try expr(&block_scope, &namespace.base, .{ .rl = .{ .ty = arg_inst } }, value_expr); |
| 5792 | wip_members.appendToField(@intFromEnum(tag_value_inst)); | 5737 | wip_members.appendToField(@intFromEnum(tag_value_inst)); |
| 5793 | } | 5738 | } |
| 5794 | } | 5739 | } |
| ... | @@ -5828,7 +5773,7 @@ fn containerDecl( | ... | @@ -5828,7 +5773,7 @@ fn containerDecl( |
| 5828 | return rvalue(gz, ri, decl_inst.toRef(), node); | 5773 | return rvalue(gz, ri, decl_inst.toRef(), node); |
| 5829 | }, | 5774 | }, |
| 5830 | .keyword_opaque => { | 5775 | .keyword_opaque => { |
| 5831 | assert(container_decl.ast.arg == 0); | 5776 | assert(container_decl.ast.arg == .none); |
| 5832 | 5777 | ||
| 5833 | const decl_inst = try gz.reserveInstructionIndex(); | 5778 | const decl_inst = try gz.reserveInstructionIndex(); |
| 5834 | 5779 | ||
| ... | @@ -5899,9 +5844,7 @@ fn containerMember( | ... | @@ -5899,9 +5844,7 @@ fn containerMember( |
| 5899 | ) InnerError!ContainerMemberResult { | 5844 | ) InnerError!ContainerMemberResult { |
| 5900 | const astgen = gz.astgen; | 5845 | const astgen = gz.astgen; |
| 5901 | const tree = astgen.tree; | 5846 | const tree = astgen.tree; |
| 5902 | const node_tags = tree.nodes.items(.tag); | 5847 | switch (tree.nodeTag(member_node)) { |
| 5903 | const node_datas = tree.nodes.items(.data); | ||
| 5904 | switch (node_tags[member_node]) { | ||
| 5905 | .container_field_init, | 5848 | .container_field_init, |
| 5906 | .container_field_align, | 5849 | .container_field_align, |
| 5907 | .container_field, | 5850 | .container_field, |
| ... | @@ -5915,7 +5858,11 @@ fn containerMember( | ... | @@ -5915,7 +5858,11 @@ fn containerMember( |
| 5915 | => { | 5858 | => { |
| 5916 | var buf: [1]Ast.Node.Index = undefined; | 5859 | var buf: [1]Ast.Node.Index = undefined; |
| 5917 | const full = tree.fullFnProto(&buf, member_node).?; | 5860 | const full = tree.fullFnProto(&buf, member_node).?; |
| 5918 | const body = if (node_tags[member_node] == .fn_decl) node_datas[member_node].rhs else 0; | 5861 | |
| 5862 | const body: Ast.Node.OptionalIndex = if (tree.nodeTag(member_node) == .fn_decl) | ||
| 5863 | tree.nodeData(member_node).node_and_node[1].toOptional() | ||
| 5864 | else | ||
| 5865 | .none; | ||
| 5919 | 5866 | ||
| 5920 | const prev_decl_index = wip_members.decl_index; | 5867 | const prev_decl_index = wip_members.decl_index; |
| 5921 | astgen.fnDecl(gz, scope, wip_members, member_node, body, full) catch |err| switch (err) { | 5868 | astgen.fnDecl(gz, scope, wip_members, member_node, body, full) catch |err| switch (err) { |
| ... | @@ -5986,12 +5933,7 @@ fn containerMember( | ... | @@ -5986,12 +5933,7 @@ fn containerMember( |
| 5986 | .@"usingnamespace", | 5933 | .@"usingnamespace", |
| 5987 | .empty, | 5934 | .empty, |
| 5988 | member_node, | 5935 | member_node, |
| 5989 | is_pub: { | 5936 | tree.isTokenPrecededByTags(tree.nodeMainToken(member_node), &.{.keyword_pub}), |
| 5990 | const main_tokens = tree.nodes.items(.main_token); | ||
| 5991 | const token_tags = tree.tokens.items(.tag); | ||
| 5992 | const main_token = main_tokens[member_node]; | ||
| 5993 | break :is_pub main_token > 0 and token_tags[main_token - 1] == .keyword_pub; | ||
| 5994 | }, | ||
| 5995 | ); | 5937 | ); |
| 5996 | }, | 5938 | }, |
| 5997 | }; | 5939 | }; |
| ... | @@ -6025,8 +5967,6 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi | ... | @@ -6025,8 +5967,6 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi |
| 6025 | const astgen = gz.astgen; | 5967 | const astgen = gz.astgen; |
| 6026 | const gpa = astgen.gpa; | 5968 | const gpa = astgen.gpa; |
| 6027 | const tree = astgen.tree; | 5969 | const tree = astgen.tree; |
| 6028 | const main_tokens = tree.nodes.items(.main_token); | ||
| 6029 | const token_tags = tree.tokens.items(.tag); | ||
| 6030 | 5970 | ||
| 6031 | const payload_index = try reserveExtra(astgen, @typeInfo(Zir.Inst.ErrorSetDecl).@"struct".fields.len); | 5971 | const payload_index = try reserveExtra(astgen, @typeInfo(Zir.Inst.ErrorSetDecl).@"struct".fields.len); |
| 6032 | var fields_len: usize = 0; | 5972 | var fields_len: usize = 0; |
| ... | @@ -6034,10 +5974,10 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi | ... | @@ -6034,10 +5974,10 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi |
| 6034 | var idents: std.AutoHashMapUnmanaged(Zir.NullTerminatedString, Ast.TokenIndex) = .empty; | 5974 | var idents: std.AutoHashMapUnmanaged(Zir.NullTerminatedString, Ast.TokenIndex) = .empty; |
| 6035 | defer idents.deinit(gpa); | 5975 | defer idents.deinit(gpa); |
| 6036 | 5976 | ||
| 6037 | const error_token = main_tokens[node]; | 5977 | const error_token = tree.nodeMainToken(node); |
| 6038 | var tok_i = error_token + 2; | 5978 | var tok_i = error_token + 2; |
| 6039 | while (true) : (tok_i += 1) { | 5979 | while (true) : (tok_i += 1) { |
| 6040 | switch (token_tags[tok_i]) { | 5980 | switch (tree.tokenTag(tok_i)) { |
| 6041 | .doc_comment, .comma => {}, | 5981 | .doc_comment, .comma => {}, |
| 6042 | .identifier => { | 5982 | .identifier => { |
| 6043 | const str_index = try astgen.identAsString(tok_i); | 5983 | const str_index = try astgen.identAsString(tok_i); |
| ... | @@ -6089,10 +6029,10 @@ fn tryExpr( | ... | @@ -6089,10 +6029,10 @@ fn tryExpr( |
| 6089 | return astgen.failNode(node, "'try' outside function scope", .{}); | 6029 | return astgen.failNode(node, "'try' outside function scope", .{}); |
| 6090 | }; | 6030 | }; |
| 6091 | 6031 | ||
| 6092 | if (parent_gz.any_defer_node != 0) { | 6032 | if (parent_gz.any_defer_node.unwrap()) |any_defer_node| { |
| 6093 | return astgen.failNodeNotes(node, "'try' not allowed inside defer expression", .{}, &.{ | 6033 | return astgen.failNodeNotes(node, "'try' not allowed inside defer expression", .{}, &.{ |
| 6094 | try astgen.errNoteNode( | 6034 | try astgen.errNoteNode( |
| 6095 | parent_gz.any_defer_node, | 6035 | any_defer_node, |
| 6096 | "defer expression here", | 6036 | "defer expression here", |
| 6097 | .{}, | 6037 | .{}, |
| 6098 | ), | 6038 | ), |
| ... | @@ -6155,16 +6095,16 @@ fn orelseCatchExpr( | ... | @@ -6155,16 +6095,16 @@ fn orelseCatchExpr( |
| 6155 | scope: *Scope, | 6095 | scope: *Scope, |
| 6156 | ri: ResultInfo, | 6096 | ri: ResultInfo, |
| 6157 | node: Ast.Node.Index, | 6097 | node: Ast.Node.Index, |
| 6158 | lhs: Ast.Node.Index, | ||
| 6159 | cond_op: Zir.Inst.Tag, | 6098 | cond_op: Zir.Inst.Tag, |
| 6160 | unwrap_op: Zir.Inst.Tag, | 6099 | unwrap_op: Zir.Inst.Tag, |
| 6161 | unwrap_code_op: Zir.Inst.Tag, | 6100 | unwrap_code_op: Zir.Inst.Tag, |
| 6162 | rhs: Ast.Node.Index, | ||
| 6163 | payload_token: ?Ast.TokenIndex, | 6101 | payload_token: ?Ast.TokenIndex, |
| 6164 | ) InnerError!Zir.Inst.Ref { | 6102 | ) InnerError!Zir.Inst.Ref { |
| 6165 | const astgen = parent_gz.astgen; | 6103 | const astgen = parent_gz.astgen; |
| 6166 | const tree = astgen.tree; | 6104 | const tree = astgen.tree; |
| 6167 | 6105 | ||
| 6106 | const lhs, const rhs = tree.nodeData(node).node_and_node; | ||
| 6107 | |||
| 6168 | const need_rl = astgen.nodes_need_rl.contains(node); | 6108 | const need_rl = astgen.nodes_need_rl.contains(node); |
| 6169 | const block_ri: ResultInfo = if (need_rl) ri else .{ | 6109 | const block_ri: ResultInfo = if (need_rl) ri else .{ |
| 6170 | .rl = switch (ri.rl) { | 6110 | .rl = switch (ri.rl) { |
| ... | @@ -6297,12 +6237,8 @@ fn addFieldAccess( | ... | @@ -6297,12 +6237,8 @@ fn addFieldAccess( |
| 6297 | ) InnerError!Zir.Inst.Ref { | 6237 | ) InnerError!Zir.Inst.Ref { |
| 6298 | const astgen = gz.astgen; | 6238 | const astgen = gz.astgen; |
| 6299 | const tree = astgen.tree; | 6239 | const tree = astgen.tree; |
| 6300 | const main_tokens = tree.nodes.items(.main_token); | ||
| 6301 | const node_datas = tree.nodes.items(.data); | ||
| 6302 | 6240 | ||
| 6303 | const object_node = node_datas[node].lhs; | 6241 | const object_node, const field_ident = tree.nodeData(node).node_and_token; |
| 6304 | const dot_token = main_tokens[node]; | ||
| 6305 | const field_ident = dot_token + 1; | ||
| 6306 | const str_index = try astgen.identAsString(field_ident); | 6242 | const str_index = try astgen.identAsString(field_ident); |
| 6307 | const lhs = try expr(gz, scope, lhs_ri, object_node); | 6243 | const lhs = try expr(gz, scope, lhs_ri, object_node); |
| 6308 | 6244 | ||
| ... | @@ -6322,24 +6258,25 @@ fn arrayAccess( | ... | @@ -6322,24 +6258,25 @@ fn arrayAccess( |
| 6322 | node: Ast.Node.Index, | 6258 | node: Ast.Node.Index, |
| 6323 | ) InnerError!Zir.Inst.Ref { | 6259 | ) InnerError!Zir.Inst.Ref { |
| 6324 | const tree = gz.astgen.tree; | 6260 | const tree = gz.astgen.tree; |
| 6325 | const node_datas = tree.nodes.items(.data); | ||
| 6326 | switch (ri.rl) { | 6261 | switch (ri.rl) { |
| 6327 | .ref, .ref_coerced_ty => { | 6262 | .ref, .ref_coerced_ty => { |
| 6328 | const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs); | 6263 | const lhs_node, const rhs_node = tree.nodeData(node).node_and_node; |
| 6264 | const lhs = try expr(gz, scope, .{ .rl = .ref }, lhs_node); | ||
| 6329 | 6265 | ||
| 6330 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | 6266 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); |
| 6331 | 6267 | ||
| 6332 | const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[node].rhs); | 6268 | const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, rhs_node); |
| 6333 | try emitDbgStmt(gz, cursor); | 6269 | try emitDbgStmt(gz, cursor); |
| 6334 | 6270 | ||
| 6335 | return gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }); | 6271 | return gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }); |
| 6336 | }, | 6272 | }, |
| 6337 | else => { | 6273 | else => { |
| 6338 | const lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs); | 6274 | const lhs_node, const rhs_node = tree.nodeData(node).node_and_node; |
| 6275 | const lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node); | ||
| 6339 | 6276 | ||
| 6340 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | 6277 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); |
| 6341 | 6278 | ||
| 6342 | const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[node].rhs); | 6279 | const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, rhs_node); |
| 6343 | try emitDbgStmt(gz, cursor); | 6280 | try emitDbgStmt(gz, cursor); |
| 6344 | 6281 | ||
| 6345 | return rvalue(gz, ri, try gz.addPlNode(.elem_val_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }), node); | 6282 | return rvalue(gz, ri, try gz.addPlNode(.elem_val_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }), node); |
| ... | @@ -6356,22 +6293,22 @@ fn simpleBinOp( | ... | @@ -6356,22 +6293,22 @@ fn simpleBinOp( |
| 6356 | ) InnerError!Zir.Inst.Ref { | 6293 | ) InnerError!Zir.Inst.Ref { |
| 6357 | const astgen = gz.astgen; | 6294 | const astgen = gz.astgen; |
| 6358 | const tree = astgen.tree; | 6295 | const tree = astgen.tree; |
| 6359 | const node_datas = tree.nodes.items(.data); | 6296 | |
| 6297 | const lhs_node, const rhs_node = tree.nodeData(node).node_and_node; | ||
| 6360 | 6298 | ||
| 6361 | if (op_inst_tag == .cmp_neq or op_inst_tag == .cmp_eq) { | 6299 | if (op_inst_tag == .cmp_neq or op_inst_tag == .cmp_eq) { |
| 6362 | const node_tags = tree.nodes.items(.tag); | ||
| 6363 | const str = if (op_inst_tag == .cmp_eq) "==" else "!="; | 6300 | const str = if (op_inst_tag == .cmp_eq) "==" else "!="; |
| 6364 | if (node_tags[node_datas[node].lhs] == .string_literal or | 6301 | if (tree.nodeTag(lhs_node) == .string_literal or |
| 6365 | node_tags[node_datas[node].rhs] == .string_literal) | 6302 | tree.nodeTag(rhs_node) == .string_literal) |
| 6366 | return astgen.failNode(node, "cannot compare strings with {s}", .{str}); | 6303 | return astgen.failNode(node, "cannot compare strings with {s}", .{str}); |
| 6367 | } | 6304 | } |
| 6368 | 6305 | ||
| 6369 | const lhs = try reachableExpr(gz, scope, .{ .rl = .none }, node_datas[node].lhs, node); | 6306 | const lhs = try reachableExpr(gz, scope, .{ .rl = .none }, lhs_node, node); |
| 6370 | const cursor = switch (op_inst_tag) { | 6307 | const cursor = switch (op_inst_tag) { |
| 6371 | .add, .sub, .mul, .div, .mod_rem => maybeAdvanceSourceCursorToMainToken(gz, node), | 6308 | .add, .sub, .mul, .div, .mod_rem => maybeAdvanceSourceCursorToMainToken(gz, node), |
| 6372 | else => undefined, | 6309 | else => undefined, |
| 6373 | }; | 6310 | }; |
| 6374 | const rhs = try reachableExpr(gz, scope, .{ .rl = .none }, node_datas[node].rhs, node); | 6311 | const rhs = try reachableExpr(gz, scope, .{ .rl = .none }, rhs_node, node); |
| 6375 | 6312 | ||
| 6376 | switch (op_inst_tag) { | 6313 | switch (op_inst_tag) { |
| 6377 | .add, .sub, .mul, .div, .mod_rem => { | 6314 | .add, .sub, .mul, .div, .mod_rem => { |
| ... | @@ -6405,16 +6342,16 @@ fn boolBinOp( | ... | @@ -6405,16 +6342,16 @@ fn boolBinOp( |
| 6405 | ) InnerError!Zir.Inst.Ref { | 6342 | ) InnerError!Zir.Inst.Ref { |
| 6406 | const astgen = gz.astgen; | 6343 | const astgen = gz.astgen; |
| 6407 | const tree = astgen.tree; | 6344 | const tree = astgen.tree; |
| 6408 | const node_datas = tree.nodes.items(.data); | ||
| 6409 | 6345 | ||
| 6410 | const lhs = try expr(gz, scope, coerced_bool_ri, node_datas[node].lhs); | 6346 | const lhs_node, const rhs_node = tree.nodeData(node).node_and_node; |
| 6347 | const lhs = try expr(gz, scope, coerced_bool_ri, lhs_node); | ||
| 6411 | const bool_br = (try gz.addPlNodePayloadIndex(zir_tag, node, undefined)).toIndex().?; | 6348 | const bool_br = (try gz.addPlNodePayloadIndex(zir_tag, node, undefined)).toIndex().?; |
| 6412 | 6349 | ||
| 6413 | var rhs_scope = gz.makeSubBlock(scope); | 6350 | var rhs_scope = gz.makeSubBlock(scope); |
| 6414 | defer rhs_scope.unstack(); | 6351 | defer rhs_scope.unstack(); |
| 6415 | const rhs = try fullBodyExpr(&rhs_scope, &rhs_scope.base, coerced_bool_ri, node_datas[node].rhs, .allow_branch_hint); | 6352 | const rhs = try fullBodyExpr(&rhs_scope, &rhs_scope.base, coerced_bool_ri, rhs_node, .allow_branch_hint); |
| 6416 | if (!gz.refIsNoReturn(rhs)) { | 6353 | if (!gz.refIsNoReturn(rhs)) { |
| 6417 | _ = try rhs_scope.addBreakWithSrcNode(.break_inline, bool_br, rhs, node_datas[node].rhs); | 6354 | _ = try rhs_scope.addBreakWithSrcNode(.break_inline, bool_br, rhs, rhs_node); |
| 6418 | } | 6355 | } |
| 6419 | try rhs_scope.setBoolBrBody(bool_br, lhs); | 6356 | try rhs_scope.setBoolBrBody(bool_br, lhs); |
| 6420 | 6357 | ||
| ... | @@ -6431,7 +6368,6 @@ fn ifExpr( | ... | @@ -6431,7 +6368,6 @@ fn ifExpr( |
| 6431 | ) InnerError!Zir.Inst.Ref { | 6368 | ) InnerError!Zir.Inst.Ref { |
| 6432 | const astgen = parent_gz.astgen; | 6369 | const astgen = parent_gz.astgen; |
| 6433 | const tree = astgen.tree; | 6370 | const tree = astgen.tree; |
| 6434 | const token_tags = tree.tokens.items(.tag); | ||
| 6435 | 6371 | ||
| 6436 | const do_err_trace = astgen.fn_block != null and if_full.error_token != null; | 6372 | const do_err_trace = astgen.fn_block != null and if_full.error_token != null; |
| 6437 | 6373 | ||
| ... | @@ -6454,7 +6390,7 @@ fn ifExpr( | ... | @@ -6454,7 +6390,7 @@ fn ifExpr( |
| 6454 | defer block_scope.unstack(); | 6390 | defer block_scope.unstack(); |
| 6455 | 6391 | ||
| 6456 | const payload_is_ref = if (if_full.payload_token) |payload_token| | 6392 | const payload_is_ref = if (if_full.payload_token) |payload_token| |
| 6457 | token_tags[payload_token] == .asterisk | 6393 | tree.tokenTag(payload_token) == .asterisk |
| 6458 | else | 6394 | else |
| 6459 | false; | 6395 | false; |
| 6460 | 6396 | ||
| ... | @@ -6532,7 +6468,7 @@ fn ifExpr( | ... | @@ -6532,7 +6468,7 @@ fn ifExpr( |
| 6532 | break :s &then_scope.base; | 6468 | break :s &then_scope.base; |
| 6533 | } | 6469 | } |
| 6534 | } else if (if_full.payload_token) |payload_token| { | 6470 | } else if (if_full.payload_token) |payload_token| { |
| 6535 | const ident_token = if (payload_is_ref) payload_token + 1 else payload_token; | 6471 | const ident_token = payload_token + @intFromBool(payload_is_ref); |
| 6536 | const tag: Zir.Inst.Tag = if (payload_is_ref) | 6472 | const tag: Zir.Inst.Tag = if (payload_is_ref) |
| 6537 | .optional_payload_unsafe_ptr | 6473 | .optional_payload_unsafe_ptr |
| 6538 | else | 6474 | else |
| ... | @@ -6574,8 +6510,7 @@ fn ifExpr( | ... | @@ -6574,8 +6510,7 @@ fn ifExpr( |
| 6574 | if (do_err_trace and nodeMayAppendToErrorTrace(tree, if_full.ast.cond_expr)) | 6510 | if (do_err_trace and nodeMayAppendToErrorTrace(tree, if_full.ast.cond_expr)) |
| 6575 | _ = try else_scope.addSaveErrRetIndex(.always); | 6511 | _ = try else_scope.addSaveErrRetIndex(.always); |
| 6576 | 6512 | ||
| 6577 | const else_node = if_full.ast.else_expr; | 6513 | if (if_full.ast.else_expr.unwrap()) |else_node| { |
| 6578 | if (else_node != 0) { | ||
| 6579 | const sub_scope = s: { | 6514 | const sub_scope = s: { |
| 6580 | if (if_full.error_token) |error_token| { | 6515 | if (if_full.error_token) |error_token| { |
| 6581 | const tag: Zir.Inst.Tag = if (payload_is_ref) | 6516 | const tag: Zir.Inst.Tag = if (payload_is_ref) |
| ... | @@ -6663,8 +6598,6 @@ fn whileExpr( | ... | @@ -6663,8 +6598,6 @@ fn whileExpr( |
| 6663 | ) InnerError!Zir.Inst.Ref { | 6598 | ) InnerError!Zir.Inst.Ref { |
| 6664 | const astgen = parent_gz.astgen; | 6599 | const astgen = parent_gz.astgen; |
| 6665 | const tree = astgen.tree; | 6600 | const tree = astgen.tree; |
| 6666 | const token_tags = tree.tokens.items(.tag); | ||
| 6667 | const token_starts = tree.tokens.items(.start); | ||
| 6668 | 6601 | ||
| 6669 | const need_rl = astgen.nodes_need_rl.contains(node); | 6602 | const need_rl = astgen.nodes_need_rl.contains(node); |
| 6670 | const block_ri: ResultInfo = if (need_rl) ri else .{ | 6603 | const block_ri: ResultInfo = if (need_rl) ri else .{ |
| ... | @@ -6701,7 +6634,7 @@ fn whileExpr( | ... | @@ -6701,7 +6634,7 @@ fn whileExpr( |
| 6701 | defer cond_scope.unstack(); | 6634 | defer cond_scope.unstack(); |
| 6702 | 6635 | ||
| 6703 | const payload_is_ref = if (while_full.payload_token) |payload_token| | 6636 | const payload_is_ref = if (while_full.payload_token) |payload_token| |
| 6704 | token_tags[payload_token] == .asterisk | 6637 | tree.tokenTag(payload_token) == .asterisk |
| 6705 | else | 6638 | else |
| 6706 | false; | 6639 | false; |
| 6707 | 6640 | ||
| ... | @@ -6787,7 +6720,6 @@ fn whileExpr( | ... | @@ -6787,7 +6720,6 @@ fn whileExpr( |
| 6787 | break :s &then_scope.base; | 6720 | break :s &then_scope.base; |
| 6788 | } | 6721 | } |
| 6789 | } else if (while_full.payload_token) |payload_token| { | 6722 | } else if (while_full.payload_token) |payload_token| { |
| 6790 | const ident_token = if (payload_is_ref) payload_token + 1 else payload_token; | ||
| 6791 | const tag: Zir.Inst.Tag = if (payload_is_ref) | 6723 | const tag: Zir.Inst.Tag = if (payload_is_ref) |
| 6792 | .optional_payload_unsafe_ptr | 6724 | .optional_payload_unsafe_ptr |
| 6793 | else | 6725 | else |
| ... | @@ -6795,6 +6727,7 @@ fn whileExpr( | ... | @@ -6795,6 +6727,7 @@ fn whileExpr( |
| 6795 | // will add this instruction to then_scope.instructions below | 6727 | // will add this instruction to then_scope.instructions below |
| 6796 | const payload_inst = try then_scope.makeUnNode(tag, cond.inst, while_full.ast.cond_expr); | 6728 | const payload_inst = try then_scope.makeUnNode(tag, cond.inst, while_full.ast.cond_expr); |
| 6797 | opt_payload_inst = payload_inst.toOptional(); | 6729 | opt_payload_inst = payload_inst.toOptional(); |
| 6730 | const ident_token = payload_token + @intFromBool(payload_is_ref); | ||
| 6798 | const ident_name = try astgen.identAsString(ident_token); | 6731 | const ident_name = try astgen.identAsString(ident_token); |
| 6799 | const ident_bytes = tree.tokenSlice(ident_token); | 6732 | const ident_bytes = tree.tokenSlice(ident_token); |
| 6800 | if (mem.eql(u8, "_", ident_bytes)) { | 6733 | if (mem.eql(u8, "_", ident_bytes)) { |
| ... | @@ -6849,8 +6782,8 @@ fn whileExpr( | ... | @@ -6849,8 +6782,8 @@ fn whileExpr( |
| 6849 | // are no jumps to it. This happens when the last statement of a while body is noreturn | 6782 | // are no jumps to it. This happens when the last statement of a while body is noreturn |
| 6850 | // and there are no `continue` statements. | 6783 | // and there are no `continue` statements. |
| 6851 | // Tracking issue: https://github.com/ziglang/zig/issues/9185 | 6784 | // Tracking issue: https://github.com/ziglang/zig/issues/9185 |
| 6852 | if (while_full.ast.cont_expr != 0) { | 6785 | if (while_full.ast.cont_expr.unwrap()) |cont_expr| { |
| 6853 | _ = try unusedResultExpr(&then_scope, then_sub_scope, while_full.ast.cont_expr); | 6786 | _ = try unusedResultExpr(&then_scope, then_sub_scope, cont_expr); |
| 6854 | } | 6787 | } |
| 6855 | 6788 | ||
| 6856 | continue_scope.instructions_top = continue_scope.instructions.items.len; | 6789 | continue_scope.instructions_top = continue_scope.instructions.items.len; |
| ... | @@ -6862,7 +6795,7 @@ fn whileExpr( | ... | @@ -6862,7 +6795,7 @@ fn whileExpr( |
| 6862 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); | 6795 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| 6863 | const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break"; | 6796 | const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break"; |
| 6864 | if (!continue_scope.endsWithNoReturn()) { | 6797 | if (!continue_scope.endsWithNoReturn()) { |
| 6865 | astgen.advanceSourceCursor(token_starts[tree.lastToken(then_node)]); | 6798 | astgen.advanceSourceCursor(tree.tokenStart(tree.lastToken(then_node))); |
| 6866 | try emitDbgStmt(parent_gz, .{ astgen.source_line - parent_gz.decl_line, astgen.source_column }); | 6799 | try emitDbgStmt(parent_gz, .{ astgen.source_line - parent_gz.decl_line, astgen.source_column }); |
| 6867 | _ = try parent_gz.add(.{ | 6800 | _ = try parent_gz.add(.{ |
| 6868 | .tag = .extended, | 6801 | .tag = .extended, |
| ... | @@ -6880,8 +6813,7 @@ fn whileExpr( | ... | @@ -6880,8 +6813,7 @@ fn whileExpr( |
| 6880 | var else_scope = parent_gz.makeSubBlock(&cond_scope.base); | 6813 | var else_scope = parent_gz.makeSubBlock(&cond_scope.base); |
| 6881 | defer else_scope.unstack(); | 6814 | defer else_scope.unstack(); |
| 6882 | 6815 | ||
| 6883 | const else_node = while_full.ast.else_expr; | 6816 | if (while_full.ast.else_expr.unwrap()) |else_node| { |
| 6884 | if (else_node != 0) { | ||
| 6885 | const sub_scope = s: { | 6817 | const sub_scope = s: { |
| 6886 | if (while_full.error_token) |error_token| { | 6818 | if (while_full.error_token) |error_token| { |
| 6887 | const tag: Zir.Inst.Tag = if (payload_is_ref) | 6819 | const tag: Zir.Inst.Tag = if (payload_is_ref) |
| ... | @@ -6979,10 +6911,6 @@ fn forExpr( | ... | @@ -6979,10 +6911,6 @@ fn forExpr( |
| 6979 | try astgen.appendErrorTok(for_full.inline_token.?, "redundant inline keyword in comptime scope", .{}); | 6911 | try astgen.appendErrorTok(for_full.inline_token.?, "redundant inline keyword in comptime scope", .{}); |
| 6980 | } | 6912 | } |
| 6981 | const tree = astgen.tree; | 6913 | const tree = astgen.tree; |
| 6982 | const token_tags = tree.tokens.items(.tag); | ||
| 6983 | const token_starts = tree.tokens.items(.start); | ||
| 6984 | const node_tags = tree.nodes.items(.tag); | ||
| 6985 | const node_data = tree.nodes.items(.data); | ||
| 6986 | const gpa = astgen.gpa; | 6914 | const gpa = astgen.gpa; |
| 6987 | 6915 | ||
| 6988 | // For counters, this is the start value; for indexables, this is the base | 6916 | // For counters, this is the start value; for indexables, this is the base |
| ... | @@ -7012,7 +6940,7 @@ fn forExpr( | ... | @@ -7012,7 +6940,7 @@ fn forExpr( |
| 7012 | { | 6940 | { |
| 7013 | var capture_token = for_full.payload_token; | 6941 | var capture_token = for_full.payload_token; |
| 7014 | for (for_full.ast.inputs, indexables, lens) |input, *indexable_ref, *len_refs| { | 6942 | for (for_full.ast.inputs, indexables, lens) |input, *indexable_ref, *len_refs| { |
| 7015 | const capture_is_ref = token_tags[capture_token] == .asterisk; | 6943 | const capture_is_ref = tree.tokenTag(capture_token) == .asterisk; |
| 7016 | const ident_tok = capture_token + @intFromBool(capture_is_ref); | 6944 | const ident_tok = capture_token + @intFromBool(capture_is_ref); |
| 7017 | const is_discard = mem.eql(u8, tree.tokenSlice(ident_tok), "_"); | 6945 | const is_discard = mem.eql(u8, tree.tokenSlice(ident_tok), "_"); |
| 7018 | 6946 | ||
| ... | @@ -7023,16 +6951,15 @@ fn forExpr( | ... | @@ -7023,16 +6951,15 @@ fn forExpr( |
| 7023 | capture_token = ident_tok + 2; | 6951 | capture_token = ident_tok + 2; |
| 7024 | 6952 | ||
| 7025 | try emitDbgNode(parent_gz, input); | 6953 | try emitDbgNode(parent_gz, input); |
| 7026 | if (node_tags[input] == .for_range) { | 6954 | if (tree.nodeTag(input) == .for_range) { |
| 7027 | if (capture_is_ref) { | 6955 | if (capture_is_ref) { |
| 7028 | return astgen.failTok(ident_tok, "cannot capture reference to range", .{}); | 6956 | return astgen.failTok(ident_tok, "cannot capture reference to range", .{}); |
| 7029 | } | 6957 | } |
| 7030 | const start_node = node_data[input].lhs; | 6958 | const start_node, const end_node = tree.nodeData(input).node_and_opt_node; |
| 7031 | const start_val = try expr(parent_gz, scope, .{ .rl = .{ .ty = .usize_type } }, start_node); | 6959 | const start_val = try expr(parent_gz, scope, .{ .rl = .{ .ty = .usize_type } }, start_node); |
| 7032 | 6960 | ||
| 7033 | const end_node = node_data[input].rhs; | 6961 | const end_val = if (end_node.unwrap()) |end| |
| 7034 | const end_val = if (end_node != 0) | 6962 | try expr(parent_gz, scope, .{ .rl = .{ .ty = .usize_type } }, end) |
| 7035 | try expr(parent_gz, scope, .{ .rl = .{ .ty = .usize_type } }, node_data[input].rhs) | ||
| 7036 | else | 6963 | else |
| 7037 | .none; | 6964 | .none; |
| 7038 | 6965 | ||
| ... | @@ -7125,7 +7052,7 @@ fn forExpr( | ... | @@ -7125,7 +7052,7 @@ fn forExpr( |
| 7125 | var capture_token = for_full.payload_token; | 7052 | var capture_token = for_full.payload_token; |
| 7126 | var capture_sub_scope: *Scope = &then_scope.base; | 7053 | var capture_sub_scope: *Scope = &then_scope.base; |
| 7127 | for (for_full.ast.inputs, indexables, capture_scopes) |input, indexable_ref, *capture_scope| { | 7054 | for (for_full.ast.inputs, indexables, capture_scopes) |input, indexable_ref, *capture_scope| { |
| 7128 | const capture_is_ref = token_tags[capture_token] == .asterisk; | 7055 | const capture_is_ref = tree.tokenTag(capture_token) == .asterisk; |
| 7129 | const ident_tok = capture_token + @intFromBool(capture_is_ref); | 7056 | const ident_tok = capture_token + @intFromBool(capture_is_ref); |
| 7130 | const capture_name = tree.tokenSlice(ident_tok); | 7057 | const capture_name = tree.tokenSlice(ident_tok); |
| 7131 | // Skip over the comma, and on to the next capture (or the ending pipe character). | 7058 | // Skip over the comma, and on to the next capture (or the ending pipe character). |
| ... | @@ -7137,7 +7064,7 @@ fn forExpr( | ... | @@ -7137,7 +7064,7 @@ fn forExpr( |
| 7137 | try astgen.detectLocalShadowing(capture_sub_scope, name_str_index, ident_tok, capture_name, .capture); | 7064 | try astgen.detectLocalShadowing(capture_sub_scope, name_str_index, ident_tok, capture_name, .capture); |
| 7138 | 7065 | ||
| 7139 | const capture_inst = inst: { | 7066 | const capture_inst = inst: { |
| 7140 | const is_counter = node_tags[input] == .for_range; | 7067 | const is_counter = tree.nodeTag(input) == .for_range; |
| 7141 | 7068 | ||
| 7142 | if (indexable_ref == .none) { | 7069 | if (indexable_ref == .none) { |
| 7143 | // Special case: the main index can be used directly. | 7070 | // Special case: the main index can be used directly. |
| ... | @@ -7184,7 +7111,7 @@ fn forExpr( | ... | @@ -7184,7 +7111,7 @@ fn forExpr( |
| 7184 | 7111 | ||
| 7185 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); | 7112 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| 7186 | 7113 | ||
| 7187 | astgen.advanceSourceCursor(token_starts[tree.lastToken(then_node)]); | 7114 | astgen.advanceSourceCursor(tree.tokenStart(tree.lastToken(then_node))); |
| 7188 | try emitDbgStmt(parent_gz, .{ astgen.source_line - parent_gz.decl_line, astgen.source_column }); | 7115 | try emitDbgStmt(parent_gz, .{ astgen.source_line - parent_gz.decl_line, astgen.source_column }); |
| 7189 | _ = try parent_gz.add(.{ | 7116 | _ = try parent_gz.add(.{ |
| 7190 | .tag = .extended, | 7117 | .tag = .extended, |
| ... | @@ -7201,8 +7128,7 @@ fn forExpr( | ... | @@ -7201,8 +7128,7 @@ fn forExpr( |
| 7201 | var else_scope = parent_gz.makeSubBlock(&cond_scope.base); | 7128 | var else_scope = parent_gz.makeSubBlock(&cond_scope.base); |
| 7202 | defer else_scope.unstack(); | 7129 | defer else_scope.unstack(); |
| 7203 | 7130 | ||
| 7204 | const else_node = for_full.ast.else_expr; | 7131 | if (for_full.ast.else_expr.unwrap()) |else_node| { |
| 7205 | if (else_node != 0) { | ||
| 7206 | const sub_scope = &else_scope.base; | 7132 | const sub_scope = &else_scope.base; |
| 7207 | // Remove the continue block and break block so that `continue` and `break` | 7133 | // Remove the continue block and break block so that `continue` and `break` |
| 7208 | // control flow apply to outer loops; not this one. | 7134 | // control flow apply to outer loops; not this one. |
| ... | @@ -7270,10 +7196,6 @@ fn switchExprErrUnion( | ... | @@ -7270,10 +7196,6 @@ fn switchExprErrUnion( |
| 7270 | const astgen = parent_gz.astgen; | 7196 | const astgen = parent_gz.astgen; |
| 7271 | const gpa = astgen.gpa; | 7197 | const gpa = astgen.gpa; |
| 7272 | const tree = astgen.tree; | 7198 | const tree = astgen.tree; |
| 7273 | const node_datas = tree.nodes.items(.data); | ||
| 7274 | const node_tags = tree.nodes.items(.tag); | ||
| 7275 | const main_tokens = tree.nodes.items(.main_token); | ||
| 7276 | const token_tags = tree.tokens.items(.tag); | ||
| 7277 | 7199 | ||
| 7278 | const if_full = switch (node_ty) { | 7200 | const if_full = switch (node_ty) { |
| 7279 | .@"catch" => undefined, | 7201 | .@"catch" => undefined, |
| ... | @@ -7282,23 +7204,19 @@ fn switchExprErrUnion( | ... | @@ -7282,23 +7204,19 @@ fn switchExprErrUnion( |
| 7282 | 7204 | ||
| 7283 | const switch_node, const operand_node, const error_payload = switch (node_ty) { | 7205 | const switch_node, const operand_node, const error_payload = switch (node_ty) { |
| 7284 | .@"catch" => .{ | 7206 | .@"catch" => .{ |
| 7285 | node_datas[catch_or_if_node].rhs, | 7207 | tree.nodeData(catch_or_if_node).node_and_node[1], |
| 7286 | node_datas[catch_or_if_node].lhs, | 7208 | tree.nodeData(catch_or_if_node).node_and_node[0], |
| 7287 | main_tokens[catch_or_if_node] + 2, | 7209 | tree.nodeMainToken(catch_or_if_node) + 2, |
| 7288 | }, | 7210 | }, |
| 7289 | .@"if" => .{ | 7211 | .@"if" => .{ |
| 7290 | if_full.ast.else_expr, | 7212 | if_full.ast.else_expr.unwrap().?, |
| 7291 | if_full.ast.cond_expr, | 7213 | if_full.ast.cond_expr, |
| 7292 | if_full.error_token.?, | 7214 | if_full.error_token.?, |
| 7293 | }, | 7215 | }, |
| 7294 | }; | 7216 | }; |
| 7295 | assert(node_tags[switch_node] == .@"switch" or node_tags[switch_node] == .switch_comma); | 7217 | const switch_full = tree.fullSwitch(switch_node).?; |
| 7296 | 7218 | ||
| 7297 | const do_err_trace = astgen.fn_block != null; | 7219 | const do_err_trace = astgen.fn_block != null; |
| 7298 | |||
| 7299 | const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange); | ||
| 7300 | const case_nodes = tree.extra_data[extra.start..extra.end]; | ||
| 7301 | |||
| 7302 | const need_rl = astgen.nodes_need_rl.contains(catch_or_if_node); | 7220 | const need_rl = astgen.nodes_need_rl.contains(catch_or_if_node); |
| 7303 | const block_ri: ResultInfo = if (need_rl) ri else .{ | 7221 | const block_ri: ResultInfo = if (need_rl) ri else .{ |
| 7304 | .rl = switch (ri.rl) { | 7222 | .rl = switch (ri.rl) { |
| ... | @@ -7310,7 +7228,7 @@ fn switchExprErrUnion( | ... | @@ -7310,7 +7228,7 @@ fn switchExprErrUnion( |
| 7310 | }; | 7228 | }; |
| 7311 | 7229 | ||
| 7312 | const payload_is_ref = switch (node_ty) { | 7230 | const payload_is_ref = switch (node_ty) { |
| 7313 | .@"if" => if_full.payload_token != null and token_tags[if_full.payload_token.?] == .asterisk, | 7231 | .@"if" => if_full.payload_token != null and tree.tokenTag(if_full.payload_token.?) == .asterisk, |
| 7314 | .@"catch" => ri.rl == .ref or ri.rl == .ref_coerced_ty, | 7232 | .@"catch" => ri.rl == .ref or ri.rl == .ref_coerced_ty, |
| 7315 | }; | 7233 | }; |
| 7316 | 7234 | ||
| ... | @@ -7322,9 +7240,9 @@ fn switchExprErrUnion( | ... | @@ -7322,9 +7240,9 @@ fn switchExprErrUnion( |
| 7322 | var multi_cases_len: u32 = 0; | 7240 | var multi_cases_len: u32 = 0; |
| 7323 | var inline_cases_len: u32 = 0; | 7241 | var inline_cases_len: u32 = 0; |
| 7324 | var has_else = false; | 7242 | var has_else = false; |
| 7325 | var else_node: Ast.Node.Index = 0; | 7243 | var else_node: Ast.Node.OptionalIndex = .none; |
| 7326 | var else_src: ?Ast.TokenIndex = null; | 7244 | var else_src: ?Ast.TokenIndex = null; |
| 7327 | for (case_nodes) |case_node| { | 7245 | for (switch_full.ast.cases) |case_node| { |
| 7328 | const case = tree.fullSwitchCase(case_node).?; | 7246 | const case = tree.fullSwitchCase(case_node).?; |
| 7329 | 7247 | ||
| 7330 | if (case.ast.values.len == 0) { | 7248 | if (case.ast.values.len == 0) { |
| ... | @@ -7344,12 +7262,12 @@ fn switchExprErrUnion( | ... | @@ -7344,12 +7262,12 @@ fn switchExprErrUnion( |
| 7344 | ); | 7262 | ); |
| 7345 | } | 7263 | } |
| 7346 | has_else = true; | 7264 | has_else = true; |
| 7347 | else_node = case_node; | 7265 | else_node = case_node.toOptional(); |
| 7348 | else_src = case_src; | 7266 | else_src = case_src; |
| 7349 | continue; | 7267 | continue; |
| 7350 | } else if (case.ast.values.len == 1 and | 7268 | } else if (case.ast.values.len == 1 and |
| 7351 | node_tags[case.ast.values[0]] == .identifier and | 7269 | tree.nodeTag(case.ast.values[0]) == .identifier and |
| 7352 | mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_")) | 7270 | mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(case.ast.values[0])), "_")) |
| 7353 | { | 7271 | { |
| 7354 | const case_src = case.ast.arrow_token - 1; | 7272 | const case_src = case.ast.arrow_token - 1; |
| 7355 | return astgen.failTokNotes( | 7273 | return astgen.failTokNotes( |
| ... | @@ -7367,11 +7285,11 @@ fn switchExprErrUnion( | ... | @@ -7367,11 +7285,11 @@ fn switchExprErrUnion( |
| 7367 | } | 7285 | } |
| 7368 | 7286 | ||
| 7369 | for (case.ast.values) |val| { | 7287 | for (case.ast.values) |val| { |
| 7370 | if (node_tags[val] == .string_literal) | 7288 | if (tree.nodeTag(val) == .string_literal) |
| 7371 | return astgen.failNode(val, "cannot switch on strings", .{}); | 7289 | return astgen.failNode(val, "cannot switch on strings", .{}); |
| 7372 | } | 7290 | } |
| 7373 | 7291 | ||
| 7374 | if (case.ast.values.len == 1 and node_tags[case.ast.values[0]] != .switch_range) { | 7292 | if (case.ast.values.len == 1 and tree.nodeTag(case.ast.values[0]) != .switch_range) { |
| 7375 | scalar_cases_len += 1; | 7293 | scalar_cases_len += 1; |
| 7376 | } else { | 7294 | } else { |
| 7377 | multi_cases_len += 1; | 7295 | multi_cases_len += 1; |
| ... | @@ -7564,11 +7482,11 @@ fn switchExprErrUnion( | ... | @@ -7564,11 +7482,11 @@ fn switchExprErrUnion( |
| 7564 | var multi_case_index: u32 = 0; | 7482 | var multi_case_index: u32 = 0; |
| 7565 | var scalar_case_index: u32 = 0; | 7483 | var scalar_case_index: u32 = 0; |
| 7566 | var any_uses_err_capture = false; | 7484 | var any_uses_err_capture = false; |
| 7567 | for (case_nodes) |case_node| { | 7485 | for (switch_full.ast.cases) |case_node| { |
| 7568 | const case = tree.fullSwitchCase(case_node).?; | 7486 | const case = tree.fullSwitchCase(case_node).?; |
| 7569 | 7487 | ||
| 7570 | const is_multi_case = case.ast.values.len > 1 or | 7488 | const is_multi_case = case.ast.values.len > 1 or |
| 7571 | (case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .switch_range); | 7489 | (case.ast.values.len == 1 and tree.nodeTag(case.ast.values[0]) == .switch_range); |
| 7572 | 7490 | ||
| 7573 | var dbg_var_name: Zir.NullTerminatedString = .empty; | 7491 | var dbg_var_name: Zir.NullTerminatedString = .empty; |
| 7574 | var dbg_var_inst: Zir.Inst.Ref = undefined; | 7492 | var dbg_var_inst: Zir.Inst.Ref = undefined; |
| ... | @@ -7586,7 +7504,7 @@ fn switchExprErrUnion( | ... | @@ -7586,7 +7504,7 @@ fn switchExprErrUnion( |
| 7586 | }; | 7504 | }; |
| 7587 | 7505 | ||
| 7588 | const capture_token = case.payload_token orelse break :blk &err_scope.base; | 7506 | const capture_token = case.payload_token orelse break :blk &err_scope.base; |
| 7589 | if (token_tags[capture_token] != .identifier) { | 7507 | if (tree.tokenTag(capture_token) != .identifier) { |
| 7590 | return astgen.failTok(capture_token + 1, "error set cannot be captured by reference", .{}); | 7508 | return astgen.failTok(capture_token + 1, "error set cannot be captured by reference", .{}); |
| 7591 | } | 7509 | } |
| 7592 | 7510 | ||
| ... | @@ -7622,7 +7540,7 @@ fn switchExprErrUnion( | ... | @@ -7622,7 +7540,7 @@ fn switchExprErrUnion( |
| 7622 | // items | 7540 | // items |
| 7623 | var items_len: u32 = 0; | 7541 | var items_len: u32 = 0; |
| 7624 | for (case.ast.values) |item_node| { | 7542 | for (case.ast.values) |item_node| { |
| 7625 | if (node_tags[item_node] == .switch_range) continue; | 7543 | if (tree.nodeTag(item_node) == .switch_range) continue; |
| 7626 | items_len += 1; | 7544 | items_len += 1; |
| 7627 | 7545 | ||
| 7628 | const item_inst = try comptimeExpr(parent_gz, scope, item_ri, item_node, .switch_item); | 7546 | const item_inst = try comptimeExpr(parent_gz, scope, item_ri, item_node, .switch_item); |
| ... | @@ -7632,11 +7550,12 @@ fn switchExprErrUnion( | ... | @@ -7632,11 +7550,12 @@ fn switchExprErrUnion( |
| 7632 | // ranges | 7550 | // ranges |
| 7633 | var ranges_len: u32 = 0; | 7551 | var ranges_len: u32 = 0; |
| 7634 | for (case.ast.values) |range| { | 7552 | for (case.ast.values) |range| { |
| 7635 | if (node_tags[range] != .switch_range) continue; | 7553 | if (tree.nodeTag(range) != .switch_range) continue; |
| 7636 | ranges_len += 1; | 7554 | ranges_len += 1; |
| 7637 | 7555 | ||
| 7638 | const first = try comptimeExpr(parent_gz, scope, item_ri, node_datas[range].lhs, .switch_item); | 7556 | const first_node, const last_node = tree.nodeData(range).node_and_node; |
| 7639 | const last = try comptimeExpr(parent_gz, scope, item_ri, node_datas[range].rhs, .switch_item); | 7557 | const first = try comptimeExpr(parent_gz, scope, item_ri, first_node, .switch_item); |
| 7558 | const last = try comptimeExpr(parent_gz, scope, item_ri, last_node, .switch_item); | ||
| 7640 | try payloads.appendSlice(gpa, &[_]u32{ | 7559 | try payloads.appendSlice(gpa, &[_]u32{ |
| 7641 | @intFromEnum(first), @intFromEnum(last), | 7560 | @intFromEnum(first), @intFromEnum(last), |
| 7642 | }); | 7561 | }); |
| ... | @@ -7645,7 +7564,7 @@ fn switchExprErrUnion( | ... | @@ -7645,7 +7564,7 @@ fn switchExprErrUnion( |
| 7645 | payloads.items[header_index] = items_len; | 7564 | payloads.items[header_index] = items_len; |
| 7646 | payloads.items[header_index + 1] = ranges_len; | 7565 | payloads.items[header_index + 1] = ranges_len; |
| 7647 | break :blk header_index + 2; | 7566 | break :blk header_index + 2; |
| 7648 | } else if (case_node == else_node) blk: { | 7567 | } else if (case_node.toOptional() == else_node) blk: { |
| 7649 | payloads.items[case_table_start + 1] = header_index; | 7568 | payloads.items[case_table_start + 1] = header_index; |
| 7650 | try payloads.resize(gpa, header_index + 1); // body_len | 7569 | try payloads.resize(gpa, header_index + 1); // body_len |
| 7651 | break :blk header_index; | 7570 | break :blk header_index; |
| ... | @@ -7675,7 +7594,7 @@ fn switchExprErrUnion( | ... | @@ -7675,7 +7594,7 @@ fn switchExprErrUnion( |
| 7675 | const case_result = try fullBodyExpr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node, .allow_branch_hint); | 7594 | const case_result = try fullBodyExpr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node, .allow_branch_hint); |
| 7676 | // check capture_scope, not err_scope to avoid false positive unused error capture | 7595 | // check capture_scope, not err_scope to avoid false positive unused error capture |
| 7677 | try checkUsed(parent_gz, &case_scope.base, err_scope.parent); | 7596 | try checkUsed(parent_gz, &case_scope.base, err_scope.parent); |
| 7678 | const uses_err = err_scope.used != 0 or err_scope.discarded != 0; | 7597 | const uses_err = err_scope.used != .none or err_scope.discarded != .none; |
| 7679 | if (uses_err) { | 7598 | if (uses_err) { |
| 7680 | try case_scope.addDbgVar(.dbg_var_val, err_name, err_inst.toRef()); | 7599 | try case_scope.addDbgVar(.dbg_var_val, err_name, err_inst.toRef()); |
| 7681 | any_uses_err_capture = true; | 7600 | any_uses_err_capture = true; |
| ... | @@ -7775,10 +7694,6 @@ fn switchExpr( | ... | @@ -7775,10 +7694,6 @@ fn switchExpr( |
| 7775 | const astgen = parent_gz.astgen; | 7694 | const astgen = parent_gz.astgen; |
| 7776 | const gpa = astgen.gpa; | 7695 | const gpa = astgen.gpa; |
| 7777 | const tree = astgen.tree; | 7696 | const tree = astgen.tree; |
| 7778 | const node_datas = tree.nodes.items(.data); | ||
| 7779 | const node_tags = tree.nodes.items(.tag); | ||
| 7780 | const main_tokens = tree.nodes.items(.main_token); | ||
| 7781 | const token_tags = tree.tokens.items(.tag); | ||
| 7782 | const operand_node = switch_full.ast.condition; | 7697 | const operand_node = switch_full.ast.condition; |
| 7783 | const case_nodes = switch_full.ast.cases; | 7698 | const case_nodes = switch_full.ast.cases; |
| 7784 | 7699 | ||
| ... | @@ -7810,17 +7725,17 @@ fn switchExpr( | ... | @@ -7810,17 +7725,17 @@ fn switchExpr( |
| 7810 | var multi_cases_len: u32 = 0; | 7725 | var multi_cases_len: u32 = 0; |
| 7811 | var inline_cases_len: u32 = 0; | 7726 | var inline_cases_len: u32 = 0; |
| 7812 | var special_prong: Zir.SpecialProng = .none; | 7727 | var special_prong: Zir.SpecialProng = .none; |
| 7813 | var special_node: Ast.Node.Index = 0; | 7728 | var special_node: Ast.Node.OptionalIndex = .none; |
| 7814 | var else_src: ?Ast.TokenIndex = null; | 7729 | var else_src: ?Ast.TokenIndex = null; |
| 7815 | var underscore_src: ?Ast.TokenIndex = null; | 7730 | var underscore_src: ?Ast.TokenIndex = null; |
| 7816 | for (case_nodes) |case_node| { | 7731 | for (case_nodes) |case_node| { |
| 7817 | const case = tree.fullSwitchCase(case_node).?; | 7732 | const case = tree.fullSwitchCase(case_node).?; |
| 7818 | if (case.payload_token) |payload_token| { | 7733 | if (case.payload_token) |payload_token| { |
| 7819 | const ident = if (token_tags[payload_token] == .asterisk) blk: { | 7734 | const ident = if (tree.tokenTag(payload_token) == .asterisk) blk: { |
| 7820 | any_payload_is_ref = true; | 7735 | any_payload_is_ref = true; |
| 7821 | break :blk payload_token + 1; | 7736 | break :blk payload_token + 1; |
| 7822 | } else payload_token; | 7737 | } else payload_token; |
| 7823 | if (token_tags[ident + 1] == .comma) { | 7738 | if (tree.tokenTag(ident + 1) == .comma) { |
| 7824 | any_has_tag_capture = true; | 7739 | any_has_tag_capture = true; |
| 7825 | } | 7740 | } |
| 7826 | 7741 | ||
| ... | @@ -7868,13 +7783,13 @@ fn switchExpr( | ... | @@ -7868,13 +7783,13 @@ fn switchExpr( |
| 7868 | }, | 7783 | }, |
| 7869 | ); | 7784 | ); |
| 7870 | } | 7785 | } |
| 7871 | special_node = case_node; | 7786 | special_node = case_node.toOptional(); |
| 7872 | special_prong = .@"else"; | 7787 | special_prong = .@"else"; |
| 7873 | else_src = case_src; | 7788 | else_src = case_src; |
| 7874 | continue; | 7789 | continue; |
| 7875 | } else if (case.ast.values.len == 1 and | 7790 | } else if (case.ast.values.len == 1 and |
| 7876 | node_tags[case.ast.values[0]] == .identifier and | 7791 | tree.nodeTag(case.ast.values[0]) == .identifier and |
| 7877 | mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_")) | 7792 | mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(case.ast.values[0])), "_")) |
| 7878 | { | 7793 | { |
| 7879 | const case_src = case.ast.arrow_token - 1; | 7794 | const case_src = case.ast.arrow_token - 1; |
| 7880 | if (underscore_src) |src| { | 7795 | if (underscore_src) |src| { |
| ... | @@ -7912,18 +7827,18 @@ fn switchExpr( | ... | @@ -7912,18 +7827,18 @@ fn switchExpr( |
| 7912 | if (case.inline_token != null) { | 7827 | if (case.inline_token != null) { |
| 7913 | return astgen.failTok(case_src, "cannot inline '_' prong", .{}); | 7828 | return astgen.failTok(case_src, "cannot inline '_' prong", .{}); |
| 7914 | } | 7829 | } |
| 7915 | special_node = case_node; | 7830 | special_node = case_node.toOptional(); |
| 7916 | special_prong = .under; | 7831 | special_prong = .under; |
| 7917 | underscore_src = case_src; | 7832 | underscore_src = case_src; |
| 7918 | continue; | 7833 | continue; |
| 7919 | } | 7834 | } |
| 7920 | 7835 | ||
| 7921 | for (case.ast.values) |val| { | 7836 | for (case.ast.values) |val| { |
| 7922 | if (node_tags[val] == .string_literal) | 7837 | if (tree.nodeTag(val) == .string_literal) |
| 7923 | return astgen.failNode(val, "cannot switch on strings", .{}); | 7838 | return astgen.failNode(val, "cannot switch on strings", .{}); |
| 7924 | } | 7839 | } |
| 7925 | 7840 | ||
| 7926 | if (case.ast.values.len == 1 and node_tags[case.ast.values[0]] != .switch_range) { | 7841 | if (case.ast.values.len == 1 and tree.nodeTag(case.ast.values[0]) != .switch_range) { |
| 7927 | scalar_cases_len += 1; | 7842 | scalar_cases_len += 1; |
| 7928 | } else { | 7843 | } else { |
| 7929 | multi_cases_len += 1; | 7844 | multi_cases_len += 1; |
| ... | @@ -8012,7 +7927,7 @@ fn switchExpr( | ... | @@ -8012,7 +7927,7 @@ fn switchExpr( |
| 8012 | const case = tree.fullSwitchCase(case_node).?; | 7927 | const case = tree.fullSwitchCase(case_node).?; |
| 8013 | 7928 | ||
| 8014 | const is_multi_case = case.ast.values.len > 1 or | 7929 | const is_multi_case = case.ast.values.len > 1 or |
| 8015 | (case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .switch_range); | 7930 | (case.ast.values.len == 1 and tree.nodeTag(case.ast.values[0]) == .switch_range); |
| 8016 | 7931 | ||
| 8017 | var dbg_var_name: Zir.NullTerminatedString = .empty; | 7932 | var dbg_var_name: Zir.NullTerminatedString = .empty; |
| 8018 | var dbg_var_inst: Zir.Inst.Ref = undefined; | 7933 | var dbg_var_inst: Zir.Inst.Ref = undefined; |
| ... | @@ -8026,18 +7941,15 @@ fn switchExpr( | ... | @@ -8026,18 +7941,15 @@ fn switchExpr( |
| 8026 | 7941 | ||
| 8027 | const sub_scope = blk: { | 7942 | const sub_scope = blk: { |
| 8028 | const payload_token = case.payload_token orelse break :blk &case_scope.base; | 7943 | const payload_token = case.payload_token orelse break :blk &case_scope.base; |
| 8029 | const ident = if (token_tags[payload_token] == .asterisk) | 7944 | const capture_is_ref = tree.tokenTag(payload_token) == .asterisk; |
| 8030 | payload_token + 1 | 7945 | const ident = payload_token + @intFromBool(capture_is_ref); |
| 8031 | else | ||
| 8032 | payload_token; | ||
| 8033 | 7946 | ||
| 8034 | const is_ptr = ident != payload_token; | 7947 | capture = if (capture_is_ref) .by_ref else .by_val; |
| 8035 | capture = if (is_ptr) .by_ref else .by_val; | ||
| 8036 | 7948 | ||
| 8037 | const ident_slice = tree.tokenSlice(ident); | 7949 | const ident_slice = tree.tokenSlice(ident); |
| 8038 | var payload_sub_scope: *Scope = undefined; | 7950 | var payload_sub_scope: *Scope = undefined; |
| 8039 | if (mem.eql(u8, ident_slice, "_")) { | 7951 | if (mem.eql(u8, ident_slice, "_")) { |
| 8040 | if (is_ptr) { | 7952 | if (capture_is_ref) { |
| 8041 | return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{}); | 7953 | return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{}); |
| 8042 | } | 7954 | } |
| 8043 | payload_sub_scope = &case_scope.base; | 7955 | payload_sub_scope = &case_scope.base; |
| ... | @@ -8057,7 +7969,7 @@ fn switchExpr( | ... | @@ -8057,7 +7969,7 @@ fn switchExpr( |
| 8057 | payload_sub_scope = &capture_val_scope.base; | 7969 | payload_sub_scope = &capture_val_scope.base; |
| 8058 | } | 7970 | } |
| 8059 | 7971 | ||
| 8060 | const tag_token = if (token_tags[ident + 1] == .comma) | 7972 | const tag_token = if (tree.tokenTag(ident + 1) == .comma) |
| 8061 | ident + 2 | 7973 | ident + 2 |
| 8062 | else | 7974 | else |
| 8063 | break :blk payload_sub_scope; | 7975 | break :blk payload_sub_scope; |
| ... | @@ -8095,7 +8007,7 @@ fn switchExpr( | ... | @@ -8095,7 +8007,7 @@ fn switchExpr( |
| 8095 | // items | 8007 | // items |
| 8096 | var items_len: u32 = 0; | 8008 | var items_len: u32 = 0; |
| 8097 | for (case.ast.values) |item_node| { | 8009 | for (case.ast.values) |item_node| { |
| 8098 | if (node_tags[item_node] == .switch_range) continue; | 8010 | if (tree.nodeTag(item_node) == .switch_range) continue; |
| 8099 | items_len += 1; | 8011 | items_len += 1; |
| 8100 | 8012 | ||
| 8101 | const item_inst = try comptimeExpr(parent_gz, scope, item_ri, item_node, .switch_item); | 8013 | const item_inst = try comptimeExpr(parent_gz, scope, item_ri, item_node, .switch_item); |
| ... | @@ -8105,11 +8017,12 @@ fn switchExpr( | ... | @@ -8105,11 +8017,12 @@ fn switchExpr( |
| 8105 | // ranges | 8017 | // ranges |
| 8106 | var ranges_len: u32 = 0; | 8018 | var ranges_len: u32 = 0; |
| 8107 | for (case.ast.values) |range| { | 8019 | for (case.ast.values) |range| { |
| 8108 | if (node_tags[range] != .switch_range) continue; | 8020 | if (tree.nodeTag(range) != .switch_range) continue; |
| 8109 | ranges_len += 1; | 8021 | ranges_len += 1; |
| 8110 | 8022 | ||
| 8111 | const first = try comptimeExpr(parent_gz, scope, item_ri, node_datas[range].lhs, .switch_item); | 8023 | const first_node, const last_node = tree.nodeData(range).node_and_node; |
| 8112 | const last = try comptimeExpr(parent_gz, scope, item_ri, node_datas[range].rhs, .switch_item); | 8024 | const first = try comptimeExpr(parent_gz, scope, item_ri, first_node, .switch_item); |
| 8025 | const last = try comptimeExpr(parent_gz, scope, item_ri, last_node, .switch_item); | ||
| 8113 | try payloads.appendSlice(gpa, &[_]u32{ | 8026 | try payloads.appendSlice(gpa, &[_]u32{ |
| 8114 | @intFromEnum(first), @intFromEnum(last), | 8027 | @intFromEnum(first), @intFromEnum(last), |
| 8115 | }); | 8028 | }); |
| ... | @@ -8118,7 +8031,7 @@ fn switchExpr( | ... | @@ -8118,7 +8031,7 @@ fn switchExpr( |
| 8118 | payloads.items[header_index] = items_len; | 8031 | payloads.items[header_index] = items_len; |
| 8119 | payloads.items[header_index + 1] = ranges_len; | 8032 | payloads.items[header_index + 1] = ranges_len; |
| 8120 | break :blk header_index + 2; | 8033 | break :blk header_index + 2; |
| 8121 | } else if (case_node == special_node) blk: { | 8034 | } else if (case_node.toOptional() == special_node) blk: { |
| 8122 | payloads.items[case_table_start] = header_index; | 8035 | payloads.items[case_table_start] = header_index; |
| 8123 | try payloads.resize(gpa, header_index + 1); // body_len | 8036 | try payloads.resize(gpa, header_index + 1); // body_len |
| 8124 | break :blk header_index; | 8037 | break :blk header_index; |
| ... | @@ -8231,17 +8144,15 @@ fn switchExpr( | ... | @@ -8231,17 +8144,15 @@ fn switchExpr( |
| 8231 | fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { | 8144 | fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 8232 | const astgen = gz.astgen; | 8145 | const astgen = gz.astgen; |
| 8233 | const tree = astgen.tree; | 8146 | const tree = astgen.tree; |
| 8234 | const node_datas = tree.nodes.items(.data); | ||
| 8235 | const node_tags = tree.nodes.items(.tag); | ||
| 8236 | 8147 | ||
| 8237 | if (astgen.fn_block == null) { | 8148 | if (astgen.fn_block == null) { |
| 8238 | return astgen.failNode(node, "'return' outside function scope", .{}); | 8149 | return astgen.failNode(node, "'return' outside function scope", .{}); |
| 8239 | } | 8150 | } |
| 8240 | 8151 | ||
| 8241 | if (gz.any_defer_node != 0) { | 8152 | if (gz.any_defer_node.unwrap()) |any_defer_node| { |
| 8242 | return astgen.failNodeNotes(node, "cannot return from defer expression", .{}, &.{ | 8153 | return astgen.failNodeNotes(node, "cannot return from defer expression", .{}, &.{ |
| 8243 | try astgen.errNoteNode( | 8154 | try astgen.errNoteNode( |
| 8244 | gz.any_defer_node, | 8155 | any_defer_node, |
| 8245 | "defer expression here", | 8156 | "defer expression here", |
| 8246 | .{}, | 8157 | .{}, |
| 8247 | ), | 8158 | ), |
| ... | @@ -8259,8 +8170,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref | ... | @@ -8259,8 +8170,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 8259 | 8170 | ||
| 8260 | const defer_outer = &astgen.fn_block.?.base; | 8171 | const defer_outer = &astgen.fn_block.?.base; |
| 8261 | 8172 | ||
| 8262 | const operand_node = node_datas[node].lhs; | 8173 | const operand_node = tree.nodeData(node).opt_node.unwrap() orelse { |
| 8263 | if (operand_node == 0) { | ||
| 8264 | // Returning a void value; skip error defers. | 8174 | // Returning a void value; skip error defers. |
| 8265 | try genDefers(gz, defer_outer, scope, .normal_only); | 8175 | try genDefers(gz, defer_outer, scope, .normal_only); |
| 8266 | 8176 | ||
| ... | @@ -8269,12 +8179,12 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref | ... | @@ -8269,12 +8179,12 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 8269 | 8179 | ||
| 8270 | _ = try gz.addUnNode(.ret_node, .void_value, node); | 8180 | _ = try gz.addUnNode(.ret_node, .void_value, node); |
| 8271 | return Zir.Inst.Ref.unreachable_value; | 8181 | return Zir.Inst.Ref.unreachable_value; |
| 8272 | } | 8182 | }; |
| 8273 | 8183 | ||
| 8274 | if (node_tags[operand_node] == .error_value) { | 8184 | if (tree.nodeTag(operand_node) == .error_value) { |
| 8275 | // Hot path for `return error.Foo`. This bypasses result location logic as well as logic | 8185 | // Hot path for `return error.Foo`. This bypasses result location logic as well as logic |
| 8276 | // for detecting whether to add something to the function's inferred error set. | 8186 | // for detecting whether to add something to the function's inferred error set. |
| 8277 | const ident_token = node_datas[operand_node].rhs; | 8187 | const ident_token = tree.nodeData(operand_node).opt_token_and_opt_token[1].unwrap().?; |
| 8278 | const err_name_str_index = try astgen.identAsString(ident_token); | 8188 | const err_name_str_index = try astgen.identAsString(ident_token); |
| 8279 | const defer_counts = countDefers(defer_outer, scope); | 8189 | const defer_counts = countDefers(defer_outer, scope); |
| 8280 | if (!defer_counts.need_err_code) { | 8190 | if (!defer_counts.need_err_code) { |
| ... | @@ -8405,9 +8315,8 @@ fn identifier( | ... | @@ -8405,9 +8315,8 @@ fn identifier( |
| 8405 | ) InnerError!Zir.Inst.Ref { | 8315 | ) InnerError!Zir.Inst.Ref { |
| 8406 | const astgen = gz.astgen; | 8316 | const astgen = gz.astgen; |
| 8407 | const tree = astgen.tree; | 8317 | const tree = astgen.tree; |
| 8408 | const main_tokens = tree.nodes.items(.main_token); | ||
| 8409 | 8318 | ||
| 8410 | const ident_token = main_tokens[ident]; | 8319 | const ident_token = tree.nodeMainToken(ident); |
| 8411 | const ident_name_raw = tree.tokenSlice(ident_token); | 8320 | const ident_name_raw = tree.tokenSlice(ident_token); |
| 8412 | if (mem.eql(u8, ident_name_raw, "_")) { | 8321 | if (mem.eql(u8, ident_name_raw, "_")) { |
| 8413 | return astgen.failNode(ident, "'_' used as an identifier without @\"_\" syntax", .{}); | 8322 | return astgen.failNode(ident, "'_' used as an identifier without @\"_\" syntax", .{}); |
| ... | @@ -8509,9 +8418,9 @@ fn localVarRef( | ... | @@ -8509,9 +8418,9 @@ fn localVarRef( |
| 8509 | // Locals cannot shadow anything, so we do not need to look for ambiguous | 8418 | // Locals cannot shadow anything, so we do not need to look for ambiguous |
| 8510 | // references in this case. | 8419 | // references in this case. |
| 8511 | if (ri.rl == .discard and ri.ctx == .assignment) { | 8420 | if (ri.rl == .discard and ri.ctx == .assignment) { |
| 8512 | local_val.discarded = ident_token; | 8421 | local_val.discarded = .fromToken(ident_token); |
| 8513 | } else { | 8422 | } else { |
| 8514 | local_val.used = ident_token; | 8423 | local_val.used = .fromToken(ident_token); |
| 8515 | } | 8424 | } |
| 8516 | 8425 | ||
| 8517 | if (local_val.is_used_or_discarded) |ptr| ptr.* = true; | 8426 | if (local_val.is_used_or_discarded) |ptr| ptr.* = true; |
| ... | @@ -8533,9 +8442,9 @@ fn localVarRef( | ... | @@ -8533,9 +8442,9 @@ fn localVarRef( |
| 8533 | const local_ptr = s.cast(Scope.LocalPtr).?; | 8442 | const local_ptr = s.cast(Scope.LocalPtr).?; |
| 8534 | if (local_ptr.name == name_str_index) { | 8443 | if (local_ptr.name == name_str_index) { |
| 8535 | if (ri.rl == .discard and ri.ctx == .assignment) { | 8444 | if (ri.rl == .discard and ri.ctx == .assignment) { |
| 8536 | local_ptr.discarded = ident_token; | 8445 | local_ptr.discarded = .fromToken(ident_token); |
| 8537 | } else { | 8446 | } else { |
| 8538 | local_ptr.used = ident_token; | 8447 | local_ptr.used = .fromToken(ident_token); |
| 8539 | } | 8448 | } |
| 8540 | 8449 | ||
| 8541 | // Can't close over a runtime variable | 8450 | // Can't close over a runtime variable |
| ... | @@ -8748,8 +8657,7 @@ fn stringLiteral( | ... | @@ -8748,8 +8657,7 @@ fn stringLiteral( |
| 8748 | ) InnerError!Zir.Inst.Ref { | 8657 | ) InnerError!Zir.Inst.Ref { |
| 8749 | const astgen = gz.astgen; | 8658 | const astgen = gz.astgen; |
| 8750 | const tree = astgen.tree; | 8659 | const tree = astgen.tree; |
| 8751 | const main_tokens = tree.nodes.items(.main_token); | 8660 | const str_lit_token = tree.nodeMainToken(node); |
| 8752 | const str_lit_token = main_tokens[node]; | ||
| 8753 | const str = try astgen.strLitAsString(str_lit_token); | 8661 | const str = try astgen.strLitAsString(str_lit_token); |
| 8754 | const result = try gz.add(.{ | 8662 | const result = try gz.add(.{ |
| 8755 | .tag = .str, | 8663 | .tag = .str, |
| ... | @@ -8781,8 +8689,7 @@ fn multilineStringLiteral( | ... | @@ -8781,8 +8689,7 @@ fn multilineStringLiteral( |
| 8781 | fn charLiteral(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { | 8689 | fn charLiteral(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 8782 | const astgen = gz.astgen; | 8690 | const astgen = gz.astgen; |
| 8783 | const tree = astgen.tree; | 8691 | const tree = astgen.tree; |
| 8784 | const main_tokens = tree.nodes.items(.main_token); | 8692 | const main_token = tree.nodeMainToken(node); |
| 8785 | const main_token = main_tokens[node]; | ||
| 8786 | const slice = tree.tokenSlice(main_token); | 8693 | const slice = tree.tokenSlice(main_token); |
| 8787 | 8694 | ||
| 8788 | switch (std.zig.parseCharLiteral(slice)) { | 8695 | switch (std.zig.parseCharLiteral(slice)) { |
| ... | @@ -8799,8 +8706,7 @@ const Sign = enum { negative, positive }; | ... | @@ -8799,8 +8706,7 @@ const Sign = enum { negative, positive }; |
| 8799 | fn numberLiteral(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index, source_node: Ast.Node.Index, sign: Sign) InnerError!Zir.Inst.Ref { | 8706 | fn numberLiteral(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index, source_node: Ast.Node.Index, sign: Sign) InnerError!Zir.Inst.Ref { |
| 8800 | const astgen = gz.astgen; | 8707 | const astgen = gz.astgen; |
| 8801 | const tree = astgen.tree; | 8708 | const tree = astgen.tree; |
| 8802 | const main_tokens = tree.nodes.items(.main_token); | 8709 | const num_token = tree.nodeMainToken(node); |
| 8803 | const num_token = main_tokens[node]; | ||
| 8804 | const bytes = tree.tokenSlice(num_token); | 8710 | const bytes = tree.tokenSlice(num_token); |
| 8805 | 8711 | ||
| 8806 | const result: Zir.Inst.Ref = switch (std.zig.parseNumberLiteral(bytes)) { | 8712 | const result: Zir.Inst.Ref = switch (std.zig.parseNumberLiteral(bytes)) { |
| ... | @@ -8918,16 +8824,12 @@ fn asmExpr( | ... | @@ -8918,16 +8824,12 @@ fn asmExpr( |
| 8918 | ) InnerError!Zir.Inst.Ref { | 8824 | ) InnerError!Zir.Inst.Ref { |
| 8919 | const astgen = gz.astgen; | 8825 | const astgen = gz.astgen; |
| 8920 | const tree = astgen.tree; | 8826 | const tree = astgen.tree; |
| 8921 | const main_tokens = tree.nodes.items(.main_token); | ||
| 8922 | const node_datas = tree.nodes.items(.data); | ||
| 8923 | const node_tags = tree.nodes.items(.tag); | ||
| 8924 | const token_tags = tree.tokens.items(.tag); | ||
| 8925 | 8827 | ||
| 8926 | const TagAndTmpl = struct { tag: Zir.Inst.Extended, tmpl: Zir.NullTerminatedString }; | 8828 | const TagAndTmpl = struct { tag: Zir.Inst.Extended, tmpl: Zir.NullTerminatedString }; |
| 8927 | const tag_and_tmpl: TagAndTmpl = switch (node_tags[full.ast.template]) { | 8829 | const tag_and_tmpl: TagAndTmpl = switch (tree.nodeTag(full.ast.template)) { |
| 8928 | .string_literal => .{ | 8830 | .string_literal => .{ |
| 8929 | .tag = .@"asm", | 8831 | .tag = .@"asm", |
| 8930 | .tmpl = (try astgen.strLitAsString(main_tokens[full.ast.template])).index, | 8832 | .tmpl = (try astgen.strLitAsString(tree.nodeMainToken(full.ast.template))).index, |
| 8931 | }, | 8833 | }, |
| 8932 | .multiline_string_literal => .{ | 8834 | .multiline_string_literal => .{ |
| 8933 | .tag = .@"asm", | 8835 | .tag = .@"asm", |
| ... | @@ -8962,17 +8864,17 @@ fn asmExpr( | ... | @@ -8962,17 +8864,17 @@ fn asmExpr( |
| 8962 | var output_type_bits: u32 = 0; | 8864 | var output_type_bits: u32 = 0; |
| 8963 | 8865 | ||
| 8964 | for (full.outputs, 0..) |output_node, i| { | 8866 | for (full.outputs, 0..) |output_node, i| { |
| 8965 | const symbolic_name = main_tokens[output_node]; | 8867 | const symbolic_name = tree.nodeMainToken(output_node); |
| 8966 | const name = try astgen.identAsString(symbolic_name); | 8868 | const name = try astgen.identAsString(symbolic_name); |
| 8967 | const constraint_token = symbolic_name + 2; | 8869 | const constraint_token = symbolic_name + 2; |
| 8968 | const constraint = (try astgen.strLitAsString(constraint_token)).index; | 8870 | const constraint = (try astgen.strLitAsString(constraint_token)).index; |
| 8969 | const has_arrow = token_tags[symbolic_name + 4] == .arrow; | 8871 | const has_arrow = tree.tokenTag(symbolic_name + 4) == .arrow; |
| 8970 | if (has_arrow) { | 8872 | if (has_arrow) { |
| 8971 | if (output_type_bits != 0) { | 8873 | if (output_type_bits != 0) { |
| 8972 | return astgen.failNode(output_node, "inline assembly allows up to one output value", .{}); | 8874 | return astgen.failNode(output_node, "inline assembly allows up to one output value", .{}); |
| 8973 | } | 8875 | } |
| 8974 | output_type_bits |= @as(u32, 1) << @intCast(i); | 8876 | output_type_bits |= @as(u32, 1) << @intCast(i); |
| 8975 | const out_type_node = node_datas[output_node].lhs; | 8877 | const out_type_node = tree.nodeData(output_node).opt_node_and_token[0].unwrap().?; |
| 8976 | const out_type_inst = try typeExpr(gz, scope, out_type_node); | 8878 | const out_type_inst = try typeExpr(gz, scope, out_type_node); |
| 8977 | outputs[i] = .{ | 8879 | outputs[i] = .{ |
| 8978 | .name = name, | 8880 | .name = name, |
| ... | @@ -8999,11 +8901,11 @@ fn asmExpr( | ... | @@ -8999,11 +8901,11 @@ fn asmExpr( |
| 8999 | const inputs = inputs_buffer[0..full.inputs.len]; | 8901 | const inputs = inputs_buffer[0..full.inputs.len]; |
| 9000 | 8902 | ||
| 9001 | for (full.inputs, 0..) |input_node, i| { | 8903 | for (full.inputs, 0..) |input_node, i| { |
| 9002 | const symbolic_name = main_tokens[input_node]; | 8904 | const symbolic_name = tree.nodeMainToken(input_node); |
| 9003 | const name = try astgen.identAsString(symbolic_name); | 8905 | const name = try astgen.identAsString(symbolic_name); |
| 9004 | const constraint_token = symbolic_name + 2; | 8906 | const constraint_token = symbolic_name + 2; |
| 9005 | const constraint = (try astgen.strLitAsString(constraint_token)).index; | 8907 | const constraint = (try astgen.strLitAsString(constraint_token)).index; |
| 9006 | const operand = try expr(gz, scope, .{ .rl = .none }, node_datas[input_node].lhs); | 8908 | const operand = try expr(gz, scope, .{ .rl = .none }, tree.nodeData(input_node).node_and_token[0]); |
| 9007 | inputs[i] = .{ | 8909 | inputs[i] = .{ |
| 9008 | .name = name, | 8910 | .name = name, |
| 9009 | .constraint = constraint, | 8911 | .constraint = constraint, |
| ... | @@ -9024,10 +8926,10 @@ fn asmExpr( | ... | @@ -9024,10 +8926,10 @@ fn asmExpr( |
| 9024 | clobbers_buffer[clobber_i] = @intFromEnum((try astgen.strLitAsString(tok_i)).index); | 8926 | clobbers_buffer[clobber_i] = @intFromEnum((try astgen.strLitAsString(tok_i)).index); |
| 9025 | clobber_i += 1; | 8927 | clobber_i += 1; |
| 9026 | tok_i += 1; | 8928 | tok_i += 1; |
| 9027 | switch (token_tags[tok_i]) { | 8929 | switch (tree.tokenTag(tok_i)) { |
| 9028 | .r_paren => break :clobbers, | 8930 | .r_paren => break :clobbers, |
| 9029 | .comma => { | 8931 | .comma => { |
| 9030 | if (token_tags[tok_i + 1] == .r_paren) { | 8932 | if (tree.tokenTag(tok_i + 1) == .r_paren) { |
| 9031 | break :clobbers; | 8933 | break :clobbers; |
| 9032 | } else { | 8934 | } else { |
| 9033 | continue; | 8935 | continue; |
| ... | @@ -9119,9 +9021,6 @@ fn ptrCast( | ... | @@ -9119,9 +9021,6 @@ fn ptrCast( |
| 9119 | ) InnerError!Zir.Inst.Ref { | 9021 | ) InnerError!Zir.Inst.Ref { |
| 9120 | const astgen = gz.astgen; | 9022 | const astgen = gz.astgen; |
| 9121 | const tree = astgen.tree; | 9023 | const tree = astgen.tree; |
| 9122 | const main_tokens = tree.nodes.items(.main_token); | ||
| 9123 | const node_datas = tree.nodes.items(.data); | ||
| 9124 | const node_tags = tree.nodes.items(.tag); | ||
| 9125 | 9024 | ||
| 9126 | const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).@"struct".backing_integer.?; | 9025 | const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).@"struct".backing_integer.?; |
| 9127 | var flags: Zir.Inst.FullPtrCastFlags = .{}; | 9026 | var flags: Zir.Inst.FullPtrCastFlags = .{}; |
| ... | @@ -9130,11 +9029,11 @@ fn ptrCast( | ... | @@ -9130,11 +9029,11 @@ fn ptrCast( |
| 9130 | // to handle `builtin_call_two`. | 9029 | // to handle `builtin_call_two`. |
| 9131 | var node = root_node; | 9030 | var node = root_node; |
| 9132 | while (true) { | 9031 | while (true) { |
| 9133 | switch (node_tags[node]) { | 9032 | switch (tree.nodeTag(node)) { |
| 9134 | .builtin_call_two, .builtin_call_two_comma => {}, | 9033 | .builtin_call_two, .builtin_call_two_comma => {}, |
| 9135 | .grouped_expression => { | 9034 | .grouped_expression => { |
| 9136 | // Handle the chaining even with redundant parentheses | 9035 | // Handle the chaining even with redundant parentheses |
| 9137 | node = node_datas[node].lhs; | 9036 | node = tree.nodeData(node).node_and_token[0]; |
| 9138 | continue; | 9037 | continue; |
| 9139 | }, | 9038 | }, |
| 9140 | else => break, | 9039 | else => break, |
| ... | @@ -9144,7 +9043,9 @@ fn ptrCast( | ... | @@ -9144,7 +9043,9 @@ fn ptrCast( |
| 9144 | const args = tree.builtinCallParams(&buf, node).?; | 9043 | const args = tree.builtinCallParams(&buf, node).?; |
| 9145 | std.debug.assert(args.len <= 2); | 9044 | std.debug.assert(args.len <= 2); |
| 9146 | 9045 | ||
| 9147 | const builtin_token = main_tokens[node]; | 9046 | if (args.len == 0) break; // 0 args |
| 9047 | |||
| 9048 | const builtin_token = tree.nodeMainToken(node); | ||
| 9148 | const builtin_name = tree.tokenSlice(builtin_token); | 9049 | const builtin_name = tree.tokenSlice(builtin_token); |
| 9149 | const info = BuiltinFn.list.get(builtin_name) orelse break; | 9050 | const info = BuiltinFn.list.get(builtin_name) orelse break; |
| 9150 | if (args.len == 1) { | 9051 | if (args.len == 1) { |
| ... | @@ -9344,9 +9245,8 @@ fn builtinCall( | ... | @@ -9344,9 +9245,8 @@ fn builtinCall( |
| 9344 | ) InnerError!Zir.Inst.Ref { | 9245 | ) InnerError!Zir.Inst.Ref { |
| 9345 | const astgen = gz.astgen; | 9246 | const astgen = gz.astgen; |
| 9346 | const tree = astgen.tree; | 9247 | const tree = astgen.tree; |
| 9347 | const main_tokens = tree.nodes.items(.main_token); | ||
| 9348 | 9248 | ||
| 9349 | const builtin_token = main_tokens[node]; | 9249 | const builtin_token = tree.nodeMainToken(node); |
| 9350 | const builtin_name = tree.tokenSlice(builtin_token); | 9250 | const builtin_name = tree.tokenSlice(builtin_token); |
| 9351 | 9251 | ||
| 9352 | // We handle the different builtins manually because they have different semantics depending | 9252 | // We handle the different builtins manually because they have different semantics depending |
| ... | @@ -9387,14 +9287,13 @@ fn builtinCall( | ... | @@ -9387,14 +9287,13 @@ fn builtinCall( |
| 9387 | return rvalue(gz, ri, .void_value, node); | 9287 | return rvalue(gz, ri, .void_value, node); |
| 9388 | }, | 9288 | }, |
| 9389 | .import => { | 9289 | .import => { |
| 9390 | const node_tags = tree.nodes.items(.tag); | ||
| 9391 | const operand_node = params[0]; | 9290 | const operand_node = params[0]; |
| 9392 | 9291 | ||
| 9393 | if (node_tags[operand_node] != .string_literal) { | 9292 | if (tree.nodeTag(operand_node) != .string_literal) { |
| 9394 | // Spec reference: https://github.com/ziglang/zig/issues/2206 | 9293 | // Spec reference: https://github.com/ziglang/zig/issues/2206 |
| 9395 | return astgen.failNode(operand_node, "@import operand must be a string literal", .{}); | 9294 | return astgen.failNode(operand_node, "@import operand must be a string literal", .{}); |
| 9396 | } | 9295 | } |
| 9397 | const str_lit_token = main_tokens[operand_node]; | 9296 | const str_lit_token = tree.nodeMainToken(operand_node); |
| 9398 | const str = try astgen.strLitAsString(str_lit_token); | 9297 | const str = try astgen.strLitAsString(str_lit_token); |
| 9399 | const str_slice = astgen.string_bytes.items[@intFromEnum(str.index)..][0..str.len]; | 9298 | const str_slice = astgen.string_bytes.items[@intFromEnum(str.index)..][0..str.len]; |
| 9400 | if (mem.indexOfScalar(u8, str_slice, 0) != null) { | 9299 | if (mem.indexOfScalar(u8, str_slice, 0) != null) { |
| ... | @@ -9505,8 +9404,7 @@ fn builtinCall( | ... | @@ -9505,8 +9404,7 @@ fn builtinCall( |
| 9505 | std.mem.asBytes(&astgen.source_column), | 9404 | std.mem.asBytes(&astgen.source_column), |
| 9506 | ); | 9405 | ); |
| 9507 | 9406 | ||
| 9508 | const token_starts = tree.tokens.items(.start); | 9407 | const node_start = tree.tokenStart(tree.firstToken(node)); |
| 9509 | const node_start = token_starts[tree.firstToken(node)]; | ||
| 9510 | astgen.advanceSourceCursor(node_start); | 9408 | astgen.advanceSourceCursor(node_start); |
| 9511 | const result = try gz.addExtendedPayload(.builtin_src, Zir.Inst.Src{ | 9409 | const result = try gz.addExtendedPayload(.builtin_src, Zir.Inst.Src{ |
| 9512 | .node = gz.nodeIndexToRelative(node), | 9410 | .node = gz.nodeIndexToRelative(node), |
| ... | @@ -9786,7 +9684,7 @@ fn builtinCall( | ... | @@ -9786,7 +9684,7 @@ fn builtinCall( |
| 9786 | .callee = callee, | 9684 | .callee = callee, |
| 9787 | .args = args, | 9685 | .args = args, |
| 9788 | .flags = .{ | 9686 | .flags = .{ |
| 9789 | .is_nosuspend = gz.nosuspend_node != 0, | 9687 | .is_nosuspend = gz.nosuspend_node != .none, |
| 9790 | .ensure_result_used = false, | 9688 | .ensure_result_used = false, |
| 9791 | }, | 9689 | }, |
| 9792 | }); | 9690 | }); |
| ... | @@ -10011,13 +9909,11 @@ fn negation( | ... | @@ -10011,13 +9909,11 @@ fn negation( |
| 10011 | ) InnerError!Zir.Inst.Ref { | 9909 | ) InnerError!Zir.Inst.Ref { |
| 10012 | const astgen = gz.astgen; | 9910 | const astgen = gz.astgen; |
| 10013 | const tree = astgen.tree; | 9911 | const tree = astgen.tree; |
| 10014 | const node_tags = tree.nodes.items(.tag); | ||
| 10015 | const node_datas = tree.nodes.items(.data); | ||
| 10016 | 9912 | ||
| 10017 | // Check for float literal as the sub-expression because we want to preserve | 9913 | // Check for float literal as the sub-expression because we want to preserve |
| 10018 | // its negativity rather than having it go through comptime subtraction. | 9914 | // its negativity rather than having it go through comptime subtraction. |
| 10019 | const operand_node = node_datas[node].lhs; | 9915 | const operand_node = tree.nodeData(node).node; |
| 10020 | if (node_tags[operand_node] == .number_literal) { | 9916 | if (tree.nodeTag(operand_node) == .number_literal) { |
| 10021 | return numberLiteral(gz, ri, operand_node, node, .negative); | 9917 | return numberLiteral(gz, ri, operand_node, node, .negative); |
| 10022 | } | 9918 | } |
| 10023 | 9919 | ||
| ... | @@ -10133,7 +10029,7 @@ fn shiftOp( | ... | @@ -10133,7 +10029,7 @@ fn shiftOp( |
| 10133 | ) InnerError!Zir.Inst.Ref { | 10029 | ) InnerError!Zir.Inst.Ref { |
| 10134 | const lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node); | 10030 | const lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node); |
| 10135 | 10031 | ||
| 10136 | const cursor = switch (gz.astgen.tree.nodes.items(.tag)[node]) { | 10032 | const cursor = switch (gz.astgen.tree.nodeTag(node)) { |
| 10137 | .shl, .shr => maybeAdvanceSourceCursorToMainToken(gz, node), | 10033 | .shl, .shr => maybeAdvanceSourceCursorToMainToken(gz, node), |
| 10138 | else => undefined, | 10034 | else => undefined, |
| 10139 | }; | 10035 | }; |
| ... | @@ -10141,7 +10037,7 @@ fn shiftOp( | ... | @@ -10141,7 +10037,7 @@ fn shiftOp( |
| 10141 | const log2_int_type = try gz.addUnNode(.typeof_log2_int_type, lhs, lhs_node); | 10037 | const log2_int_type = try gz.addUnNode(.typeof_log2_int_type, lhs, lhs_node); |
| 10142 | const rhs = try expr(gz, scope, .{ .rl = .{ .ty = log2_int_type }, .ctx = .shift_op }, rhs_node); | 10038 | const rhs = try expr(gz, scope, .{ .rl = .{ .ty = log2_int_type }, .ctx = .shift_op }, rhs_node); |
| 10143 | 10039 | ||
| 10144 | switch (gz.astgen.tree.nodes.items(.tag)[node]) { | 10040 | switch (gz.astgen.tree.nodeTag(node)) { |
| 10145 | .shl, .shr => try emitDbgStmt(gz, cursor), | 10041 | .shl, .shr => try emitDbgStmt(gz, cursor), |
| 10146 | else => undefined, | 10042 | else => undefined, |
| 10147 | } | 10043 | } |
| ... | @@ -10217,14 +10113,14 @@ fn callExpr( | ... | @@ -10217,14 +10113,14 @@ fn callExpr( |
| 10217 | if (call.async_token != null) { | 10113 | if (call.async_token != null) { |
| 10218 | break :blk .async_kw; | 10114 | break :blk .async_kw; |
| 10219 | } | 10115 | } |
| 10220 | if (gz.nosuspend_node != 0) { | 10116 | if (gz.nosuspend_node != .none) { |
| 10221 | break :blk .no_async; | 10117 | break :blk .no_async; |
| 10222 | } | 10118 | } |
| 10223 | break :blk .auto; | 10119 | break :blk .auto; |
| 10224 | }; | 10120 | }; |
| 10225 | 10121 | ||
| 10226 | { | 10122 | { |
| 10227 | astgen.advanceSourceCursor(astgen.tree.tokens.items(.start)[call.ast.lparen]); | 10123 | astgen.advanceSourceCursor(astgen.tree.tokenStart(call.ast.lparen)); |
| 10228 | const line = astgen.source_line - gz.decl_line; | 10124 | const line = astgen.source_line - gz.decl_line; |
| 10229 | const column = astgen.source_column; | 10125 | const column = astgen.source_column; |
| 10230 | // Sema expects a dbg_stmt immediately before call, | 10126 | // Sema expects a dbg_stmt immediately before call, |
| ... | @@ -10235,7 +10131,6 @@ fn callExpr( | ... | @@ -10235,7 +10131,6 @@ fn callExpr( |
| 10235 | .direct => |obj| assert(obj != .none), | 10131 | .direct => |obj| assert(obj != .none), |
| 10236 | .field => |field| assert(field.obj_ptr != .none), | 10132 | .field => |field| assert(field.obj_ptr != .none), |
| 10237 | } | 10133 | } |
| 10238 | assert(node != 0); | ||
| 10239 | 10134 | ||
| 10240 | const call_index: Zir.Inst.Index = @enumFromInt(astgen.instructions.len); | 10135 | const call_index: Zir.Inst.Index = @enumFromInt(astgen.instructions.len); |
| 10241 | const call_inst = call_index.toRef(); | 10136 | const call_inst = call_index.toRef(); |
| ... | @@ -10346,14 +10241,10 @@ fn calleeExpr( | ... | @@ -10346,14 +10241,10 @@ fn calleeExpr( |
| 10346 | const astgen = gz.astgen; | 10241 | const astgen = gz.astgen; |
| 10347 | const tree = astgen.tree; | 10242 | const tree = astgen.tree; |
| 10348 | 10243 | ||
| 10349 | const tag = tree.nodes.items(.tag)[node]; | 10244 | const tag = tree.nodeTag(node); |
| 10350 | switch (tag) { | 10245 | switch (tag) { |
| 10351 | .field_access => { | 10246 | .field_access => { |
| 10352 | const main_tokens = tree.nodes.items(.main_token); | 10247 | const object_node, const field_ident = tree.nodeData(node).node_and_token; |
| 10353 | const node_datas = tree.nodes.items(.data); | ||
| 10354 | const object_node = node_datas[node].lhs; | ||
| 10355 | const dot_token = main_tokens[node]; | ||
| 10356 | const field_ident = dot_token + 1; | ||
| 10357 | const str_index = try astgen.identAsString(field_ident); | 10248 | const str_index = try astgen.identAsString(field_ident); |
| 10358 | // Capture the object by reference so we can promote it to an | 10249 | // Capture the object by reference so we can promote it to an |
| 10359 | // address in Sema if needed. | 10250 | // address in Sema if needed. |
| ... | @@ -10378,7 +10269,7 @@ fn calleeExpr( | ... | @@ -10378,7 +10269,7 @@ fn calleeExpr( |
| 10378 | // Decl literal call syntax, e.g. | 10269 | // Decl literal call syntax, e.g. |
| 10379 | // `const foo: T = .init();` | 10270 | // `const foo: T = .init();` |
| 10380 | // Look up `init` in `T`, but don't try and coerce it. | 10271 | // Look up `init` in `T`, but don't try and coerce it. |
| 10381 | const str_index = try astgen.identAsString(tree.nodes.items(.main_token)[node]); | 10272 | const str_index = try astgen.identAsString(tree.nodeMainToken(node)); |
| 10382 | const callee = try gz.addPlNode(.decl_literal_no_coerce, node, Zir.Inst.Field{ | 10273 | const callee = try gz.addPlNode(.decl_literal_no_coerce, node, Zir.Inst.Field{ |
| 10383 | .lhs = res_ty, | 10274 | .lhs = res_ty, |
| 10384 | .field_name_start = str_index, | 10275 | .field_name_start = str_index, |
| ... | @@ -10450,12 +10341,9 @@ comptime { | ... | @@ -10450,12 +10341,9 @@ comptime { |
| 10450 | } | 10341 | } |
| 10451 | 10342 | ||
| 10452 | fn nodeIsTriviallyZero(tree: *const Ast, node: Ast.Node.Index) bool { | 10343 | fn nodeIsTriviallyZero(tree: *const Ast, node: Ast.Node.Index) bool { |
| 10453 | const node_tags = tree.nodes.items(.tag); | 10344 | switch (tree.nodeTag(node)) { |
| 10454 | const main_tokens = tree.nodes.items(.main_token); | ||
| 10455 | |||
| 10456 | switch (node_tags[node]) { | ||
| 10457 | .number_literal => { | 10345 | .number_literal => { |
| 10458 | const ident = main_tokens[node]; | 10346 | const ident = tree.nodeMainToken(node); |
| 10459 | return switch (std.zig.parseNumberLiteral(tree.tokenSlice(ident))) { | 10347 | return switch (std.zig.parseNumberLiteral(tree.tokenSlice(ident))) { |
| 10460 | .int => |number| switch (number) { | 10348 | .int => |number| switch (number) { |
| 10461 | 0 => true, | 10349 | 0 => true, |
| ... | @@ -10469,12 +10357,9 @@ fn nodeIsTriviallyZero(tree: *const Ast, node: Ast.Node.Index) bool { | ... | @@ -10469,12 +10357,9 @@ fn nodeIsTriviallyZero(tree: *const Ast, node: Ast.Node.Index) bool { |
| 10469 | } | 10357 | } |
| 10470 | 10358 | ||
| 10471 | fn nodeMayAppendToErrorTrace(tree: *const Ast, start_node: Ast.Node.Index) bool { | 10359 | fn nodeMayAppendToErrorTrace(tree: *const Ast, start_node: Ast.Node.Index) bool { |
| 10472 | const node_tags = tree.nodes.items(.tag); | ||
| 10473 | const node_datas = tree.nodes.items(.data); | ||
| 10474 | |||
| 10475 | var node = start_node; | 10360 | var node = start_node; |
| 10476 | while (true) { | 10361 | while (true) { |
| 10477 | switch (node_tags[node]) { | 10362 | switch (tree.nodeTag(node)) { |
| 10478 | // These don't have the opportunity to call any runtime functions. | 10363 | // These don't have the opportunity to call any runtime functions. |
| 10479 | .error_value, | 10364 | .error_value, |
| 10480 | .identifier, | 10365 | .identifier, |
| ... | @@ -10482,11 +10367,12 @@ fn nodeMayAppendToErrorTrace(tree: *const Ast, start_node: Ast.Node.Index) bool | ... | @@ -10482,11 +10367,12 @@ fn nodeMayAppendToErrorTrace(tree: *const Ast, start_node: Ast.Node.Index) bool |
| 10482 | => return false, | 10367 | => return false, |
| 10483 | 10368 | ||
| 10484 | // Forward the question to the LHS sub-expression. | 10369 | // Forward the question to the LHS sub-expression. |
| 10485 | .grouped_expression, | ||
| 10486 | .@"try", | 10370 | .@"try", |
| 10487 | .@"nosuspend", | 10371 | .@"nosuspend", |
| 10372 | => node = tree.nodeData(node).node, | ||
| 10373 | .grouped_expression, | ||
| 10488 | .unwrap_optional, | 10374 | .unwrap_optional, |
| 10489 | => node = node_datas[node].lhs, | 10375 | => node = tree.nodeData(node).node_and_token[0], |
| 10490 | 10376 | ||
| 10491 | // Anything that does not eval to an error is guaranteed to pop any | 10377 | // Anything that does not eval to an error is guaranteed to pop any |
| 10492 | // additions to the error trace, so it effectively does not append. | 10378 | // additions to the error trace, so it effectively does not append. |
| ... | @@ -10496,14 +10382,9 @@ fn nodeMayAppendToErrorTrace(tree: *const Ast, start_node: Ast.Node.Index) bool | ... | @@ -10496,14 +10382,9 @@ fn nodeMayAppendToErrorTrace(tree: *const Ast, start_node: Ast.Node.Index) bool |
| 10496 | } | 10382 | } |
| 10497 | 10383 | ||
| 10498 | fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.EvalToError { | 10384 | fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.EvalToError { |
| 10499 | const node_tags = tree.nodes.items(.tag); | ||
| 10500 | const node_datas = tree.nodes.items(.data); | ||
| 10501 | const main_tokens = tree.nodes.items(.main_token); | ||
| 10502 | const token_tags = tree.tokens.items(.tag); | ||
| 10503 | |||
| 10504 | var node = start_node; | 10385 | var node = start_node; |
| 10505 | while (true) { | 10386 | while (true) { |
| 10506 | switch (node_tags[node]) { | 10387 | switch (tree.nodeTag(node)) { |
| 10507 | .root, | 10388 | .root, |
| 10508 | .@"usingnamespace", | 10389 | .@"usingnamespace", |
| 10509 | .test_decl, | 10390 | .test_decl, |
| ... | @@ -10666,13 +10547,14 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev | ... | @@ -10666,13 +10547,14 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev |
| 10666 | => return .never, | 10547 | => return .never, |
| 10667 | 10548 | ||
| 10668 | // Forward the question to the LHS sub-expression. | 10549 | // Forward the question to the LHS sub-expression. |
| 10669 | .grouped_expression, | ||
| 10670 | .@"try", | 10550 | .@"try", |
| 10671 | .@"await", | 10551 | .@"await", |
| 10672 | .@"comptime", | 10552 | .@"comptime", |
| 10673 | .@"nosuspend", | 10553 | .@"nosuspend", |
| 10554 | => node = tree.nodeData(node).node, | ||
| 10555 | .grouped_expression, | ||
| 10674 | .unwrap_optional, | 10556 | .unwrap_optional, |
| 10675 | => node = node_datas[node].lhs, | 10557 | => node = tree.nodeData(node).node_and_token[0], |
| 10676 | 10558 | ||
| 10677 | // LHS sub-expression may still be an error under the outer optional or error union | 10559 | // LHS sub-expression may still be an error under the outer optional or error union |
| 10678 | .@"catch", | 10560 | .@"catch", |
| ... | @@ -10684,8 +10566,8 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev | ... | @@ -10684,8 +10566,8 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev |
| 10684 | .block, | 10566 | .block, |
| 10685 | .block_semicolon, | 10567 | .block_semicolon, |
| 10686 | => { | 10568 | => { |
| 10687 | const lbrace = main_tokens[node]; | 10569 | const lbrace = tree.nodeMainToken(node); |
| 10688 | if (token_tags[lbrace - 1] == .colon) { | 10570 | if (tree.tokenTag(lbrace - 1) == .colon) { |
| 10689 | // Labeled blocks may need a memory location to forward | 10571 | // Labeled blocks may need a memory location to forward |
| 10690 | // to their break statements. | 10572 | // to their break statements. |
| 10691 | return .maybe; | 10573 | return .maybe; |
| ... | @@ -10699,7 +10581,7 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev | ... | @@ -10699,7 +10581,7 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev |
| 10699 | .builtin_call_two, | 10581 | .builtin_call_two, |
| 10700 | .builtin_call_two_comma, | 10582 | .builtin_call_two_comma, |
| 10701 | => { | 10583 | => { |
| 10702 | const builtin_token = main_tokens[node]; | 10584 | const builtin_token = tree.nodeMainToken(node); |
| 10703 | const builtin_name = tree.tokenSlice(builtin_token); | 10585 | const builtin_name = tree.tokenSlice(builtin_token); |
| 10704 | // If the builtin is an invalid name, we don't cause an error here; instead | 10586 | // If the builtin is an invalid name, we don't cause an error here; instead |
| 10705 | // let it pass, and the error will be "invalid builtin function" later. | 10587 | // let it pass, and the error will be "invalid builtin function" later. |
| ... | @@ -10713,12 +10595,9 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev | ... | @@ -10713,12 +10595,9 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev |
| 10713 | /// Returns `true` if it is known the type expression has more than one possible value; | 10595 | /// Returns `true` if it is known the type expression has more than one possible value; |
| 10714 | /// `false` otherwise. | 10596 | /// `false` otherwise. |
| 10715 | fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.Index) bool { | 10597 | fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.Index) bool { |
| 10716 | const node_tags = tree.nodes.items(.tag); | ||
| 10717 | const node_datas = tree.nodes.items(.data); | ||
| 10718 | |||
| 10719 | var node = start_node; | 10598 | var node = start_node; |
| 10720 | while (true) { | 10599 | while (true) { |
| 10721 | switch (node_tags[node]) { | 10600 | switch (tree.nodeTag(node)) { |
| 10722 | .root, | 10601 | .root, |
| 10723 | .@"usingnamespace", | 10602 | .@"usingnamespace", |
| 10724 | .test_decl, | 10603 | .test_decl, |
| ... | @@ -10881,13 +10760,14 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In | ... | @@ -10881,13 +10760,14 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In |
| 10881 | => return false, | 10760 | => return false, |
| 10882 | 10761 | ||
| 10883 | // Forward the question to the LHS sub-expression. | 10762 | // Forward the question to the LHS sub-expression. |
| 10884 | .grouped_expression, | ||
| 10885 | .@"try", | 10763 | .@"try", |
| 10886 | .@"await", | 10764 | .@"await", |
| 10887 | .@"comptime", | 10765 | .@"comptime", |
| 10888 | .@"nosuspend", | 10766 | .@"nosuspend", |
| 10767 | => node = tree.nodeData(node).node, | ||
| 10768 | .grouped_expression, | ||
| 10889 | .unwrap_optional, | 10769 | .unwrap_optional, |
| 10890 | => node = node_datas[node].lhs, | 10770 | => node = tree.nodeData(node).node_and_token[0], |
| 10891 | 10771 | ||
| 10892 | .ptr_type_aligned, | 10772 | .ptr_type_aligned, |
| 10893 | .ptr_type_sentinel, | 10773 | .ptr_type_sentinel, |
| ... | @@ -10899,8 +10779,7 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In | ... | @@ -10899,8 +10779,7 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In |
| 10899 | => return true, | 10779 | => return true, |
| 10900 | 10780 | ||
| 10901 | .identifier => { | 10781 | .identifier => { |
| 10902 | const main_tokens = tree.nodes.items(.main_token); | 10782 | const ident_bytes = tree.tokenSlice(tree.nodeMainToken(node)); |
| 10903 | const ident_bytes = tree.tokenSlice(main_tokens[node]); | ||
| 10904 | if (primitive_instrs.get(ident_bytes)) |primitive| switch (primitive) { | 10783 | if (primitive_instrs.get(ident_bytes)) |primitive| switch (primitive) { |
| 10905 | .anyerror_type, | 10784 | .anyerror_type, |
| 10906 | .anyframe_type, | 10785 | .anyframe_type, |
| ... | @@ -10960,12 +10839,9 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In | ... | @@ -10960,12 +10839,9 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In |
| 10960 | /// Returns `true` if it is known the expression is a type that cannot be used at runtime; | 10839 | /// Returns `true` if it is known the expression is a type that cannot be used at runtime; |
| 10961 | /// `false` otherwise. | 10840 | /// `false` otherwise. |
| 10962 | fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool { | 10841 | fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool { |
| 10963 | const node_tags = tree.nodes.items(.tag); | ||
| 10964 | const node_datas = tree.nodes.items(.data); | ||
| 10965 | |||
| 10966 | var node = start_node; | 10842 | var node = start_node; |
| 10967 | while (true) { | 10843 | while (true) { |
| 10968 | switch (node_tags[node]) { | 10844 | switch (tree.nodeTag(node)) { |
| 10969 | .root, | 10845 | .root, |
| 10970 | .@"usingnamespace", | 10846 | .@"usingnamespace", |
| 10971 | .test_decl, | 10847 | .test_decl, |
| ... | @@ -11137,17 +11013,17 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool { | ... | @@ -11137,17 +11013,17 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool { |
| 11137 | => return true, | 11013 | => return true, |
| 11138 | 11014 | ||
| 11139 | // Forward the question to the LHS sub-expression. | 11015 | // Forward the question to the LHS sub-expression. |
| 11140 | .grouped_expression, | ||
| 11141 | .@"try", | 11016 | .@"try", |
| 11142 | .@"await", | 11017 | .@"await", |
| 11143 | .@"comptime", | 11018 | .@"comptime", |
| 11144 | .@"nosuspend", | 11019 | .@"nosuspend", |
| 11020 | => node = tree.nodeData(node).node, | ||
| 11021 | .grouped_expression, | ||
| 11145 | .unwrap_optional, | 11022 | .unwrap_optional, |
| 11146 | => node = node_datas[node].lhs, | 11023 | => node = tree.nodeData(node).node_and_token[0], |
| 11147 | 11024 | ||
| 11148 | .identifier => { | 11025 | .identifier => { |
| 11149 | const main_tokens = tree.nodes.items(.main_token); | 11026 | const ident_bytes = tree.tokenSlice(tree.nodeMainToken(node)); |
| 11150 | const ident_bytes = tree.tokenSlice(main_tokens[node]); | ||
| 11151 | if (primitive_instrs.get(ident_bytes)) |primitive| switch (primitive) { | 11027 | if (primitive_instrs.get(ident_bytes)) |primitive| switch (primitive) { |
| 11152 | .anyerror_type, | 11028 | .anyerror_type, |
| 11153 | .anyframe_type, | 11029 | .anyframe_type, |
| ... | @@ -11206,8 +11082,7 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool { | ... | @@ -11206,8 +11082,7 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool { |
| 11206 | 11082 | ||
| 11207 | /// Returns `true` if the node uses `gz.anon_name_strategy`. | 11083 | /// Returns `true` if the node uses `gz.anon_name_strategy`. |
| 11208 | fn nodeUsesAnonNameStrategy(tree: *const Ast, node: Ast.Node.Index) bool { | 11084 | fn nodeUsesAnonNameStrategy(tree: *const Ast, node: Ast.Node.Index) bool { |
| 11209 | const node_tags = tree.nodes.items(.tag); | 11085 | switch (tree.nodeTag(node)) { |
| 11210 | switch (node_tags[node]) { | ||
| 11211 | .container_decl, | 11086 | .container_decl, |
| 11212 | .container_decl_trailing, | 11087 | .container_decl_trailing, |
| 11213 | .container_decl_two, | 11088 | .container_decl_two, |
| ... | @@ -11222,7 +11097,7 @@ fn nodeUsesAnonNameStrategy(tree: *const Ast, node: Ast.Node.Index) bool { | ... | @@ -11222,7 +11097,7 @@ fn nodeUsesAnonNameStrategy(tree: *const Ast, node: Ast.Node.Index) bool { |
| 11222 | .tagged_union_enum_tag_trailing, | 11097 | .tagged_union_enum_tag_trailing, |
| 11223 | => return true, | 11098 | => return true, |
| 11224 | .builtin_call_two, .builtin_call_two_comma, .builtin_call, .builtin_call_comma => { | 11099 | .builtin_call_two, .builtin_call_two_comma, .builtin_call, .builtin_call_comma => { |
| 11225 | const builtin_token = tree.nodes.items(.main_token)[node]; | 11100 | const builtin_token = tree.nodeMainToken(node); |
| 11226 | const builtin_name = tree.tokenSlice(builtin_token); | 11101 | const builtin_name = tree.tokenSlice(builtin_token); |
| 11227 | return std.mem.eql(u8, builtin_name, "@Type"); | 11102 | return std.mem.eql(u8, builtin_name, "@Type"); |
| 11228 | }, | 11103 | }, |
| ... | @@ -11455,8 +11330,7 @@ fn rvalueInner( | ... | @@ -11455,8 +11330,7 @@ fn rvalueInner( |
| 11455 | /// See also `appendIdentStr` and `parseStrLit`. | 11330 | /// See also `appendIdentStr` and `parseStrLit`. |
| 11456 | fn identifierTokenString(astgen: *AstGen, token: Ast.TokenIndex) InnerError![]const u8 { | 11331 | fn identifierTokenString(astgen: *AstGen, token: Ast.TokenIndex) InnerError![]const u8 { |
| 11457 | const tree = astgen.tree; | 11332 | const tree = astgen.tree; |
| 11458 | const token_tags = tree.tokens.items(.tag); | 11333 | assert(tree.tokenTag(token) == .identifier); |
| 11459 | assert(token_tags[token] == .identifier); | ||
| 11460 | const ident_name = tree.tokenSlice(token); | 11334 | const ident_name = tree.tokenSlice(token); |
| 11461 | if (!mem.startsWith(u8, ident_name, "@")) { | 11335 | if (!mem.startsWith(u8, ident_name, "@")) { |
| 11462 | return ident_name; | 11336 | return ident_name; |
| ... | @@ -11482,8 +11356,7 @@ fn appendIdentStr( | ... | @@ -11482,8 +11356,7 @@ fn appendIdentStr( |
| 11482 | buf: *ArrayListUnmanaged(u8), | 11356 | buf: *ArrayListUnmanaged(u8), |
| 11483 | ) InnerError!void { | 11357 | ) InnerError!void { |
| 11484 | const tree = astgen.tree; | 11358 | const tree = astgen.tree; |
| 11485 | const token_tags = tree.tokens.items(.tag); | 11359 | assert(tree.tokenTag(token) == .identifier); |
| 11486 | assert(token_tags[token] == .identifier); | ||
| 11487 | const ident_name = tree.tokenSlice(token); | 11360 | const ident_name = tree.tokenSlice(token); |
| 11488 | if (!mem.startsWith(u8, ident_name, "@")) { | 11361 | if (!mem.startsWith(u8, ident_name, "@")) { |
| 11489 | return buf.appendSlice(astgen.gpa, ident_name); | 11362 | return buf.appendSlice(astgen.gpa, ident_name); |
| ... | @@ -11572,8 +11445,8 @@ fn appendErrorNodeNotes( | ... | @@ -11572,8 +11445,8 @@ fn appendErrorNodeNotes( |
| 11572 | } else 0; | 11445 | } else 0; |
| 11573 | try astgen.compile_errors.append(astgen.gpa, .{ | 11446 | try astgen.compile_errors.append(astgen.gpa, .{ |
| 11574 | .msg = msg, | 11447 | .msg = msg, |
| 11575 | .node = node, | 11448 | .node = node.toOptional(), |
| 11576 | .token = 0, | 11449 | .token = .none, |
| 11577 | .byte_offset = 0, | 11450 | .byte_offset = 0, |
| 11578 | .notes = notes_index, | 11451 | .notes = notes_index, |
| 11579 | }); | 11452 | }); |
| ... | @@ -11664,8 +11537,8 @@ fn appendErrorTokNotesOff( | ... | @@ -11664,8 +11537,8 @@ fn appendErrorTokNotesOff( |
| 11664 | } else 0; | 11537 | } else 0; |
| 11665 | try astgen.compile_errors.append(gpa, .{ | 11538 | try astgen.compile_errors.append(gpa, .{ |
| 11666 | .msg = msg, | 11539 | .msg = msg, |
| 11667 | .node = 0, | 11540 | .node = .none, |
| 11668 | .token = token, | 11541 | .token = .fromToken(token), |
| 11669 | .byte_offset = byte_offset, | 11542 | .byte_offset = byte_offset, |
| 11670 | .notes = notes_index, | 11543 | .notes = notes_index, |
| 11671 | }); | 11544 | }); |
| ... | @@ -11693,8 +11566,8 @@ fn errNoteTokOff( | ... | @@ -11693,8 +11566,8 @@ fn errNoteTokOff( |
| 11693 | try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args); | 11566 | try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args); |
| 11694 | return astgen.addExtra(Zir.Inst.CompileErrors.Item{ | 11567 | return astgen.addExtra(Zir.Inst.CompileErrors.Item{ |
| 11695 | .msg = msg, | 11568 | .msg = msg, |
| 11696 | .node = 0, | 11569 | .node = .none, |
| 11697 | .token = token, | 11570 | .token = .fromToken(token), |
| 11698 | .byte_offset = byte_offset, | 11571 | .byte_offset = byte_offset, |
| 11699 | .notes = 0, | 11572 | .notes = 0, |
| 11700 | }); | 11573 | }); |
| ... | @@ -11712,8 +11585,8 @@ fn errNoteNode( | ... | @@ -11712,8 +11585,8 @@ fn errNoteNode( |
| 11712 | try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args); | 11585 | try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args); |
| 11713 | return astgen.addExtra(Zir.Inst.CompileErrors.Item{ | 11586 | return astgen.addExtra(Zir.Inst.CompileErrors.Item{ |
| 11714 | .msg = msg, | 11587 | .msg = msg, |
| 11715 | .node = node, | 11588 | .node = node.toOptional(), |
| 11716 | .token = 0, | 11589 | .token = .none, |
| 11717 | .byte_offset = 0, | 11590 | .byte_offset = 0, |
| 11718 | .notes = 0, | 11591 | .notes = 0, |
| 11719 | }); | 11592 | }); |
| ... | @@ -11779,10 +11652,8 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice { | ... | @@ -11779,10 +11652,8 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice { |
| 11779 | 11652 | ||
| 11780 | fn strLitNodeAsString(astgen: *AstGen, node: Ast.Node.Index) !IndexSlice { | 11653 | fn strLitNodeAsString(astgen: *AstGen, node: Ast.Node.Index) !IndexSlice { |
| 11781 | const tree = astgen.tree; | 11654 | const tree = astgen.tree; |
| 11782 | const node_datas = tree.nodes.items(.data); | ||
| 11783 | 11655 | ||
| 11784 | const start = node_datas[node].lhs; | 11656 | const start, const end = tree.nodeData(node).token_and_token; |
| 11785 | const end = node_datas[node].rhs; | ||
| 11786 | 11657 | ||
| 11787 | const gpa = astgen.gpa; | 11658 | const gpa = astgen.gpa; |
| 11788 | const string_bytes = &astgen.string_bytes; | 11659 | const string_bytes = &astgen.string_bytes; |
| ... | @@ -11877,11 +11748,11 @@ const Scope = struct { | ... | @@ -11877,11 +11748,11 @@ const Scope = struct { |
| 11877 | /// Source location of the corresponding variable declaration. | 11748 | /// Source location of the corresponding variable declaration. |
| 11878 | token_src: Ast.TokenIndex, | 11749 | token_src: Ast.TokenIndex, |
| 11879 | /// Track the first identifier where it is referenced. | 11750 | /// Track the first identifier where it is referenced. |
| 11880 | /// 0 means never referenced. | 11751 | /// .none means never referenced. |
| 11881 | used: Ast.TokenIndex = 0, | 11752 | used: Ast.OptionalTokenIndex = .none, |
| 11882 | /// Track the identifier where it is discarded, like this `_ = foo;`. | 11753 | /// Track the identifier where it is discarded, like this `_ = foo;`. |
| 11883 | /// 0 means never discarded. | 11754 | /// .none means never discarded. |
| 11884 | discarded: Ast.TokenIndex = 0, | 11755 | discarded: Ast.OptionalTokenIndex = .none, |
| 11885 | is_used_or_discarded: ?*bool = null, | 11756 | is_used_or_discarded: ?*bool = null, |
| 11886 | /// String table index. | 11757 | /// String table index. |
| 11887 | name: Zir.NullTerminatedString, | 11758 | name: Zir.NullTerminatedString, |
| ... | @@ -11901,11 +11772,11 @@ const Scope = struct { | ... | @@ -11901,11 +11772,11 @@ const Scope = struct { |
| 11901 | /// Source location of the corresponding variable declaration. | 11772 | /// Source location of the corresponding variable declaration. |
| 11902 | token_src: Ast.TokenIndex, | 11773 | token_src: Ast.TokenIndex, |
| 11903 | /// Track the first identifier where it is referenced. | 11774 | /// Track the first identifier where it is referenced. |
| 11904 | /// 0 means never referenced. | 11775 | /// .none means never referenced. |
| 11905 | used: Ast.TokenIndex = 0, | 11776 | used: Ast.OptionalTokenIndex = .none, |
| 11906 | /// Track the identifier where it is discarded, like this `_ = foo;`. | 11777 | /// Track the identifier where it is discarded, like this `_ = foo;`. |
| 11907 | /// 0 means never discarded. | 11778 | /// .none means never discarded. |
| 11908 | discarded: Ast.TokenIndex = 0, | 11779 | discarded: Ast.OptionalTokenIndex = .none, |
| 11909 | /// Whether this value is used as an lvalue after initialization. | 11780 | /// Whether this value is used as an lvalue after initialization. |
| 11910 | /// If not, we know it can be `const`, so will emit a compile error if it is `var`. | 11781 | /// If not, we know it can be `const`, so will emit a compile error if it is `var`. |
| 11911 | used_as_lvalue: bool = false, | 11782 | used_as_lvalue: bool = false, |
| ... | @@ -12000,12 +11871,12 @@ const GenZir = struct { | ... | @@ -12000,12 +11871,12 @@ const GenZir = struct { |
| 12000 | break_result_info: AstGen.ResultInfo = undefined, | 11871 | break_result_info: AstGen.ResultInfo = undefined, |
| 12001 | continue_result_info: AstGen.ResultInfo = undefined, | 11872 | continue_result_info: AstGen.ResultInfo = undefined, |
| 12002 | 11873 | ||
| 12003 | suspend_node: Ast.Node.Index = 0, | 11874 | suspend_node: Ast.Node.OptionalIndex = .none, |
| 12004 | nosuspend_node: Ast.Node.Index = 0, | 11875 | nosuspend_node: Ast.Node.OptionalIndex = .none, |
| 12005 | /// Set if this GenZir is a defer. | 11876 | /// Set if this GenZir is a defer. |
| 12006 | cur_defer_node: Ast.Node.Index = 0, | 11877 | cur_defer_node: Ast.Node.OptionalIndex = .none, |
| 12007 | // Set if this GenZir is a defer or it is inside a defer. | 11878 | // Set if this GenZir is a defer or it is inside a defer. |
| 12008 | any_defer_node: Ast.Node.Index = 0, | 11879 | any_defer_node: Ast.Node.OptionalIndex = .none, |
| 12009 | 11880 | ||
| 12010 | const unstacked_top = std.math.maxInt(usize); | 11881 | const unstacked_top = std.math.maxInt(usize); |
| 12011 | /// Call unstack before adding any new instructions to containing GenZir. | 11882 | /// Call unstack before adding any new instructions to containing GenZir. |
| ... | @@ -12086,12 +11957,12 @@ const GenZir = struct { | ... | @@ -12086,12 +11957,12 @@ const GenZir = struct { |
| 12086 | return false; | 11957 | return false; |
| 12087 | } | 11958 | } |
| 12088 | 11959 | ||
| 12089 | fn nodeIndexToRelative(gz: GenZir, node_index: Ast.Node.Index) i32 { | 11960 | fn nodeIndexToRelative(gz: GenZir, node_index: Ast.Node.Index) Ast.Node.Offset { |
| 12090 | return @as(i32, @bitCast(node_index)) - @as(i32, @bitCast(gz.decl_node_index)); | 11961 | return gz.decl_node_index.toOffset(node_index); |
| 12091 | } | 11962 | } |
| 12092 | 11963 | ||
| 12093 | fn tokenIndexToRelative(gz: GenZir, token: Ast.TokenIndex) u32 { | 11964 | fn tokenIndexToRelative(gz: GenZir, token: Ast.TokenIndex) Ast.TokenOffset { |
| 12094 | return token - gz.srcToken(); | 11965 | return .init(gz.srcToken(), token); |
| 12095 | } | 11966 | } |
| 12096 | 11967 | ||
| 12097 | fn srcToken(gz: GenZir) Ast.TokenIndex { | 11968 | fn srcToken(gz: GenZir) Ast.TokenIndex { |
| ... | @@ -12244,7 +12115,7 @@ const GenZir = struct { | ... | @@ -12244,7 +12115,7 @@ const GenZir = struct { |
| 12244 | proto_hash: std.zig.SrcHash, | 12115 | proto_hash: std.zig.SrcHash, |
| 12245 | }, | 12116 | }, |
| 12246 | ) !Zir.Inst.Ref { | 12117 | ) !Zir.Inst.Ref { |
| 12247 | assert(args.src_node != 0); | 12118 | assert(args.src_node != .root); |
| 12248 | const astgen = gz.astgen; | 12119 | const astgen = gz.astgen; |
| 12249 | const gpa = astgen.gpa; | 12120 | const gpa = astgen.gpa; |
| 12250 | const ret_ref = if (args.ret_ref == .void_type) .none else args.ret_ref; | 12121 | const ret_ref = if (args.ret_ref == .void_type) .none else args.ret_ref; |
| ... | @@ -12276,13 +12147,13 @@ const GenZir = struct { | ... | @@ -12276,13 +12147,13 @@ const GenZir = struct { |
| 12276 | var src_locs_and_hash_buffer: [7]u32 = undefined; | 12147 | var src_locs_and_hash_buffer: [7]u32 = undefined; |
| 12277 | const src_locs_and_hash: []const u32 = if (args.body_gz != null) src_locs_and_hash: { | 12148 | const src_locs_and_hash: []const u32 = if (args.body_gz != null) src_locs_and_hash: { |
| 12278 | const tree = astgen.tree; | 12149 | const tree = astgen.tree; |
| 12279 | const node_tags = tree.nodes.items(.tag); | ||
| 12280 | const node_datas = tree.nodes.items(.data); | ||
| 12281 | const token_starts = tree.tokens.items(.start); | ||
| 12282 | const fn_decl = args.src_node; | 12150 | const fn_decl = args.src_node; |
| 12283 | assert(node_tags[fn_decl] == .fn_decl or node_tags[fn_decl] == .test_decl); | 12151 | const block = switch (tree.nodeTag(fn_decl)) { |
| 12284 | const block = node_datas[fn_decl].rhs; | 12152 | .fn_decl => tree.nodeData(fn_decl).node_and_node[1], |
| 12285 | const rbrace_start = token_starts[tree.lastToken(block)]; | 12153 | .test_decl => tree.nodeData(fn_decl).opt_token_and_node[1], |
| 12154 | else => unreachable, | ||
| 12155 | }; | ||
| 12156 | const rbrace_start = tree.tokenStart(tree.lastToken(block)); | ||
| 12286 | astgen.advanceSourceCursor(rbrace_start); | 12157 | astgen.advanceSourceCursor(rbrace_start); |
| 12287 | const rbrace_line: u32 = @intCast(astgen.source_line - gz.decl_line); | 12158 | const rbrace_line: u32 = @intCast(astgen.source_line - gz.decl_line); |
| 12288 | const rbrace_column: u32 = @intCast(astgen.source_column); | 12159 | const rbrace_column: u32 = @intCast(astgen.source_column); |
| ... | @@ -12689,7 +12560,7 @@ const GenZir = struct { | ... | @@ -12689,7 +12560,7 @@ const GenZir = struct { |
| 12689 | .data = .{ .extended = .{ | 12560 | .data = .{ .extended = .{ |
| 12690 | .opcode = opcode, | 12561 | .opcode = opcode, |
| 12691 | .small = small, | 12562 | .small = small, |
| 12692 | .operand = @bitCast(gz.nodeIndexToRelative(src_node)), | 12563 | .operand = @bitCast(@intFromEnum(gz.nodeIndexToRelative(src_node))), |
| 12693 | } }, | 12564 | } }, |
| 12694 | }); | 12565 | }); |
| 12695 | gz.instructions.appendAssumeCapacity(new_index); | 12566 | gz.instructions.appendAssumeCapacity(new_index); |
| ... | @@ -12878,9 +12749,9 @@ const GenZir = struct { | ... | @@ -12878,9 +12749,9 @@ const GenZir = struct { |
| 12878 | .operand = operand, | 12749 | .operand = operand, |
| 12879 | .payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Break{ | 12750 | .payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Break{ |
| 12880 | .operand_src_node = if (operand_src_node) |src_node| | 12751 | .operand_src_node = if (operand_src_node) |src_node| |
| 12881 | gz.nodeIndexToRelative(src_node) | 12752 | gz.nodeIndexToRelative(src_node).toOptional() |
| 12882 | else | 12753 | else |
| 12883 | Zir.Inst.Break.no_src_node, | 12754 | .none, |
| 12884 | .block_inst = block_inst, | 12755 | .block_inst = block_inst, |
| 12885 | }), | 12756 | }), |
| 12886 | } }, | 12757 | } }, |
| ... | @@ -12969,7 +12840,7 @@ const GenZir = struct { | ... | @@ -12969,7 +12840,7 @@ const GenZir = struct { |
| 12969 | .data = .{ .extended = .{ | 12840 | .data = .{ .extended = .{ |
| 12970 | .opcode = opcode, | 12841 | .opcode = opcode, |
| 12971 | .small = undefined, | 12842 | .small = undefined, |
| 12972 | .operand = @bitCast(gz.nodeIndexToRelative(src_node)), | 12843 | .operand = @bitCast(@intFromEnum(gz.nodeIndexToRelative(src_node))), |
| 12973 | } }, | 12844 | } }, |
| 12974 | }); | 12845 | }); |
| 12975 | } | 12846 | } |
| ... | @@ -13149,8 +13020,8 @@ const GenZir = struct { | ... | @@ -13149,8 +13020,8 @@ const GenZir = struct { |
| 13149 | const astgen = gz.astgen; | 13020 | const astgen = gz.astgen; |
| 13150 | const gpa = astgen.gpa; | 13021 | const gpa = astgen.gpa; |
| 13151 | 13022 | ||
| 13152 | // Node 0 is valid for the root `struct_decl` of a file! | 13023 | // Node .root is valid for the root `struct_decl` of a file! |
| 13153 | assert(args.src_node != 0 or gz.parent.tag == .top); | 13024 | assert(args.src_node != .root or gz.parent.tag == .top); |
| 13154 | 13025 | ||
| 13155 | const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash); | 13026 | const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash); |
| 13156 | 13027 | ||
| ... | @@ -13210,7 +13081,7 @@ const GenZir = struct { | ... | @@ -13210,7 +13081,7 @@ const GenZir = struct { |
| 13210 | const astgen = gz.astgen; | 13081 | const astgen = gz.astgen; |
| 13211 | const gpa = astgen.gpa; | 13082 | const gpa = astgen.gpa; |
| 13212 | 13083 | ||
| 13213 | assert(args.src_node != 0); | 13084 | assert(args.src_node != .root); |
| 13214 | 13085 | ||
| 13215 | const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash); | 13086 | const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash); |
| 13216 | 13087 | ||
| ... | @@ -13272,7 +13143,7 @@ const GenZir = struct { | ... | @@ -13272,7 +13143,7 @@ const GenZir = struct { |
| 13272 | const astgen = gz.astgen; | 13143 | const astgen = gz.astgen; |
| 13273 | const gpa = astgen.gpa; | 13144 | const gpa = astgen.gpa; |
| 13274 | 13145 | ||
| 13275 | assert(args.src_node != 0); | 13146 | assert(args.src_node != .root); |
| 13276 | 13147 | ||
| 13277 | const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash); | 13148 | const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash); |
| 13278 | 13149 | ||
| ... | @@ -13327,7 +13198,7 @@ const GenZir = struct { | ... | @@ -13327,7 +13198,7 @@ const GenZir = struct { |
| 13327 | const astgen = gz.astgen; | 13198 | const astgen = gz.astgen; |
| 13328 | const gpa = astgen.gpa; | 13199 | const gpa = astgen.gpa; |
| 13329 | 13200 | ||
| 13330 | assert(args.src_node != 0); | 13201 | assert(args.src_node != .root); |
| 13331 | 13202 | ||
| 13332 | try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.OpaqueDecl).@"struct".fields.len + 2); | 13203 | try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.OpaqueDecl).@"struct".fields.len + 2); |
| 13333 | const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.OpaqueDecl{ | 13204 | const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.OpaqueDecl{ |
| ... | @@ -13521,9 +13392,7 @@ fn maybeAdvanceSourceCursorToMainToken(gz: *GenZir, node: Ast.Node.Index) LineCo | ... | @@ -13521,9 +13392,7 @@ fn maybeAdvanceSourceCursorToMainToken(gz: *GenZir, node: Ast.Node.Index) LineCo |
| 13521 | if (gz.is_comptime) return .{ gz.astgen.source_line - gz.decl_line, gz.astgen.source_column }; | 13392 | if (gz.is_comptime) return .{ gz.astgen.source_line - gz.decl_line, gz.astgen.source_column }; |
| 13522 | 13393 | ||
| 13523 | const tree = gz.astgen.tree; | 13394 | const tree = gz.astgen.tree; |
| 13524 | const token_starts = tree.tokens.items(.start); | 13395 | const node_start = tree.tokenStart(tree.nodeMainToken(node)); |
| 13525 | const main_tokens = tree.nodes.items(.main_token); | ||
| 13526 | const node_start = token_starts[main_tokens[node]]; | ||
| 13527 | gz.astgen.advanceSourceCursor(node_start); | 13396 | gz.astgen.advanceSourceCursor(node_start); |
| 13528 | 13397 | ||
| 13529 | return .{ gz.astgen.source_line - gz.decl_line, gz.astgen.source_column }; | 13398 | return .{ gz.astgen.source_line - gz.decl_line, gz.astgen.source_column }; |
| ... | @@ -13532,8 +13401,7 @@ fn maybeAdvanceSourceCursorToMainToken(gz: *GenZir, node: Ast.Node.Index) LineCo | ... | @@ -13532,8 +13401,7 @@ fn maybeAdvanceSourceCursorToMainToken(gz: *GenZir, node: Ast.Node.Index) LineCo |
| 13532 | /// Advances the source cursor to the beginning of `node`. | 13401 | /// Advances the source cursor to the beginning of `node`. |
| 13533 | fn advanceSourceCursorToNode(astgen: *AstGen, node: Ast.Node.Index) void { | 13402 | fn advanceSourceCursorToNode(astgen: *AstGen, node: Ast.Node.Index) void { |
| 13534 | const tree = astgen.tree; | 13403 | const tree = astgen.tree; |
| 13535 | const token_starts = tree.tokens.items(.start); | 13404 | const node_start = tree.tokenStart(tree.firstToken(node)); |
| 13536 | const node_start = token_starts[tree.firstToken(node)]; | ||
| 13537 | astgen.advanceSourceCursor(node_start); | 13405 | astgen.advanceSourceCursor(node_start); |
| 13538 | } | 13406 | } |
| 13539 | 13407 | ||
| ... | @@ -13588,9 +13456,6 @@ fn scanContainer( | ... | @@ -13588,9 +13456,6 @@ fn scanContainer( |
| 13588 | ) !u32 { | 13456 | ) !u32 { |
| 13589 | const gpa = astgen.gpa; | 13457 | const gpa = astgen.gpa; |
| 13590 | const tree = astgen.tree; | 13458 | const tree = astgen.tree; |
| 13591 | const node_tags = tree.nodes.items(.tag); | ||
| 13592 | const main_tokens = tree.nodes.items(.main_token); | ||
| 13593 | const token_tags = tree.tokens.items(.tag); | ||
| 13594 | 13459 | ||
| 13595 | var any_invalid_declarations = false; | 13460 | var any_invalid_declarations = false; |
| 13596 | 13461 | ||
| ... | @@ -13620,7 +13485,7 @@ fn scanContainer( | ... | @@ -13620,7 +13485,7 @@ fn scanContainer( |
| 13620 | var decl_count: u32 = 0; | 13485 | var decl_count: u32 = 0; |
| 13621 | for (members) |member_node| { | 13486 | for (members) |member_node| { |
| 13622 | const Kind = enum { decl, field }; | 13487 | const Kind = enum { decl, field }; |
| 13623 | const kind: Kind, const name_token = switch (node_tags[member_node]) { | 13488 | const kind: Kind, const name_token = switch (tree.nodeTag(member_node)) { |
| 13624 | .container_field_init, | 13489 | .container_field_init, |
| 13625 | .container_field_align, | 13490 | .container_field_align, |
| 13626 | .container_field, | 13491 | .container_field, |
| ... | @@ -13628,7 +13493,7 @@ fn scanContainer( | ... | @@ -13628,7 +13493,7 @@ fn scanContainer( |
| 13628 | var full = tree.fullContainerField(member_node).?; | 13493 | var full = tree.fullContainerField(member_node).?; |
| 13629 | switch (container_kind) { | 13494 | switch (container_kind) { |
| 13630 | .@"struct", .@"opaque" => {}, | 13495 | .@"struct", .@"opaque" => {}, |
| 13631 | .@"union", .@"enum" => full.convertToNonTupleLike(astgen.tree.nodes), | 13496 | .@"union", .@"enum" => full.convertToNonTupleLike(astgen.tree), |
| 13632 | } | 13497 | } |
| 13633 | if (full.ast.tuple_like) continue; | 13498 | if (full.ast.tuple_like) continue; |
| 13634 | break :blk .{ .field, full.ast.main_token }; | 13499 | break :blk .{ .field, full.ast.main_token }; |
| ... | @@ -13640,7 +13505,7 @@ fn scanContainer( | ... | @@ -13640,7 +13505,7 @@ fn scanContainer( |
| 13640 | .aligned_var_decl, | 13505 | .aligned_var_decl, |
| 13641 | => blk: { | 13506 | => blk: { |
| 13642 | decl_count += 1; | 13507 | decl_count += 1; |
| 13643 | break :blk .{ .decl, main_tokens[member_node] + 1 }; | 13508 | break :blk .{ .decl, tree.nodeMainToken(member_node) + 1 }; |
| 13644 | }, | 13509 | }, |
| 13645 | 13510 | ||
| 13646 | .fn_proto_simple, | 13511 | .fn_proto_simple, |
| ... | @@ -13650,8 +13515,8 @@ fn scanContainer( | ... | @@ -13650,8 +13515,8 @@ fn scanContainer( |
| 13650 | .fn_decl, | 13515 | .fn_decl, |
| 13651 | => blk: { | 13516 | => blk: { |
| 13652 | decl_count += 1; | 13517 | decl_count += 1; |
| 13653 | const ident = main_tokens[member_node] + 1; | 13518 | const ident = tree.nodeMainToken(member_node) + 1; |
| 13654 | if (token_tags[ident] != .identifier) { | 13519 | if (tree.tokenTag(ident) != .identifier) { |
| 13655 | try astgen.appendErrorNode(member_node, "missing function name", .{}); | 13520 | try astgen.appendErrorNode(member_node, "missing function name", .{}); |
| 13656 | any_invalid_declarations = true; | 13521 | any_invalid_declarations = true; |
| 13657 | continue; | 13522 | continue; |
| ... | @@ -13668,12 +13533,12 @@ fn scanContainer( | ... | @@ -13668,12 +13533,12 @@ fn scanContainer( |
| 13668 | decl_count += 1; | 13533 | decl_count += 1; |
| 13669 | // We don't want shadowing detection here, and test names work a bit differently, so | 13534 | // We don't want shadowing detection here, and test names work a bit differently, so |
| 13670 | // we must do the redeclaration detection ourselves. | 13535 | // we must do the redeclaration detection ourselves. |
| 13671 | const test_name_token = main_tokens[member_node] + 1; | 13536 | const test_name_token = tree.nodeMainToken(member_node) + 1; |
| 13672 | const new_ent: NameEntry = .{ | 13537 | const new_ent: NameEntry = .{ |
| 13673 | .tok = test_name_token, | 13538 | .tok = test_name_token, |
| 13674 | .next = null, | 13539 | .next = null, |
| 13675 | }; | 13540 | }; |
| 13676 | switch (token_tags[test_name_token]) { | 13541 | switch (tree.tokenTag(test_name_token)) { |
| 13677 | else => {}, // unnamed test | 13542 | else => {}, // unnamed test |
| 13678 | .string_literal => { | 13543 | .string_literal => { |
| 13679 | const name = try astgen.strLitAsString(test_name_token); | 13544 | const name = try astgen.strLitAsString(test_name_token); |
| ... | @@ -14275,3 +14140,7 @@ fn fetchRemoveRefEntries(astgen: *AstGen, param_insts: []const Zir.Inst.Index) ! | ... | @@ -14275,3 +14140,7 @@ fn fetchRemoveRefEntries(astgen: *AstGen, param_insts: []const Zir.Inst.Index) ! |
| 14275 | } | 14140 | } |
| 14276 | return refs.items; | 14141 | return refs.items; |
| 14277 | } | 14142 | } |
| 14143 | |||
| 14144 | test { | ||
| 14145 | _ = &generate; | ||
| 14146 | } |
lib/std/zig/AstRlAnnotate.zig+159-142| ... | @@ -92,27 +92,26 @@ fn containerDecl( | ... | @@ -92,27 +92,26 @@ fn containerDecl( |
| 92 | full: Ast.full.ContainerDecl, | 92 | full: Ast.full.ContainerDecl, |
| 93 | ) !void { | 93 | ) !void { |
| 94 | const tree = astrl.tree; | 94 | const tree = astrl.tree; |
| 95 | const token_tags = tree.tokens.items(.tag); | 95 | switch (tree.tokenTag(full.ast.main_token)) { |
| 96 | switch (token_tags[full.ast.main_token]) { | ||
| 97 | .keyword_struct => { | 96 | .keyword_struct => { |
| 98 | if (full.ast.arg != 0) { | 97 | if (full.ast.arg.unwrap()) |arg| { |
| 99 | _ = try astrl.expr(full.ast.arg, block, ResultInfo.type_only); | 98 | _ = try astrl.expr(arg, block, ResultInfo.type_only); |
| 100 | } | 99 | } |
| 101 | for (full.ast.members) |member_node| { | 100 | for (full.ast.members) |member_node| { |
| 102 | _ = try astrl.expr(member_node, block, ResultInfo.none); | 101 | _ = try astrl.expr(member_node, block, ResultInfo.none); |
| 103 | } | 102 | } |
| 104 | }, | 103 | }, |
| 105 | .keyword_union => { | 104 | .keyword_union => { |
| 106 | if (full.ast.arg != 0) { | 105 | if (full.ast.arg.unwrap()) |arg| { |
| 107 | _ = try astrl.expr(full.ast.arg, block, ResultInfo.type_only); | 106 | _ = try astrl.expr(arg, block, ResultInfo.type_only); |
| 108 | } | 107 | } |
| 109 | for (full.ast.members) |member_node| { | 108 | for (full.ast.members) |member_node| { |
| 110 | _ = try astrl.expr(member_node, block, ResultInfo.none); | 109 | _ = try astrl.expr(member_node, block, ResultInfo.none); |
| 111 | } | 110 | } |
| 112 | }, | 111 | }, |
| 113 | .keyword_enum => { | 112 | .keyword_enum => { |
| 114 | if (full.ast.arg != 0) { | 113 | if (full.ast.arg.unwrap()) |arg| { |
| 115 | _ = try astrl.expr(full.ast.arg, block, ResultInfo.type_only); | 114 | _ = try astrl.expr(arg, block, ResultInfo.type_only); |
| 116 | } | 115 | } |
| 117 | for (full.ast.members) |member_node| { | 116 | for (full.ast.members) |member_node| { |
| 118 | _ = try astrl.expr(member_node, block, ResultInfo.none); | 117 | _ = try astrl.expr(member_node, block, ResultInfo.none); |
| ... | @@ -130,10 +129,7 @@ fn containerDecl( | ... | @@ -130,10 +129,7 @@ fn containerDecl( |
| 130 | /// Returns true if `rl` provides a result pointer and the expression consumes it. | 129 | /// Returns true if `rl` provides a result pointer and the expression consumes it. |
| 131 | fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultInfo) Allocator.Error!bool { | 130 | fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultInfo) Allocator.Error!bool { |
| 132 | const tree = astrl.tree; | 131 | const tree = astrl.tree; |
| 133 | const token_tags = tree.tokens.items(.tag); | 132 | switch (tree.nodeTag(node)) { |
| 134 | const node_datas = tree.nodes.items(.data); | ||
| 135 | const node_tags = tree.nodes.items(.tag); | ||
| 136 | switch (node_tags[node]) { | ||
| 137 | .root, | 133 | .root, |
| 138 | .switch_case_one, | 134 | .switch_case_one, |
| 139 | .switch_case_inline_one, | 135 | .switch_case_inline_one, |
| ... | @@ -145,8 +141,12 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -145,8 +141,12 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 145 | .asm_input, | 141 | .asm_input, |
| 146 | => unreachable, | 142 | => unreachable, |
| 147 | 143 | ||
| 148 | .@"errdefer", .@"defer" => { | 144 | .@"errdefer" => { |
| 149 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | 145 | _ = try astrl.expr(tree.nodeData(node).opt_token_and_node[1], block, ResultInfo.none); |
| 146 | return false; | ||
| 147 | }, | ||
| 148 | .@"defer" => { | ||
| 149 | _ = try astrl.expr(tree.nodeData(node).node, block, ResultInfo.none); | ||
| 150 | return false; | 150 | return false; |
| 151 | }, | 151 | }, |
| 152 | 152 | ||
| ... | @@ -155,21 +155,22 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -155,21 +155,22 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 155 | .container_field, | 155 | .container_field, |
| 156 | => { | 156 | => { |
| 157 | const full = tree.fullContainerField(node).?; | 157 | const full = tree.fullContainerField(node).?; |
| 158 | _ = try astrl.expr(full.ast.type_expr, block, ResultInfo.type_only); | 158 | const type_expr = full.ast.type_expr.unwrap().?; |
| 159 | if (full.ast.align_expr != 0) { | 159 | _ = try astrl.expr(type_expr, block, ResultInfo.type_only); |
| 160 | _ = try astrl.expr(full.ast.align_expr, block, ResultInfo.type_only); | 160 | if (full.ast.align_expr.unwrap()) |align_expr| { |
| 161 | _ = try astrl.expr(align_expr, block, ResultInfo.type_only); | ||
| 161 | } | 162 | } |
| 162 | if (full.ast.value_expr != 0) { | 163 | if (full.ast.value_expr.unwrap()) |value_expr| { |
| 163 | _ = try astrl.expr(full.ast.value_expr, block, ResultInfo.type_only); | 164 | _ = try astrl.expr(value_expr, block, ResultInfo.type_only); |
| 164 | } | 165 | } |
| 165 | return false; | 166 | return false; |
| 166 | }, | 167 | }, |
| 167 | .@"usingnamespace" => { | 168 | .@"usingnamespace" => { |
| 168 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | 169 | _ = try astrl.expr(tree.nodeData(node).node, block, ResultInfo.type_only); |
| 169 | return false; | 170 | return false; |
| 170 | }, | 171 | }, |
| 171 | .test_decl => { | 172 | .test_decl => { |
| 172 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | 173 | _ = try astrl.expr(tree.nodeData(node).opt_token_and_node[1], block, ResultInfo.none); |
| 173 | return false; | 174 | return false; |
| 174 | }, | 175 | }, |
| 175 | .global_var_decl, | 176 | .global_var_decl, |
| ... | @@ -178,17 +179,17 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -178,17 +179,17 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 178 | .aligned_var_decl, | 179 | .aligned_var_decl, |
| 179 | => { | 180 | => { |
| 180 | const full = tree.fullVarDecl(node).?; | 181 | const full = tree.fullVarDecl(node).?; |
| 181 | const init_ri = if (full.ast.type_node != 0) init_ri: { | 182 | const init_ri = if (full.ast.type_node.unwrap()) |type_node| init_ri: { |
| 182 | _ = try astrl.expr(full.ast.type_node, block, ResultInfo.type_only); | 183 | _ = try astrl.expr(type_node, block, ResultInfo.type_only); |
| 183 | break :init_ri ResultInfo.typed_ptr; | 184 | break :init_ri ResultInfo.typed_ptr; |
| 184 | } else ResultInfo.inferred_ptr; | 185 | } else ResultInfo.inferred_ptr; |
| 185 | if (full.ast.init_node == 0) { | 186 | const init_node = full.ast.init_node.unwrap() orelse { |
| 186 | // No init node, so we're done. | 187 | // No init node, so we're done. |
| 187 | return false; | 188 | return false; |
| 188 | } | 189 | }; |
| 189 | switch (token_tags[full.ast.mut_token]) { | 190 | switch (tree.tokenTag(full.ast.mut_token)) { |
| 190 | .keyword_const => { | 191 | .keyword_const => { |
| 191 | const init_consumes_rl = try astrl.expr(full.ast.init_node, block, init_ri); | 192 | const init_consumes_rl = try astrl.expr(init_node, block, init_ri); |
| 192 | if (init_consumes_rl) { | 193 | if (init_consumes_rl) { |
| 193 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | 194 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); |
| 194 | } | 195 | } |
| ... | @@ -197,7 +198,7 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -197,7 +198,7 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 197 | .keyword_var => { | 198 | .keyword_var => { |
| 198 | // We'll create an alloc either way, so don't care if the | 199 | // We'll create an alloc either way, so don't care if the |
| 199 | // result pointer is consumed. | 200 | // result pointer is consumed. |
| 200 | _ = try astrl.expr(full.ast.init_node, block, init_ri); | 201 | _ = try astrl.expr(init_node, block, init_ri); |
| 201 | return false; | 202 | return false; |
| 202 | }, | 203 | }, |
| 203 | else => unreachable, | 204 | else => unreachable, |
| ... | @@ -213,8 +214,9 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -213,8 +214,9 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 213 | return false; | 214 | return false; |
| 214 | }, | 215 | }, |
| 215 | .assign => { | 216 | .assign => { |
| 216 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 217 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 217 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.typed_ptr); | 218 | _ = try astrl.expr(lhs, block, ResultInfo.none); |
| 219 | _ = try astrl.expr(rhs, block, ResultInfo.typed_ptr); | ||
| 218 | return false; | 220 | return false; |
| 219 | }, | 221 | }, |
| 220 | .assign_shl, | 222 | .assign_shl, |
| ... | @@ -235,13 +237,15 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -235,13 +237,15 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 235 | .assign_mul_wrap, | 237 | .assign_mul_wrap, |
| 236 | .assign_mul_sat, | 238 | .assign_mul_sat, |
| 237 | => { | 239 | => { |
| 238 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 240 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 239 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | 241 | _ = try astrl.expr(lhs, block, ResultInfo.none); |
| 242 | _ = try astrl.expr(rhs, block, ResultInfo.none); | ||
| 240 | return false; | 243 | return false; |
| 241 | }, | 244 | }, |
| 242 | .shl, .shr => { | 245 | .shl, .shr => { |
| 243 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 246 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 244 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | 247 | _ = try astrl.expr(lhs, block, ResultInfo.none); |
| 248 | _ = try astrl.expr(rhs, block, ResultInfo.type_only); | ||
| 245 | return false; | 249 | return false; |
| 246 | }, | 250 | }, |
| 247 | .add, | 251 | .add, |
| ... | @@ -267,33 +271,38 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -267,33 +271,38 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 267 | .less_or_equal, | 271 | .less_or_equal, |
| 268 | .array_cat, | 272 | .array_cat, |
| 269 | => { | 273 | => { |
| 270 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 274 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 271 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | 275 | _ = try astrl.expr(lhs, block, ResultInfo.none); |
| 276 | _ = try astrl.expr(rhs, block, ResultInfo.none); | ||
| 272 | return false; | 277 | return false; |
| 273 | }, | 278 | }, |
| 279 | |||
| 274 | .array_mult => { | 280 | .array_mult => { |
| 275 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 281 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 276 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | 282 | _ = try astrl.expr(lhs, block, ResultInfo.none); |
| 283 | _ = try astrl.expr(rhs, block, ResultInfo.type_only); | ||
| 277 | return false; | 284 | return false; |
| 278 | }, | 285 | }, |
| 279 | .error_union, .merge_error_sets => { | 286 | .error_union, .merge_error_sets => { |
| 280 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 287 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 281 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | 288 | _ = try astrl.expr(lhs, block, ResultInfo.none); |
| 289 | _ = try astrl.expr(rhs, block, ResultInfo.none); | ||
| 282 | return false; | 290 | return false; |
| 283 | }, | 291 | }, |
| 284 | .bool_and, | 292 | .bool_and, |
| 285 | .bool_or, | 293 | .bool_or, |
| 286 | => { | 294 | => { |
| 287 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | 295 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 288 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | 296 | _ = try astrl.expr(lhs, block, ResultInfo.type_only); |
| 297 | _ = try astrl.expr(rhs, block, ResultInfo.type_only); | ||
| 289 | return false; | 298 | return false; |
| 290 | }, | 299 | }, |
| 291 | .bool_not => { | 300 | .bool_not => { |
| 292 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | 301 | _ = try astrl.expr(tree.nodeData(node).node, block, ResultInfo.type_only); |
| 293 | return false; | 302 | return false; |
| 294 | }, | 303 | }, |
| 295 | .bit_not, .negation, .negation_wrap => { | 304 | .bit_not, .negation, .negation_wrap => { |
| 296 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 305 | _ = try astrl.expr(tree.nodeData(node).node, block, ResultInfo.none); |
| 297 | return false; | 306 | return false; |
| 298 | }, | 307 | }, |
| 299 | 308 | ||
| ... | @@ -338,7 +347,7 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -338,7 +347,7 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 338 | for (full.ast.params) |param_node| { | 347 | for (full.ast.params) |param_node| { |
| 339 | _ = try astrl.expr(param_node, block, ResultInfo.type_only); | 348 | _ = try astrl.expr(param_node, block, ResultInfo.type_only); |
| 340 | } | 349 | } |
| 341 | return switch (node_tags[node]) { | 350 | return switch (tree.nodeTag(node)) { |
| 342 | .call_one, | 351 | .call_one, |
| 343 | .call_one_comma, | 352 | .call_one_comma, |
| 344 | .call, | 353 | .call, |
| ... | @@ -354,8 +363,8 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -354,8 +363,8 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 354 | }, | 363 | }, |
| 355 | 364 | ||
| 356 | .@"return" => { | 365 | .@"return" => { |
| 357 | if (node_datas[node].lhs != 0) { | 366 | if (tree.nodeData(node).opt_node.unwrap()) |lhs| { |
| 358 | const ret_val_consumes_rl = try astrl.expr(node_datas[node].lhs, block, ResultInfo.typed_ptr); | 367 | const ret_val_consumes_rl = try astrl.expr(lhs, block, ResultInfo.typed_ptr); |
| 359 | if (ret_val_consumes_rl) { | 368 | if (ret_val_consumes_rl) { |
| 360 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | 369 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); |
| 361 | } | 370 | } |
| ... | @@ -364,7 +373,8 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -364,7 +373,8 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 364 | }, | 373 | }, |
| 365 | 374 | ||
| 366 | .field_access => { | 375 | .field_access => { |
| 367 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 376 | const lhs, _ = tree.nodeData(node).node_and_token; |
| 377 | _ = try astrl.expr(lhs, block, ResultInfo.none); | ||
| 368 | return false; | 378 | return false; |
| 369 | }, | 379 | }, |
| 370 | 380 | ||
| ... | @@ -376,15 +386,15 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -376,15 +386,15 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 376 | _ = try astrl.expr(full.ast.cond_expr, block, ResultInfo.type_only); // bool | 386 | _ = try astrl.expr(full.ast.cond_expr, block, ResultInfo.type_only); // bool |
| 377 | } | 387 | } |
| 378 | 388 | ||
| 379 | if (full.ast.else_expr == 0) { | 389 | if (full.ast.else_expr.unwrap()) |else_expr| { |
| 380 | _ = try astrl.expr(full.ast.then_expr, block, ResultInfo.none); | ||
| 381 | return false; | ||
| 382 | } else { | ||
| 383 | const then_uses_rl = try astrl.expr(full.ast.then_expr, block, ri); | 390 | const then_uses_rl = try astrl.expr(full.ast.then_expr, block, ri); |
| 384 | const else_uses_rl = try astrl.expr(full.ast.else_expr, block, ri); | 391 | const else_uses_rl = try astrl.expr(else_expr, block, ri); |
| 385 | const uses_rl = then_uses_rl or else_uses_rl; | 392 | const uses_rl = then_uses_rl or else_uses_rl; |
| 386 | if (uses_rl) try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | 393 | if (uses_rl) try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); |
| 387 | return uses_rl; | 394 | return uses_rl; |
| 395 | } else { | ||
| 396 | _ = try astrl.expr(full.ast.then_expr, block, ResultInfo.none); | ||
| 397 | return false; | ||
| 388 | } | 398 | } |
| 389 | }, | 399 | }, |
| 390 | 400 | ||
| ... | @@ -405,12 +415,12 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -405,12 +415,12 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 405 | .ri = ri, | 415 | .ri = ri, |
| 406 | .consumes_res_ptr = false, | 416 | .consumes_res_ptr = false, |
| 407 | }; | 417 | }; |
| 408 | if (full.ast.cont_expr != 0) { | 418 | if (full.ast.cont_expr.unwrap()) |cont_expr| { |
| 409 | _ = try astrl.expr(full.ast.cont_expr, &new_block, ResultInfo.none); | 419 | _ = try astrl.expr(cont_expr, &new_block, ResultInfo.none); |
| 410 | } | 420 | } |
| 411 | _ = try astrl.expr(full.ast.then_expr, &new_block, ResultInfo.none); | 421 | _ = try astrl.expr(full.ast.then_expr, &new_block, ResultInfo.none); |
| 412 | const else_consumes_rl = if (full.ast.else_expr != 0) else_rl: { | 422 | const else_consumes_rl = if (full.ast.else_expr.unwrap()) |else_expr| else_rl: { |
| 413 | break :else_rl try astrl.expr(full.ast.else_expr, block, ri); | 423 | break :else_rl try astrl.expr(else_expr, block, ri); |
| 414 | } else false; | 424 | } else false; |
| 415 | if (new_block.consumes_res_ptr or else_consumes_rl) { | 425 | if (new_block.consumes_res_ptr or else_consumes_rl) { |
| 416 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | 426 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); |
| ... | @@ -426,10 +436,11 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -426,10 +436,11 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 426 | break :label try astrl.identString(label_token); | 436 | break :label try astrl.identString(label_token); |
| 427 | } else null; | 437 | } else null; |
| 428 | for (full.ast.inputs) |input| { | 438 | for (full.ast.inputs) |input| { |
| 429 | if (node_tags[input] == .for_range) { | 439 | if (tree.nodeTag(input) == .for_range) { |
| 430 | _ = try astrl.expr(node_datas[input].lhs, block, ResultInfo.type_only); | 440 | const lhs, const opt_rhs = tree.nodeData(input).node_and_opt_node; |
| 431 | if (node_datas[input].rhs != 0) { | 441 | _ = try astrl.expr(lhs, block, ResultInfo.type_only); |
| 432 | _ = try astrl.expr(node_datas[input].rhs, block, ResultInfo.type_only); | 442 | if (opt_rhs.unwrap()) |rhs| { |
| 443 | _ = try astrl.expr(rhs, block, ResultInfo.type_only); | ||
| 433 | } | 444 | } |
| 434 | } else { | 445 | } else { |
| 435 | _ = try astrl.expr(input, block, ResultInfo.none); | 446 | _ = try astrl.expr(input, block, ResultInfo.none); |
| ... | @@ -443,8 +454,8 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -443,8 +454,8 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 443 | .consumes_res_ptr = false, | 454 | .consumes_res_ptr = false, |
| 444 | }; | 455 | }; |
| 445 | _ = try astrl.expr(full.ast.then_expr, &new_block, ResultInfo.none); | 456 | _ = try astrl.expr(full.ast.then_expr, &new_block, ResultInfo.none); |
| 446 | const else_consumes_rl = if (full.ast.else_expr != 0) else_rl: { | 457 | const else_consumes_rl = if (full.ast.else_expr.unwrap()) |else_expr| else_rl: { |
| 447 | break :else_rl try astrl.expr(full.ast.else_expr, block, ri); | 458 | break :else_rl try astrl.expr(else_expr, block, ri); |
| 448 | } else false; | 459 | } else false; |
| 449 | if (new_block.consumes_res_ptr or else_consumes_rl) { | 460 | if (new_block.consumes_res_ptr or else_consumes_rl) { |
| 450 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | 461 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); |
| ... | @@ -455,45 +466,49 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -455,45 +466,49 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 455 | }, | 466 | }, |
| 456 | 467 | ||
| 457 | .slice_open => { | 468 | .slice_open => { |
| 458 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 469 | const sliced, const start = tree.nodeData(node).node_and_node; |
| 459 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | 470 | _ = try astrl.expr(sliced, block, ResultInfo.none); |
| 471 | _ = try astrl.expr(start, block, ResultInfo.type_only); | ||
| 460 | return false; | 472 | return false; |
| 461 | }, | 473 | }, |
| 462 | .slice => { | 474 | .slice => { |
| 463 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.Slice); | 475 | const sliced, const extra_index = tree.nodeData(node).node_and_extra; |
| 464 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 476 | const extra = tree.extraData(extra_index, Ast.Node.Slice); |
| 477 | _ = try astrl.expr(sliced, block, ResultInfo.none); | ||
| 465 | _ = try astrl.expr(extra.start, block, ResultInfo.type_only); | 478 | _ = try astrl.expr(extra.start, block, ResultInfo.type_only); |
| 466 | _ = try astrl.expr(extra.end, block, ResultInfo.type_only); | 479 | _ = try astrl.expr(extra.end, block, ResultInfo.type_only); |
| 467 | return false; | 480 | return false; |
| 468 | }, | 481 | }, |
| 469 | .slice_sentinel => { | 482 | .slice_sentinel => { |
| 470 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.SliceSentinel); | 483 | const sliced, const extra_index = tree.nodeData(node).node_and_extra; |
| 471 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 484 | const extra = tree.extraData(extra_index, Ast.Node.SliceSentinel); |
| 485 | _ = try astrl.expr(sliced, block, ResultInfo.none); | ||
| 472 | _ = try astrl.expr(extra.start, block, ResultInfo.type_only); | 486 | _ = try astrl.expr(extra.start, block, ResultInfo.type_only); |
| 473 | if (extra.end != 0) { | 487 | if (extra.end.unwrap()) |end| { |
| 474 | _ = try astrl.expr(extra.end, block, ResultInfo.type_only); | 488 | _ = try astrl.expr(end, block, ResultInfo.type_only); |
| 475 | } | 489 | } |
| 476 | _ = try astrl.expr(extra.sentinel, block, ResultInfo.none); | 490 | _ = try astrl.expr(extra.sentinel, block, ResultInfo.none); |
| 477 | return false; | 491 | return false; |
| 478 | }, | 492 | }, |
| 479 | .deref => { | 493 | .deref => { |
| 480 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 494 | _ = try astrl.expr(tree.nodeData(node).node, block, ResultInfo.none); |
| 481 | return false; | 495 | return false; |
| 482 | }, | 496 | }, |
| 483 | .address_of => { | 497 | .address_of => { |
| 484 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 498 | _ = try astrl.expr(tree.nodeData(node).node, block, ResultInfo.none); |
| 485 | return false; | 499 | return false; |
| 486 | }, | 500 | }, |
| 487 | .optional_type => { | 501 | .optional_type => { |
| 488 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | 502 | _ = try astrl.expr(tree.nodeData(node).node, block, ResultInfo.type_only); |
| 489 | return false; | 503 | return false; |
| 490 | }, | 504 | }, |
| 491 | .grouped_expression, | ||
| 492 | .@"try", | 505 | .@"try", |
| 493 | .@"await", | 506 | .@"await", |
| 494 | .@"nosuspend", | 507 | .@"nosuspend", |
| 508 | => return astrl.expr(tree.nodeData(node).node, block, ri), | ||
| 509 | .grouped_expression, | ||
| 495 | .unwrap_optional, | 510 | .unwrap_optional, |
| 496 | => return astrl.expr(node_datas[node].lhs, block, ri), | 511 | => return astrl.expr(tree.nodeData(node).node_and_token[0], block, ri), |
| 497 | 512 | ||
| 498 | .block_two, | 513 | .block_two, |
| 499 | .block_two_semicolon, | 514 | .block_two_semicolon, |
| ... | @@ -505,12 +520,14 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -505,12 +520,14 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 505 | return astrl.blockExpr(block, ri, node, statements); | 520 | return astrl.blockExpr(block, ri, node, statements); |
| 506 | }, | 521 | }, |
| 507 | .anyframe_type => { | 522 | .anyframe_type => { |
| 508 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | 523 | _, const child_type = tree.nodeData(node).token_and_node; |
| 524 | _ = try astrl.expr(child_type, block, ResultInfo.type_only); | ||
| 509 | return false; | 525 | return false; |
| 510 | }, | 526 | }, |
| 511 | .@"catch", .@"orelse" => { | 527 | .@"catch", .@"orelse" => { |
| 512 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 528 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 513 | const rhs_consumes_rl = try astrl.expr(node_datas[node].rhs, block, ri); | 529 | _ = try astrl.expr(lhs, block, ResultInfo.none); |
| 530 | const rhs_consumes_rl = try astrl.expr(rhs, block, ri); | ||
| 514 | if (rhs_consumes_rl) { | 531 | if (rhs_consumes_rl) { |
| 515 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | 532 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); |
| 516 | } | 533 | } |
| ... | @@ -524,19 +541,19 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -524,19 +541,19 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 524 | => { | 541 | => { |
| 525 | const full = tree.fullPtrType(node).?; | 542 | const full = tree.fullPtrType(node).?; |
| 526 | _ = try astrl.expr(full.ast.child_type, block, ResultInfo.type_only); | 543 | _ = try astrl.expr(full.ast.child_type, block, ResultInfo.type_only); |
| 527 | if (full.ast.sentinel != 0) { | 544 | if (full.ast.sentinel.unwrap()) |sentinel| { |
| 528 | _ = try astrl.expr(full.ast.sentinel, block, ResultInfo.type_only); | 545 | _ = try astrl.expr(sentinel, block, ResultInfo.type_only); |
| 529 | } | 546 | } |
| 530 | if (full.ast.addrspace_node != 0) { | 547 | if (full.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 531 | _ = try astrl.expr(full.ast.addrspace_node, block, ResultInfo.type_only); | 548 | _ = try astrl.expr(addrspace_node, block, ResultInfo.type_only); |
| 532 | } | 549 | } |
| 533 | if (full.ast.align_node != 0) { | 550 | if (full.ast.align_node.unwrap()) |align_node| { |
| 534 | _ = try astrl.expr(full.ast.align_node, block, ResultInfo.type_only); | 551 | _ = try astrl.expr(align_node, block, ResultInfo.type_only); |
| 535 | } | 552 | } |
| 536 | if (full.ast.bit_range_start != 0) { | 553 | if (full.ast.bit_range_start.unwrap()) |bit_range_start| { |
| 537 | assert(full.ast.bit_range_end != 0); | 554 | const bit_range_end = full.ast.bit_range_end.unwrap().?; |
| 538 | _ = try astrl.expr(full.ast.bit_range_start, block, ResultInfo.type_only); | 555 | _ = try astrl.expr(bit_range_start, block, ResultInfo.type_only); |
| 539 | _ = try astrl.expr(full.ast.bit_range_end, block, ResultInfo.type_only); | 556 | _ = try astrl.expr(bit_range_end, block, ResultInfo.type_only); |
| 540 | } | 557 | } |
| 541 | return false; | 558 | return false; |
| 542 | }, | 559 | }, |
| ... | @@ -560,63 +577,66 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -560,63 +577,66 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 560 | }, | 577 | }, |
| 561 | 578 | ||
| 562 | .@"break" => { | 579 | .@"break" => { |
| 563 | if (node_datas[node].rhs == 0) { | 580 | const opt_label, const opt_rhs = tree.nodeData(node).opt_token_and_opt_node; |
| 581 | const rhs = opt_rhs.unwrap() orelse { | ||
| 564 | // Breaks with void are not interesting | 582 | // Breaks with void are not interesting |
| 565 | return false; | 583 | return false; |
| 566 | } | 584 | }; |
| 567 | 585 | ||
| 568 | var opt_cur_block = block; | 586 | var opt_cur_block = block; |
| 569 | if (node_datas[node].lhs == 0) { | 587 | if (opt_label.unwrap()) |label_token| { |
| 570 | // No label - we're breaking from a loop. | 588 | const break_label = try astrl.identString(label_token); |
| 571 | while (opt_cur_block) |cur_block| : (opt_cur_block = cur_block.parent) { | 589 | while (opt_cur_block) |cur_block| : (opt_cur_block = cur_block.parent) { |
| 572 | if (cur_block.is_loop) break; | 590 | const block_label = cur_block.label orelse continue; |
| 591 | if (std.mem.eql(u8, block_label, break_label)) break; | ||
| 573 | } | 592 | } |
| 574 | } else { | 593 | } else { |
| 575 | const break_label = try astrl.identString(node_datas[node].lhs); | 594 | // No label - we're breaking from a loop. |
| 576 | while (opt_cur_block) |cur_block| : (opt_cur_block = cur_block.parent) { | 595 | while (opt_cur_block) |cur_block| : (opt_cur_block = cur_block.parent) { |
| 577 | const block_label = cur_block.label orelse continue; | 596 | if (cur_block.is_loop) break; |
| 578 | if (std.mem.eql(u8, block_label, break_label)) break; | ||
| 579 | } | 597 | } |
| 580 | } | 598 | } |
| 581 | 599 | ||
| 582 | if (opt_cur_block) |target_block| { | 600 | if (opt_cur_block) |target_block| { |
| 583 | const consumes_break_rl = try astrl.expr(node_datas[node].rhs, block, target_block.ri); | 601 | const consumes_break_rl = try astrl.expr(rhs, block, target_block.ri); |
| 584 | if (consumes_break_rl) target_block.consumes_res_ptr = true; | 602 | if (consumes_break_rl) target_block.consumes_res_ptr = true; |
| 585 | } else { | 603 | } else { |
| 586 | // No corresponding scope to break from - AstGen will emit an error. | 604 | // No corresponding scope to break from - AstGen will emit an error. |
| 587 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | 605 | _ = try astrl.expr(rhs, block, ResultInfo.none); |
| 588 | } | 606 | } |
| 589 | 607 | ||
| 590 | return false; | 608 | return false; |
| 591 | }, | 609 | }, |
| 592 | 610 | ||
| 593 | .array_type => { | 611 | .array_type => { |
| 594 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | 612 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 595 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | 613 | _ = try astrl.expr(lhs, block, ResultInfo.type_only); |
| 614 | _ = try astrl.expr(rhs, block, ResultInfo.type_only); | ||
| 596 | return false; | 615 | return false; |
| 597 | }, | 616 | }, |
| 598 | .array_type_sentinel => { | 617 | .array_type_sentinel => { |
| 599 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.ArrayTypeSentinel); | 618 | const len_expr, const extra_index = tree.nodeData(node).node_and_extra; |
| 600 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | 619 | const extra = tree.extraData(extra_index, Ast.Node.ArrayTypeSentinel); |
| 620 | _ = try astrl.expr(len_expr, block, ResultInfo.type_only); | ||
| 601 | _ = try astrl.expr(extra.elem_type, block, ResultInfo.type_only); | 621 | _ = try astrl.expr(extra.elem_type, block, ResultInfo.type_only); |
| 602 | _ = try astrl.expr(extra.sentinel, block, ResultInfo.type_only); | 622 | _ = try astrl.expr(extra.sentinel, block, ResultInfo.type_only); |
| 603 | return false; | 623 | return false; |
| 604 | }, | 624 | }, |
| 605 | .array_access => { | 625 | .array_access => { |
| 606 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 626 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 607 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.type_only); | 627 | _ = try astrl.expr(lhs, block, ResultInfo.none); |
| 628 | _ = try astrl.expr(rhs, block, ResultInfo.type_only); | ||
| 608 | return false; | 629 | return false; |
| 609 | }, | 630 | }, |
| 610 | .@"comptime" => { | 631 | .@"comptime" => { |
| 611 | // AstGen will emit an error if the scope is already comptime, so we can assume it is | 632 | // AstGen will emit an error if the scope is already comptime, so we can assume it is |
| 612 | // not. This means the result location is not forwarded. | 633 | // not. This means the result location is not forwarded. |
| 613 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 634 | _ = try astrl.expr(tree.nodeData(node).node, block, ResultInfo.none); |
| 614 | return false; | 635 | return false; |
| 615 | }, | 636 | }, |
| 616 | .@"switch", .switch_comma => { | 637 | .@"switch", .switch_comma => { |
| 617 | const operand_node = node_datas[node].lhs; | 638 | const operand_node, const extra_index = tree.nodeData(node).node_and_extra; |
| 618 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.SubRange); | 639 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); |
| 619 | const case_nodes = tree.extra_data[extra.start..extra.end]; | ||
| 620 | 640 | ||
| 621 | _ = try astrl.expr(operand_node, block, ResultInfo.none); | 641 | _ = try astrl.expr(operand_node, block, ResultInfo.none); |
| 622 | 642 | ||
| ... | @@ -624,9 +644,10 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -624,9 +644,10 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 624 | for (case_nodes) |case_node| { | 644 | for (case_nodes) |case_node| { |
| 625 | const case = tree.fullSwitchCase(case_node).?; | 645 | const case = tree.fullSwitchCase(case_node).?; |
| 626 | for (case.ast.values) |item_node| { | 646 | for (case.ast.values) |item_node| { |
| 627 | if (node_tags[item_node] == .switch_range) { | 647 | if (tree.nodeTag(item_node) == .switch_range) { |
| 628 | _ = try astrl.expr(node_datas[item_node].lhs, block, ResultInfo.none); | 648 | const lhs, const rhs = tree.nodeData(item_node).node_and_node; |
| 629 | _ = try astrl.expr(node_datas[item_node].rhs, block, ResultInfo.none); | 649 | _ = try astrl.expr(lhs, block, ResultInfo.none); |
| 650 | _ = try astrl.expr(rhs, block, ResultInfo.none); | ||
| 630 | } else { | 651 | } else { |
| 631 | _ = try astrl.expr(item_node, block, ResultInfo.none); | 652 | _ = try astrl.expr(item_node, block, ResultInfo.none); |
| 632 | } | 653 | } |
| ... | @@ -641,11 +662,11 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -641,11 +662,11 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 641 | return any_prong_consumed_rl; | 662 | return any_prong_consumed_rl; |
| 642 | }, | 663 | }, |
| 643 | .@"suspend" => { | 664 | .@"suspend" => { |
| 644 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 665 | _ = try astrl.expr(tree.nodeData(node).node, block, ResultInfo.none); |
| 645 | return false; | 666 | return false; |
| 646 | }, | 667 | }, |
| 647 | .@"resume" => { | 668 | .@"resume" => { |
| 648 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 669 | _ = try astrl.expr(tree.nodeData(node).node, block, ResultInfo.none); |
| 649 | return false; | 670 | return false; |
| 650 | }, | 671 | }, |
| 651 | 672 | ||
| ... | @@ -661,9 +682,9 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -661,9 +682,9 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 661 | var buf: [2]Ast.Node.Index = undefined; | 682 | var buf: [2]Ast.Node.Index = undefined; |
| 662 | const full = tree.fullArrayInit(&buf, node).?; | 683 | const full = tree.fullArrayInit(&buf, node).?; |
| 663 | 684 | ||
| 664 | if (full.ast.type_expr != 0) { | 685 | if (full.ast.type_expr.unwrap()) |type_expr| { |
| 665 | // Explicitly typed init does not participate in RLS | 686 | // Explicitly typed init does not participate in RLS |
| 666 | _ = try astrl.expr(full.ast.type_expr, block, ResultInfo.none); | 687 | _ = try astrl.expr(type_expr, block, ResultInfo.none); |
| 667 | for (full.ast.elements) |elem_init| { | 688 | for (full.ast.elements) |elem_init| { |
| 668 | _ = try astrl.expr(elem_init, block, ResultInfo.type_only); | 689 | _ = try astrl.expr(elem_init, block, ResultInfo.type_only); |
| 669 | } | 690 | } |
| ... | @@ -698,9 +719,9 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -698,9 +719,9 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 698 | var buf: [2]Ast.Node.Index = undefined; | 719 | var buf: [2]Ast.Node.Index = undefined; |
| 699 | const full = tree.fullStructInit(&buf, node).?; | 720 | const full = tree.fullStructInit(&buf, node).?; |
| 700 | 721 | ||
| 701 | if (full.ast.type_expr != 0) { | 722 | if (full.ast.type_expr.unwrap()) |type_expr| { |
| 702 | // Explicitly typed init does not participate in RLS | 723 | // Explicitly typed init does not participate in RLS |
| 703 | _ = try astrl.expr(full.ast.type_expr, block, ResultInfo.none); | 724 | _ = try astrl.expr(type_expr, block, ResultInfo.none); |
| 704 | for (full.ast.fields) |field_init| { | 725 | for (full.ast.fields) |field_init| { |
| 705 | _ = try astrl.expr(field_init, block, ResultInfo.type_only); | 726 | _ = try astrl.expr(field_init, block, ResultInfo.type_only); |
| 706 | } | 727 | } |
| ... | @@ -728,33 +749,35 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -728,33 +749,35 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 728 | .fn_proto_one, | 749 | .fn_proto_one, |
| 729 | .fn_proto, | 750 | .fn_proto, |
| 730 | .fn_decl, | 751 | .fn_decl, |
| 731 | => { | 752 | => |tag| { |
| 732 | var buf: [1]Ast.Node.Index = undefined; | 753 | var buf: [1]Ast.Node.Index = undefined; |
| 733 | const full = tree.fullFnProto(&buf, node).?; | 754 | const full = tree.fullFnProto(&buf, node).?; |
| 734 | const body_node = if (node_tags[node] == .fn_decl) node_datas[node].rhs else 0; | 755 | const body_node = if (tag == .fn_decl) tree.nodeData(node).node_and_node[1].toOptional() else .none; |
| 735 | { | 756 | { |
| 736 | var it = full.iterate(tree); | 757 | var it = full.iterate(tree); |
| 737 | while (it.next()) |param| { | 758 | while (it.next()) |param| { |
| 738 | if (param.anytype_ellipsis3 == null) { | 759 | if (param.anytype_ellipsis3 == null) { |
| 739 | _ = try astrl.expr(param.type_expr, block, ResultInfo.type_only); | 760 | const type_expr = param.type_expr.?; |
| 761 | _ = try astrl.expr(type_expr, block, ResultInfo.type_only); | ||
| 740 | } | 762 | } |
| 741 | } | 763 | } |
| 742 | } | 764 | } |
| 743 | if (full.ast.align_expr != 0) { | 765 | if (full.ast.align_expr.unwrap()) |align_expr| { |
| 744 | _ = try astrl.expr(full.ast.align_expr, block, ResultInfo.type_only); | 766 | _ = try astrl.expr(align_expr, block, ResultInfo.type_only); |
| 745 | } | 767 | } |
| 746 | if (full.ast.addrspace_expr != 0) { | 768 | if (full.ast.addrspace_expr.unwrap()) |addrspace_expr| { |
| 747 | _ = try astrl.expr(full.ast.addrspace_expr, block, ResultInfo.type_only); | 769 | _ = try astrl.expr(addrspace_expr, block, ResultInfo.type_only); |
| 748 | } | 770 | } |
| 749 | if (full.ast.section_expr != 0) { | 771 | if (full.ast.section_expr.unwrap()) |section_expr| { |
| 750 | _ = try astrl.expr(full.ast.section_expr, block, ResultInfo.type_only); | 772 | _ = try astrl.expr(section_expr, block, ResultInfo.type_only); |
| 751 | } | 773 | } |
| 752 | if (full.ast.callconv_expr != 0) { | 774 | if (full.ast.callconv_expr.unwrap()) |callconv_expr| { |
| 753 | _ = try astrl.expr(full.ast.callconv_expr, block, ResultInfo.type_only); | 775 | _ = try astrl.expr(callconv_expr, block, ResultInfo.type_only); |
| 754 | } | 776 | } |
| 755 | _ = try astrl.expr(full.ast.return_type, block, ResultInfo.type_only); | 777 | const return_type = full.ast.return_type.unwrap().?; |
| 756 | if (body_node != 0) { | 778 | _ = try astrl.expr(return_type, block, ResultInfo.type_only); |
| 757 | _ = try astrl.expr(body_node, block, ResultInfo.none); | 779 | if (body_node.unwrap()) |body| { |
| 780 | _ = try astrl.expr(body, block, ResultInfo.none); | ||
| 758 | } | 781 | } |
| 759 | return false; | 782 | return false; |
| 760 | }, | 783 | }, |
| ... | @@ -763,8 +786,7 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -763,8 +786,7 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 763 | 786 | ||
| 764 | fn identString(astrl: *AstRlAnnotate, token: Ast.TokenIndex) ![]const u8 { | 787 | fn identString(astrl: *AstRlAnnotate, token: Ast.TokenIndex) ![]const u8 { |
| 765 | const tree = astrl.tree; | 788 | const tree = astrl.tree; |
| 766 | const token_tags = tree.tokens.items(.tag); | 789 | assert(tree.tokenTag(token) == .identifier); |
| 767 | assert(token_tags[token] == .identifier); | ||
| 768 | const ident_name = tree.tokenSlice(token); | 790 | const ident_name = tree.tokenSlice(token); |
| 769 | if (!std.mem.startsWith(u8, ident_name, "@")) { | 791 | if (!std.mem.startsWith(u8, ident_name, "@")) { |
| 770 | return ident_name; | 792 | return ident_name; |
| ... | @@ -777,13 +799,9 @@ fn identString(astrl: *AstRlAnnotate, token: Ast.TokenIndex) ![]const u8 { | ... | @@ -777,13 +799,9 @@ fn identString(astrl: *AstRlAnnotate, token: Ast.TokenIndex) ![]const u8 { |
| 777 | 799 | ||
| 778 | fn blockExpr(astrl: *AstRlAnnotate, parent_block: ?*Block, ri: ResultInfo, node: Ast.Node.Index, statements: []const Ast.Node.Index) !bool { | 800 | fn blockExpr(astrl: *AstRlAnnotate, parent_block: ?*Block, ri: ResultInfo, node: Ast.Node.Index, statements: []const Ast.Node.Index) !bool { |
| 779 | const tree = astrl.tree; | 801 | const tree = astrl.tree; |
| 780 | const token_tags = tree.tokens.items(.tag); | ||
| 781 | const main_tokens = tree.nodes.items(.main_token); | ||
| 782 | 802 | ||
| 783 | const lbrace = main_tokens[node]; | 803 | const lbrace = tree.nodeMainToken(node); |
| 784 | if (token_tags[lbrace - 1] == .colon and | 804 | if (tree.isTokenPrecededByTags(lbrace, &.{ .identifier, .colon })) { |
| 785 | token_tags[lbrace - 2] == .identifier) | ||
| 786 | { | ||
| 787 | // Labeled block | 805 | // Labeled block |
| 788 | var new_block: Block = .{ | 806 | var new_block: Block = .{ |
| 789 | .parent = parent_block, | 807 | .parent = parent_block, |
| ... | @@ -812,8 +830,7 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast. | ... | @@ -812,8 +830,7 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast. |
| 812 | _ = ri; // Currently, no builtin consumes its result location. | 830 | _ = ri; // Currently, no builtin consumes its result location. |
| 813 | 831 | ||
| 814 | const tree = astrl.tree; | 832 | const tree = astrl.tree; |
| 815 | const main_tokens = tree.nodes.items(.main_token); | 833 | const builtin_token = tree.nodeMainToken(node); |
| 816 | const builtin_token = main_tokens[node]; | ||
| 817 | const builtin_name = tree.tokenSlice(builtin_token); | 834 | const builtin_name = tree.tokenSlice(builtin_token); |
| 818 | const info = BuiltinFn.list.get(builtin_name) orelse return false; | 835 | const info = BuiltinFn.list.get(builtin_name) orelse return false; |
| 819 | if (info.param_count) |expected| { | 836 | if (info.param_count) |expected| { |
lib/std/zig/ErrorBundle.zig+28-26| ... | @@ -481,13 +481,13 @@ pub const Wip = struct { | ... | @@ -481,13 +481,13 @@ pub const Wip = struct { |
| 481 | const item = zir.extraData(Zir.Inst.CompileErrors.Item, extra_index); | 481 | const item = zir.extraData(Zir.Inst.CompileErrors.Item, extra_index); |
| 482 | extra_index = item.end; | 482 | extra_index = item.end; |
| 483 | const err_span = blk: { | 483 | const err_span = blk: { |
| 484 | if (item.data.node != 0) { | 484 | if (item.data.node.unwrap()) |node| { |
| 485 | break :blk tree.nodeToSpan(item.data.node); | 485 | break :blk tree.nodeToSpan(node); |
| 486 | } | 486 | } else if (item.data.token.unwrap()) |token| { |
| 487 | const token_starts = tree.tokens.items(.start); | 487 | const start = tree.tokenStart(token) + item.data.byte_offset; |
| 488 | const start = token_starts[item.data.token] + item.data.byte_offset; | 488 | const end = start + @as(u32, @intCast(tree.tokenSlice(token).len)) - item.data.byte_offset; |
| 489 | const end = start + @as(u32, @intCast(tree.tokenSlice(item.data.token).len)) - item.data.byte_offset; | 489 | break :blk std.zig.Ast.Span{ .start = start, .end = end, .main = start }; |
| 490 | break :blk std.zig.Ast.Span{ .start = start, .end = end, .main = start }; | 490 | } else unreachable; |
| 491 | }; | 491 | }; |
| 492 | const err_loc = std.zig.findLineColumn(source, err_span.main); | 492 | const err_loc = std.zig.findLineColumn(source, err_span.main); |
| 493 | 493 | ||
| ... | @@ -516,13 +516,13 @@ pub const Wip = struct { | ... | @@ -516,13 +516,13 @@ pub const Wip = struct { |
| 516 | const note_item = zir.extraData(Zir.Inst.CompileErrors.Item, body_elem); | 516 | const note_item = zir.extraData(Zir.Inst.CompileErrors.Item, body_elem); |
| 517 | const msg = zir.nullTerminatedString(note_item.data.msg); | 517 | const msg = zir.nullTerminatedString(note_item.data.msg); |
| 518 | const span = blk: { | 518 | const span = blk: { |
| 519 | if (note_item.data.node != 0) { | 519 | if (note_item.data.node.unwrap()) |node| { |
| 520 | break :blk tree.nodeToSpan(note_item.data.node); | 520 | break :blk tree.nodeToSpan(node); |
| 521 | } | 521 | } else if (note_item.data.token.unwrap()) |token| { |
| 522 | const token_starts = tree.tokens.items(.start); | 522 | const start = tree.tokenStart(token) + note_item.data.byte_offset; |
| 523 | const start = token_starts[note_item.data.token] + note_item.data.byte_offset; | 523 | const end = start + @as(u32, @intCast(tree.tokenSlice(token).len)) - item.data.byte_offset; |
| 524 | const end = start + @as(u32, @intCast(tree.tokenSlice(note_item.data.token).len)) - item.data.byte_offset; | 524 | break :blk std.zig.Ast.Span{ .start = start, .end = end, .main = start }; |
| 525 | break :blk std.zig.Ast.Span{ .start = start, .end = end, .main = start }; | 525 | } else unreachable; |
| 526 | }; | 526 | }; |
| 527 | const loc = std.zig.findLineColumn(source, span.main); | 527 | const loc = std.zig.findLineColumn(source, span.main); |
| 528 | 528 | ||
| ... | @@ -560,13 +560,14 @@ pub const Wip = struct { | ... | @@ -560,13 +560,14 @@ pub const Wip = struct { |
| 560 | 560 | ||
| 561 | for (zoir.compile_errors) |err| { | 561 | for (zoir.compile_errors) |err| { |
| 562 | const err_span: std.zig.Ast.Span = span: { | 562 | const err_span: std.zig.Ast.Span = span: { |
| 563 | if (err.token == std.zig.Zoir.CompileError.invalid_token) { | 563 | if (err.token.unwrap()) |token| { |
| 564 | break :span tree.nodeToSpan(err.node_or_offset); | 564 | const token_start = tree.tokenStart(token); |
| 565 | const start = token_start + err.node_or_offset; | ||
| 566 | const end = token_start + @as(u32, @intCast(tree.tokenSlice(token).len)); | ||
| 567 | break :span .{ .start = start, .end = end, .main = start }; | ||
| 568 | } else { | ||
| 569 | break :span tree.nodeToSpan(@enumFromInt(err.node_or_offset)); | ||
| 565 | } | 570 | } |
| 566 | const token_start = tree.tokens.items(.start)[err.token]; | ||
| 567 | const start = token_start + err.node_or_offset; | ||
| 568 | const end = token_start + @as(u32, @intCast(tree.tokenSlice(err.token).len)); | ||
| 569 | break :span .{ .start = start, .end = end, .main = start }; | ||
| 570 | }; | 571 | }; |
| 571 | const err_loc = std.zig.findLineColumn(source, err_span.main); | 572 | const err_loc = std.zig.findLineColumn(source, err_span.main); |
| 572 | 573 | ||
| ... | @@ -588,13 +589,14 @@ pub const Wip = struct { | ... | @@ -588,13 +589,14 @@ pub const Wip = struct { |
| 588 | for (notes_start.., err.first_note.., 0..err.note_count) |eb_note_idx, zoir_note_idx, _| { | 589 | for (notes_start.., err.first_note.., 0..err.note_count) |eb_note_idx, zoir_note_idx, _| { |
| 589 | const note = zoir.error_notes[zoir_note_idx]; | 590 | const note = zoir.error_notes[zoir_note_idx]; |
| 590 | const note_span: std.zig.Ast.Span = span: { | 591 | const note_span: std.zig.Ast.Span = span: { |
| 591 | if (note.token == std.zig.Zoir.CompileError.invalid_token) { | 592 | if (note.token.unwrap()) |token| { |
| 592 | break :span tree.nodeToSpan(note.node_or_offset); | 593 | const token_start = tree.tokenStart(token); |
| 594 | const start = token_start + note.node_or_offset; | ||
| 595 | const end = token_start + @as(u32, @intCast(tree.tokenSlice(token).len)); | ||
| 596 | break :span .{ .start = start, .end = end, .main = start }; | ||
| 597 | } else { | ||
| 598 | break :span tree.nodeToSpan(@enumFromInt(note.node_or_offset)); | ||
| 593 | } | 599 | } |
| 594 | const token_start = tree.tokens.items(.start)[note.token]; | ||
| 595 | const start = token_start + note.node_or_offset; | ||
| 596 | const end = token_start + @as(u32, @intCast(tree.tokenSlice(note.token).len)); | ||
| 597 | break :span .{ .start = start, .end = end, .main = start }; | ||
| 598 | }; | 600 | }; |
| 599 | const note_loc = std.zig.findLineColumn(source, note_span.main); | 601 | const note_loc = std.zig.findLineColumn(source, note_span.main); |
| 600 | 602 |
lib/std/zig/Parse.zig+1070-1327| ... | @@ -4,52 +4,71 @@ pub const Error = error{ParseError} || Allocator.Error; | ... | @@ -4,52 +4,71 @@ pub const Error = error{ParseError} || Allocator.Error; |
| 4 | 4 | ||
| 5 | gpa: Allocator, | 5 | gpa: Allocator, |
| 6 | source: []const u8, | 6 | source: []const u8, |
| 7 | token_tags: []const Token.Tag, | 7 | tokens: Ast.TokenList.Slice, |
| 8 | token_starts: []const Ast.ByteOffset, | ||
| 9 | tok_i: TokenIndex, | 8 | tok_i: TokenIndex, |
| 10 | errors: std.ArrayListUnmanaged(AstError), | 9 | errors: std.ArrayListUnmanaged(AstError), |
| 11 | nodes: Ast.NodeList, | 10 | nodes: Ast.NodeList, |
| 12 | extra_data: std.ArrayListUnmanaged(Node.Index), | 11 | extra_data: std.ArrayListUnmanaged(u32), |
| 13 | scratch: std.ArrayListUnmanaged(Node.Index), | 12 | scratch: std.ArrayListUnmanaged(Node.Index), |
| 14 | 13 | ||
| 14 | fn tokenTag(p: *const Parse, token_index: TokenIndex) Token.Tag { | ||
| 15 | return p.tokens.items(.tag)[token_index]; | ||
| 16 | } | ||
| 17 | |||
| 18 | fn tokenStart(p: *const Parse, token_index: TokenIndex) Ast.ByteOffset { | ||
| 19 | return p.tokens.items(.start)[token_index]; | ||
| 20 | } | ||
| 21 | |||
| 22 | fn nodeTag(p: *const Parse, node: Node.Index) Node.Tag { | ||
| 23 | return p.nodes.items(.tag)[@intFromEnum(node)]; | ||
| 24 | } | ||
| 25 | |||
| 26 | fn nodeMainToken(p: *const Parse, node: Node.Index) TokenIndex { | ||
| 27 | return p.nodes.items(.main_token)[@intFromEnum(node)]; | ||
| 28 | } | ||
| 29 | |||
| 30 | fn nodeData(p: *const Parse, node: Node.Index) Node.Data { | ||
| 31 | return p.nodes.items(.data)[@intFromEnum(node)]; | ||
| 32 | } | ||
| 33 | |||
| 15 | const SmallSpan = union(enum) { | 34 | const SmallSpan = union(enum) { |
| 16 | zero_or_one: Node.Index, | 35 | zero_or_one: Node.OptionalIndex, |
| 17 | multi: Node.SubRange, | 36 | multi: Node.SubRange, |
| 18 | }; | 37 | }; |
| 19 | 38 | ||
| 20 | const Members = struct { | 39 | const Members = struct { |
| 21 | len: usize, | 40 | len: usize, |
| 22 | lhs: Node.Index, | 41 | /// Must be either `.opt_node_and_opt_node` if `len <= 2` or `.extra_range` otherwise. |
| 23 | rhs: Node.Index, | 42 | data: Node.Data, |
| 24 | trailing: bool, | 43 | trailing: bool, |
| 25 | 44 | ||
| 26 | fn toSpan(self: Members, p: *Parse) !Node.SubRange { | 45 | fn toSpan(self: Members, p: *Parse) !Node.SubRange { |
| 27 | if (self.len <= 2) { | 46 | return switch (self.len) { |
| 28 | const nodes = [2]Node.Index{ self.lhs, self.rhs }; | 47 | 0 => p.listToSpan(&.{}), |
| 29 | return p.listToSpan(nodes[0..self.len]); | 48 | 1 => p.listToSpan(&.{self.data.opt_node_and_opt_node[0].unwrap().?}), |
| 30 | } else { | 49 | 2 => p.listToSpan(&.{ self.data.opt_node_and_opt_node[0].unwrap().?, self.data.opt_node_and_opt_node[1].unwrap().? }), |
| 31 | return Node.SubRange{ .start = self.lhs, .end = self.rhs }; | 50 | else => self.data.extra_range, |
| 32 | } | 51 | }; |
| 33 | } | 52 | } |
| 34 | }; | 53 | }; |
| 35 | 54 | ||
| 36 | fn listToSpan(p: *Parse, list: []const Node.Index) !Node.SubRange { | 55 | fn listToSpan(p: *Parse, list: []const Node.Index) Allocator.Error!Node.SubRange { |
| 37 | try p.extra_data.appendSlice(p.gpa, list); | 56 | try p.extra_data.appendSlice(p.gpa, @ptrCast(list)); |
| 38 | return Node.SubRange{ | 57 | return .{ |
| 39 | .start = @as(Node.Index, @intCast(p.extra_data.items.len - list.len)), | 58 | .start = @enumFromInt(p.extra_data.items.len - list.len), |
| 40 | .end = @as(Node.Index, @intCast(p.extra_data.items.len)), | 59 | .end = @enumFromInt(p.extra_data.items.len), |
| 41 | }; | 60 | }; |
| 42 | } | 61 | } |
| 43 | 62 | ||
| 44 | fn addNode(p: *Parse, elem: Ast.Node) Allocator.Error!Node.Index { | 63 | fn addNode(p: *Parse, elem: Ast.Node) Allocator.Error!Node.Index { |
| 45 | const result = @as(Node.Index, @intCast(p.nodes.len)); | 64 | const result: Node.Index = @enumFromInt(p.nodes.len); |
| 46 | try p.nodes.append(p.gpa, elem); | 65 | try p.nodes.append(p.gpa, elem); |
| 47 | return result; | 66 | return result; |
| 48 | } | 67 | } |
| 49 | 68 | ||
| 50 | fn setNode(p: *Parse, i: usize, elem: Ast.Node) Node.Index { | 69 | fn setNode(p: *Parse, i: usize, elem: Ast.Node) Node.Index { |
| 51 | p.nodes.set(i, elem); | 70 | p.nodes.set(i, elem); |
| 52 | return @as(Node.Index, @intCast(i)); | 71 | return @enumFromInt(i); |
| 53 | } | 72 | } |
| 54 | 73 | ||
| 55 | fn reserveNode(p: *Parse, tag: Ast.Node.Tag) !usize { | 74 | fn reserveNode(p: *Parse, tag: Ast.Node.Tag) !usize { |
| ... | @@ -69,13 +88,22 @@ fn unreserveNode(p: *Parse, node_index: usize) void { | ... | @@ -69,13 +88,22 @@ fn unreserveNode(p: *Parse, node_index: usize) void { |
| 69 | } | 88 | } |
| 70 | } | 89 | } |
| 71 | 90 | ||
| 72 | fn addExtra(p: *Parse, extra: anytype) Allocator.Error!Node.Index { | 91 | fn addExtra(p: *Parse, extra: anytype) Allocator.Error!ExtraIndex { |
| 73 | const fields = std.meta.fields(@TypeOf(extra)); | 92 | const fields = std.meta.fields(@TypeOf(extra)); |
| 74 | try p.extra_data.ensureUnusedCapacity(p.gpa, fields.len); | 93 | try p.extra_data.ensureUnusedCapacity(p.gpa, fields.len); |
| 75 | const result = @as(u32, @intCast(p.extra_data.items.len)); | 94 | const result: ExtraIndex = @enumFromInt(p.extra_data.items.len); |
| 76 | inline for (fields) |field| { | 95 | inline for (fields) |field| { |
| 77 | comptime assert(field.type == Node.Index); | 96 | const data: u32 = switch (field.type) { |
| 78 | p.extra_data.appendAssumeCapacity(@field(extra, field.name)); | 97 | Node.Index, |
| 98 | Node.OptionalIndex, | ||
| 99 | OptionalTokenIndex, | ||
| 100 | ExtraIndex, | ||
| 101 | => @intFromEnum(@field(extra, field.name)), | ||
| 102 | TokenIndex, | ||
| 103 | => @field(extra, field.name), | ||
| 104 | else => @compileError("unexpected field type"), | ||
| 105 | }; | ||
| 106 | p.extra_data.appendAssumeCapacity(data); | ||
| 79 | } | 107 | } |
| 80 | return result; | 108 | return result; |
| 81 | } | 109 | } |
| ... | @@ -170,13 +198,10 @@ pub fn parseRoot(p: *Parse) !void { | ... | @@ -170,13 +198,10 @@ pub fn parseRoot(p: *Parse) !void { |
| 170 | }); | 198 | }); |
| 171 | const root_members = try p.parseContainerMembers(); | 199 | const root_members = try p.parseContainerMembers(); |
| 172 | const root_decls = try root_members.toSpan(p); | 200 | const root_decls = try root_members.toSpan(p); |
| 173 | if (p.token_tags[p.tok_i] != .eof) { | 201 | if (p.tokenTag(p.tok_i) != .eof) { |
| 174 | try p.warnExpected(.eof); | 202 | try p.warnExpected(.eof); |
| 175 | } | 203 | } |
| 176 | p.nodes.items(.data)[0] = .{ | 204 | p.nodes.items(.data)[0] = .{ .extra_range = root_decls }; |
| 177 | .lhs = root_decls.start, | ||
| 178 | .rhs = root_decls.end, | ||
| 179 | }; | ||
| 180 | } | 205 | } |
| 181 | 206 | ||
| 182 | /// Parse in ZON mode. Subset of the language. | 207 | /// Parse in ZON mode. Subset of the language. |
| ... | @@ -196,13 +221,10 @@ pub fn parseZon(p: *Parse) !void { | ... | @@ -196,13 +221,10 @@ pub fn parseZon(p: *Parse) !void { |
| 196 | }, | 221 | }, |
| 197 | else => |e| return e, | 222 | else => |e| return e, |
| 198 | }; | 223 | }; |
| 199 | if (p.token_tags[p.tok_i] != .eof) { | 224 | if (p.tokenTag(p.tok_i) != .eof) { |
| 200 | try p.warnExpected(.eof); | 225 | try p.warnExpected(.eof); |
| 201 | } | 226 | } |
| 202 | p.nodes.items(.data)[0] = .{ | 227 | p.nodes.items(.data)[0] = .{ .node = node_index }; |
| 203 | .lhs = node_index, | ||
| 204 | .rhs = undefined, | ||
| 205 | }; | ||
| 206 | } | 228 | } |
| 207 | 229 | ||
| 208 | /// ContainerMembers <- ContainerDeclaration* (ContainerField COMMA)* (ContainerField / ContainerDeclaration*) | 230 | /// ContainerMembers <- ContainerDeclaration* (ContainerField COMMA)* (ContainerField / ContainerDeclaration*) |
| ... | @@ -235,13 +257,13 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { | ... | @@ -235,13 +257,13 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { |
| 235 | while (true) { | 257 | while (true) { |
| 236 | const doc_comment = try p.eatDocComments(); | 258 | const doc_comment = try p.eatDocComments(); |
| 237 | 259 | ||
| 238 | switch (p.token_tags[p.tok_i]) { | 260 | switch (p.tokenTag(p.tok_i)) { |
| 239 | .keyword_test => { | 261 | .keyword_test => { |
| 240 | if (doc_comment) |some| { | 262 | if (doc_comment) |some| { |
| 241 | try p.warnMsg(.{ .tag = .test_doc_comment, .token = some }); | 263 | try p.warnMsg(.{ .tag = .test_doc_comment, .token = some }); |
| 242 | } | 264 | } |
| 243 | const test_decl_node = try p.expectTestDeclRecoverable(); | 265 | const maybe_test_decl_node = try p.expectTestDeclRecoverable(); |
| 244 | if (test_decl_node != 0) { | 266 | if (maybe_test_decl_node) |test_decl_node| { |
| 245 | if (field_state == .seen) { | 267 | if (field_state == .seen) { |
| 246 | field_state = .{ .end = test_decl_node }; | 268 | field_state = .{ .end = test_decl_node }; |
| 247 | } | 269 | } |
| ... | @@ -249,27 +271,24 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { | ... | @@ -249,27 +271,24 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { |
| 249 | } | 271 | } |
| 250 | trailing = false; | 272 | trailing = false; |
| 251 | }, | 273 | }, |
| 252 | .keyword_comptime => switch (p.token_tags[p.tok_i + 1]) { | 274 | .keyword_comptime => switch (p.tokenTag(p.tok_i + 1)) { |
| 253 | .l_brace => { | 275 | .l_brace => { |
| 254 | if (doc_comment) |some| { | 276 | if (doc_comment) |some| { |
| 255 | try p.warnMsg(.{ .tag = .comptime_doc_comment, .token = some }); | 277 | try p.warnMsg(.{ .tag = .comptime_doc_comment, .token = some }); |
| 256 | } | 278 | } |
| 257 | const comptime_token = p.nextToken(); | 279 | const comptime_token = p.nextToken(); |
| 258 | const block = p.parseBlock() catch |err| switch (err) { | 280 | const opt_block = p.parseBlock() catch |err| switch (err) { |
| 259 | error.OutOfMemory => return error.OutOfMemory, | 281 | error.OutOfMemory => return error.OutOfMemory, |
| 260 | error.ParseError => blk: { | 282 | error.ParseError => blk: { |
| 261 | p.findNextContainerMember(); | 283 | p.findNextContainerMember(); |
| 262 | break :blk null_node; | 284 | break :blk null; |
| 263 | }, | 285 | }, |
| 264 | }; | 286 | }; |
| 265 | if (block != 0) { | 287 | if (opt_block) |block| { |
| 266 | const comptime_node = try p.addNode(.{ | 288 | const comptime_node = try p.addNode(.{ |
| 267 | .tag = .@"comptime", | 289 | .tag = .@"comptime", |
| 268 | .main_token = comptime_token, | 290 | .main_token = comptime_token, |
| 269 | .data = .{ | 291 | .data = .{ .node = block }, |
| 270 | .lhs = block, | ||
| 271 | .rhs = undefined, | ||
| 272 | }, | ||
| 273 | }); | 292 | }); |
| 274 | if (field_state == .seen) { | 293 | if (field_state == .seen) { |
| 275 | field_state = .{ .end = comptime_node }; | 294 | field_state = .{ .end = comptime_node }; |
| ... | @@ -294,7 +313,7 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { | ... | @@ -294,7 +313,7 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { |
| 294 | .end => |node| { | 313 | .end => |node| { |
| 295 | try p.warnMsg(.{ | 314 | try p.warnMsg(.{ |
| 296 | .tag = .decl_between_fields, | 315 | .tag = .decl_between_fields, |
| 297 | .token = p.nodes.items(.main_token)[node], | 316 | .token = p.nodeMainToken(node), |
| 298 | }); | 317 | }); |
| 299 | try p.warnMsg(.{ | 318 | try p.warnMsg(.{ |
| 300 | .tag = .previous_field, | 319 | .tag = .previous_field, |
| ... | @@ -311,7 +330,7 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { | ... | @@ -311,7 +330,7 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { |
| 311 | }, | 330 | }, |
| 312 | } | 331 | } |
| 313 | try p.scratch.append(p.gpa, container_field); | 332 | try p.scratch.append(p.gpa, container_field); |
| 314 | switch (p.token_tags[p.tok_i]) { | 333 | switch (p.tokenTag(p.tok_i)) { |
| 315 | .comma => { | 334 | .comma => { |
| 316 | p.tok_i += 1; | 335 | p.tok_i += 1; |
| 317 | trailing = true; | 336 | trailing = true; |
| ... | @@ -331,24 +350,24 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { | ... | @@ -331,24 +350,24 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { |
| 331 | }, | 350 | }, |
| 332 | .keyword_pub => { | 351 | .keyword_pub => { |
| 333 | p.tok_i += 1; | 352 | p.tok_i += 1; |
| 334 | const top_level_decl = try p.expectTopLevelDeclRecoverable(); | 353 | const opt_top_level_decl = try p.expectTopLevelDeclRecoverable(); |
| 335 | if (top_level_decl != 0) { | 354 | if (opt_top_level_decl) |top_level_decl| { |
| 336 | if (field_state == .seen) { | 355 | if (field_state == .seen) { |
| 337 | field_state = .{ .end = top_level_decl }; | 356 | field_state = .{ .end = top_level_decl }; |
| 338 | } | 357 | } |
| 339 | try p.scratch.append(p.gpa, top_level_decl); | 358 | try p.scratch.append(p.gpa, top_level_decl); |
| 340 | } | 359 | } |
| 341 | trailing = p.token_tags[p.tok_i - 1] == .semicolon; | 360 | trailing = p.tokenTag(p.tok_i - 1) == .semicolon; |
| 342 | }, | 361 | }, |
| 343 | .keyword_usingnamespace => { | 362 | .keyword_usingnamespace => { |
| 344 | const node = try p.expectUsingNamespaceRecoverable(); | 363 | const opt_node = try p.expectUsingNamespaceRecoverable(); |
| 345 | if (node != 0) { | 364 | if (opt_node) |node| { |
| 346 | if (field_state == .seen) { | 365 | if (field_state == .seen) { |
| 347 | field_state = .{ .end = node }; | 366 | field_state = .{ .end = node }; |
| 348 | } | 367 | } |
| 349 | try p.scratch.append(p.gpa, node); | 368 | try p.scratch.append(p.gpa, node); |
| 350 | } | 369 | } |
| 351 | trailing = p.token_tags[p.tok_i - 1] == .semicolon; | 370 | trailing = p.tokenTag(p.tok_i - 1) == .semicolon; |
| 352 | }, | 371 | }, |
| 353 | .keyword_const, | 372 | .keyword_const, |
| 354 | .keyword_var, | 373 | .keyword_var, |
| ... | @@ -359,14 +378,14 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { | ... | @@ -359,14 +378,14 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { |
| 359 | .keyword_noinline, | 378 | .keyword_noinline, |
| 360 | .keyword_fn, | 379 | .keyword_fn, |
| 361 | => { | 380 | => { |
| 362 | const top_level_decl = try p.expectTopLevelDeclRecoverable(); | 381 | const opt_top_level_decl = try p.expectTopLevelDeclRecoverable(); |
| 363 | if (top_level_decl != 0) { | 382 | if (opt_top_level_decl) |top_level_decl| { |
| 364 | if (field_state == .seen) { | 383 | if (field_state == .seen) { |
| 365 | field_state = .{ .end = top_level_decl }; | 384 | field_state = .{ .end = top_level_decl }; |
| 366 | } | 385 | } |
| 367 | try p.scratch.append(p.gpa, top_level_decl); | 386 | try p.scratch.append(p.gpa, top_level_decl); |
| 368 | } | 387 | } |
| 369 | trailing = p.token_tags[p.tok_i - 1] == .semicolon; | 388 | trailing = p.tokenTag(p.tok_i - 1) == .semicolon; |
| 370 | }, | 389 | }, |
| 371 | .eof, .r_brace => { | 390 | .eof, .r_brace => { |
| 372 | if (doc_comment) |tok| { | 391 | if (doc_comment) |tok| { |
| ... | @@ -399,7 +418,7 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { | ... | @@ -399,7 +418,7 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { |
| 399 | .end => |node| { | 418 | .end => |node| { |
| 400 | try p.warnMsg(.{ | 419 | try p.warnMsg(.{ |
| 401 | .tag = .decl_between_fields, | 420 | .tag = .decl_between_fields, |
| 402 | .token = p.nodes.items(.main_token)[node], | 421 | .token = p.nodeMainToken(node), |
| 403 | }); | 422 | }); |
| 404 | try p.warnMsg(.{ | 423 | try p.warnMsg(.{ |
| 405 | .tag = .previous_field, | 424 | .tag = .previous_field, |
| ... | @@ -416,7 +435,7 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { | ... | @@ -416,7 +435,7 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { |
| 416 | }, | 435 | }, |
| 417 | } | 436 | } |
| 418 | try p.scratch.append(p.gpa, container_field); | 437 | try p.scratch.append(p.gpa, container_field); |
| 419 | switch (p.token_tags[p.tok_i]) { | 438 | switch (p.tokenTag(p.tok_i)) { |
| 420 | .comma => { | 439 | .comma => { |
| 421 | p.tok_i += 1; | 440 | p.tok_i += 1; |
| 422 | trailing = true; | 441 | trailing = true; |
| ... | @@ -431,7 +450,7 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { | ... | @@ -431,7 +450,7 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { |
| 431 | // There is not allowed to be a decl after a field with no comma. | 450 | // There is not allowed to be a decl after a field with no comma. |
| 432 | // Report error but recover parser. | 451 | // Report error but recover parser. |
| 433 | try p.warn(.expected_comma_after_field); | 452 | try p.warn(.expected_comma_after_field); |
| 434 | if (p.token_tags[p.tok_i] == .semicolon and p.token_tags[identifier] == .identifier) { | 453 | if (p.tokenTag(p.tok_i) == .semicolon and p.tokenTag(identifier) == .identifier) { |
| 435 | try p.warnMsg(.{ | 454 | try p.warnMsg(.{ |
| 436 | .tag = .var_const_decl, | 455 | .tag = .var_const_decl, |
| 437 | .is_note = true, | 456 | .is_note = true, |
| ... | @@ -445,34 +464,21 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { | ... | @@ -445,34 +464,21 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members { |
| 445 | } | 464 | } |
| 446 | 465 | ||
| 447 | const items = p.scratch.items[scratch_top..]; | 466 | const items = p.scratch.items[scratch_top..]; |
| 448 | switch (items.len) { | 467 | if (items.len <= 2) { |
| 449 | 0 => return Members{ | 468 | return Members{ |
| 450 | .len = 0, | 469 | .len = items.len, |
| 451 | .lhs = 0, | 470 | .data = .{ .opt_node_and_opt_node = .{ |
| 452 | .rhs = 0, | 471 | if (items.len >= 1) items[0].toOptional() else .none, |
| 472 | if (items.len >= 2) items[1].toOptional() else .none, | ||
| 473 | } }, | ||
| 453 | .trailing = trailing, | 474 | .trailing = trailing, |
| 454 | }, | 475 | }; |
| 455 | 1 => return Members{ | 476 | } else { |
| 456 | .len = 1, | 477 | return Members{ |
| 457 | .lhs = items[0], | 478 | .len = items.len, |
| 458 | .rhs = 0, | 479 | .data = .{ .extra_range = try p.listToSpan(items) }, |
| 459 | .trailing = trailing, | ||
| 460 | }, | ||
| 461 | 2 => return Members{ | ||
| 462 | .len = 2, | ||
| 463 | .lhs = items[0], | ||
| 464 | .rhs = items[1], | ||
| 465 | .trailing = trailing, | 480 | .trailing = trailing, |
| 466 | }, | 481 | }; |
| 467 | else => { | ||
| 468 | const span = try p.listToSpan(items); | ||
| 469 | return Members{ | ||
| 470 | .len = items.len, | ||
| 471 | .lhs = span.start, | ||
| 472 | .rhs = span.end, | ||
| 473 | .trailing = trailing, | ||
| 474 | }; | ||
| 475 | }, | ||
| 476 | } | 482 | } |
| 477 | } | 483 | } |
| 478 | 484 | ||
| ... | @@ -481,7 +487,7 @@ fn findNextContainerMember(p: *Parse) void { | ... | @@ -481,7 +487,7 @@ fn findNextContainerMember(p: *Parse) void { |
| 481 | var level: u32 = 0; | 487 | var level: u32 = 0; |
| 482 | while (true) { | 488 | while (true) { |
| 483 | const tok = p.nextToken(); | 489 | const tok = p.nextToken(); |
| 484 | switch (p.token_tags[tok]) { | 490 | switch (p.tokenTag(tok)) { |
| 485 | // Any of these can start a new top level declaration. | 491 | // Any of these can start a new top level declaration. |
| 486 | .keyword_test, | 492 | .keyword_test, |
| 487 | .keyword_comptime, | 493 | .keyword_comptime, |
| ... | @@ -502,7 +508,7 @@ fn findNextContainerMember(p: *Parse) void { | ... | @@ -502,7 +508,7 @@ fn findNextContainerMember(p: *Parse) void { |
| 502 | } | 508 | } |
| 503 | }, | 509 | }, |
| 504 | .identifier => { | 510 | .identifier => { |
| 505 | if (p.token_tags[tok + 1] == .comma and level == 0) { | 511 | if (p.tokenTag(tok + 1) == .comma and level == 0) { |
| 506 | p.tok_i -= 1; | 512 | p.tok_i -= 1; |
| 507 | return; | 513 | return; |
| 508 | } | 514 | } |
| ... | @@ -539,7 +545,7 @@ fn findNextStmt(p: *Parse) void { | ... | @@ -539,7 +545,7 @@ fn findNextStmt(p: *Parse) void { |
| 539 | var level: u32 = 0; | 545 | var level: u32 = 0; |
| 540 | while (true) { | 546 | while (true) { |
| 541 | const tok = p.nextToken(); | 547 | const tok = p.nextToken(); |
| 542 | switch (p.token_tags[tok]) { | 548 | switch (p.tokenTag(tok)) { |
| 543 | .l_brace => level += 1, | 549 | .l_brace => level += 1, |
| 544 | .r_brace => { | 550 | .r_brace => { |
| 545 | if (level == 0) { | 551 | if (level == 0) { |
| ... | @@ -563,44 +569,45 @@ fn findNextStmt(p: *Parse) void { | ... | @@ -563,44 +569,45 @@ fn findNextStmt(p: *Parse) void { |
| 563 | } | 569 | } |
| 564 | 570 | ||
| 565 | /// TestDecl <- KEYWORD_test (STRINGLITERALSINGLE / IDENTIFIER)? Block | 571 | /// TestDecl <- KEYWORD_test (STRINGLITERALSINGLE / IDENTIFIER)? Block |
| 566 | fn expectTestDecl(p: *Parse) !Node.Index { | 572 | fn expectTestDecl(p: *Parse) Error!Node.Index { |
| 567 | const test_token = p.assertToken(.keyword_test); | 573 | const test_token = p.assertToken(.keyword_test); |
| 568 | const name_token = switch (p.token_tags[p.tok_i]) { | 574 | const name_token: OptionalTokenIndex = switch (p.tokenTag(p.tok_i)) { |
| 569 | .string_literal, .identifier => p.nextToken(), | 575 | .string_literal, .identifier => .fromToken(p.nextToken()), |
| 570 | else => null, | 576 | else => .none, |
| 571 | }; | 577 | }; |
| 572 | const block_node = try p.parseBlock(); | 578 | const block_node = try p.parseBlock() orelse return p.fail(.expected_block); |
| 573 | if (block_node == 0) return p.fail(.expected_block); | ||
| 574 | return p.addNode(.{ | 579 | return p.addNode(.{ |
| 575 | .tag = .test_decl, | 580 | .tag = .test_decl, |
| 576 | .main_token = test_token, | 581 | .main_token = test_token, |
| 577 | .data = .{ | 582 | .data = .{ .opt_token_and_node = .{ |
| 578 | .lhs = name_token orelse 0, | 583 | name_token, |
| 579 | .rhs = block_node, | 584 | block_node, |
| 580 | }, | 585 | } }, |
| 581 | }); | 586 | }); |
| 582 | } | 587 | } |
| 583 | 588 | ||
| 584 | fn expectTestDeclRecoverable(p: *Parse) error{OutOfMemory}!Node.Index { | 589 | fn expectTestDeclRecoverable(p: *Parse) error{OutOfMemory}!?Node.Index { |
| 585 | return p.expectTestDecl() catch |err| switch (err) { | 590 | if (p.expectTestDecl()) |node| { |
| 591 | return node; | ||
| 592 | } else |err| switch (err) { | ||
| 586 | error.OutOfMemory => return error.OutOfMemory, | 593 | error.OutOfMemory => return error.OutOfMemory, |
| 587 | error.ParseError => { | 594 | error.ParseError => { |
| 588 | p.findNextContainerMember(); | 595 | p.findNextContainerMember(); |
| 589 | return null_node; | 596 | return null; |
| 590 | }, | 597 | }, |
| 591 | }; | 598 | } |
| 592 | } | 599 | } |
| 593 | 600 | ||
| 594 | /// Decl | 601 | /// Decl |
| 595 | /// <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / KEYWORD_inline / KEYWORD_noinline)? FnProto (SEMICOLON / Block) | 602 | /// <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / KEYWORD_inline / KEYWORD_noinline)? FnProto (SEMICOLON / Block) |
| 596 | /// / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl | 603 | /// / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl |
| 597 | /// / KEYWORD_usingnamespace Expr SEMICOLON | 604 | /// / KEYWORD_usingnamespace Expr SEMICOLON |
| 598 | fn expectTopLevelDecl(p: *Parse) !Node.Index { | 605 | fn expectTopLevelDecl(p: *Parse) !?Node.Index { |
| 599 | const extern_export_inline_token = p.nextToken(); | 606 | const extern_export_inline_token = p.nextToken(); |
| 600 | var is_extern: bool = false; | 607 | var is_extern: bool = false; |
| 601 | var expect_fn: bool = false; | 608 | var expect_fn: bool = false; |
| 602 | var expect_var_or_fn: bool = false; | 609 | var expect_var_or_fn: bool = false; |
| 603 | switch (p.token_tags[extern_export_inline_token]) { | 610 | switch (p.tokenTag(extern_export_inline_token)) { |
| 604 | .keyword_extern => { | 611 | .keyword_extern => { |
| 605 | _ = p.eatToken(.string_literal); | 612 | _ = p.eatToken(.string_literal); |
| 606 | is_extern = true; | 613 | is_extern = true; |
| ... | @@ -610,9 +617,9 @@ fn expectTopLevelDecl(p: *Parse) !Node.Index { | ... | @@ -610,9 +617,9 @@ fn expectTopLevelDecl(p: *Parse) !Node.Index { |
| 610 | .keyword_inline, .keyword_noinline => expect_fn = true, | 617 | .keyword_inline, .keyword_noinline => expect_fn = true, |
| 611 | else => p.tok_i -= 1, | 618 | else => p.tok_i -= 1, |
| 612 | } | 619 | } |
| 613 | const fn_proto = try p.parseFnProto(); | 620 | const opt_fn_proto = try p.parseFnProto(); |
| 614 | if (fn_proto != 0) { | 621 | if (opt_fn_proto) |fn_proto| { |
| 615 | switch (p.token_tags[p.tok_i]) { | 622 | switch (p.tokenTag(p.tok_i)) { |
| 616 | .semicolon => { | 623 | .semicolon => { |
| 617 | p.tok_i += 1; | 624 | p.tok_i += 1; |
| 618 | return fn_proto; | 625 | return fn_proto; |
| ... | @@ -620,20 +627,19 @@ fn expectTopLevelDecl(p: *Parse) !Node.Index { | ... | @@ -620,20 +627,19 @@ fn expectTopLevelDecl(p: *Parse) !Node.Index { |
| 620 | .l_brace => { | 627 | .l_brace => { |
| 621 | if (is_extern) { | 628 | if (is_extern) { |
| 622 | try p.warnMsg(.{ .tag = .extern_fn_body, .token = extern_export_inline_token }); | 629 | try p.warnMsg(.{ .tag = .extern_fn_body, .token = extern_export_inline_token }); |
| 623 | return null_node; | 630 | return null; |
| 624 | } | 631 | } |
| 625 | const fn_decl_index = try p.reserveNode(.fn_decl); | 632 | const fn_decl_index = try p.reserveNode(.fn_decl); |
| 626 | errdefer p.unreserveNode(fn_decl_index); | 633 | errdefer p.unreserveNode(fn_decl_index); |
| 627 | 634 | ||
| 628 | const body_block = try p.parseBlock(); | 635 | const body_block = try p.parseBlock(); |
| 629 | assert(body_block != 0); | ||
| 630 | return p.setNode(fn_decl_index, .{ | 636 | return p.setNode(fn_decl_index, .{ |
| 631 | .tag = .fn_decl, | 637 | .tag = .fn_decl, |
| 632 | .main_token = p.nodes.items(.main_token)[fn_proto], | 638 | .main_token = p.nodeMainToken(fn_proto), |
| 633 | .data = .{ | 639 | .data = .{ .node_and_node = .{ |
| 634 | .lhs = fn_proto, | 640 | fn_proto, |
| 635 | .rhs = body_block, | 641 | body_block.?, |
| 636 | }, | 642 | } }, |
| 637 | }); | 643 | }); |
| 638 | }, | 644 | }, |
| 639 | else => { | 645 | else => { |
| ... | @@ -641,7 +647,7 @@ fn expectTopLevelDecl(p: *Parse) !Node.Index { | ... | @@ -641,7 +647,7 @@ fn expectTopLevelDecl(p: *Parse) !Node.Index { |
| 641 | // a missing '}' we can assume this function was | 647 | // a missing '}' we can assume this function was |
| 642 | // supposed to end here. | 648 | // supposed to end here. |
| 643 | try p.warn(.expected_semi_or_lbrace); | 649 | try p.warn(.expected_semi_or_lbrace); |
| 644 | return null_node; | 650 | return null; |
| 645 | }, | 651 | }, |
| 646 | } | 652 | } |
| 647 | } | 653 | } |
| ... | @@ -651,28 +657,25 @@ fn expectTopLevelDecl(p: *Parse) !Node.Index { | ... | @@ -651,28 +657,25 @@ fn expectTopLevelDecl(p: *Parse) !Node.Index { |
| 651 | } | 657 | } |
| 652 | 658 | ||
| 653 | const thread_local_token = p.eatToken(.keyword_threadlocal); | 659 | const thread_local_token = p.eatToken(.keyword_threadlocal); |
| 654 | const var_decl = try p.parseGlobalVarDecl(); | 660 | if (try p.parseGlobalVarDecl()) |var_decl| return var_decl; |
| 655 | if (var_decl != 0) { | ||
| 656 | return var_decl; | ||
| 657 | } | ||
| 658 | if (thread_local_token != null) { | 661 | if (thread_local_token != null) { |
| 659 | return p.fail(.expected_var_decl); | 662 | return p.fail(.expected_var_decl); |
| 660 | } | 663 | } |
| 661 | if (expect_var_or_fn) { | 664 | if (expect_var_or_fn) { |
| 662 | return p.fail(.expected_var_decl_or_fn); | 665 | return p.fail(.expected_var_decl_or_fn); |
| 663 | } | 666 | } |
| 664 | if (p.token_tags[p.tok_i] != .keyword_usingnamespace) { | 667 | if (p.tokenTag(p.tok_i) != .keyword_usingnamespace) { |
| 665 | return p.fail(.expected_pub_item); | 668 | return p.fail(.expected_pub_item); |
| 666 | } | 669 | } |
| 667 | return p.expectUsingNamespace(); | 670 | return try p.expectUsingNamespace(); |
| 668 | } | 671 | } |
| 669 | 672 | ||
| 670 | fn expectTopLevelDeclRecoverable(p: *Parse) error{OutOfMemory}!Node.Index { | 673 | fn expectTopLevelDeclRecoverable(p: *Parse) error{OutOfMemory}!?Node.Index { |
| 671 | return p.expectTopLevelDecl() catch |err| switch (err) { | 674 | return p.expectTopLevelDecl() catch |err| switch (err) { |
| 672 | error.OutOfMemory => return error.OutOfMemory, | 675 | error.OutOfMemory => return error.OutOfMemory, |
| 673 | error.ParseError => { | 676 | error.ParseError => { |
| 674 | p.findNextContainerMember(); | 677 | p.findNextContainerMember(); |
| 675 | return null_node; | 678 | return null; |
| 676 | }, | 679 | }, |
| 677 | }; | 680 | }; |
| 678 | } | 681 | } |
| ... | @@ -684,26 +687,23 @@ fn expectUsingNamespace(p: *Parse) !Node.Index { | ... | @@ -684,26 +687,23 @@ fn expectUsingNamespace(p: *Parse) !Node.Index { |
| 684 | return p.addNode(.{ | 687 | return p.addNode(.{ |
| 685 | .tag = .@"usingnamespace", | 688 | .tag = .@"usingnamespace", |
| 686 | .main_token = usingnamespace_token, | 689 | .main_token = usingnamespace_token, |
| 687 | .data = .{ | 690 | .data = .{ .node = expr }, |
| 688 | .lhs = expr, | ||
| 689 | .rhs = undefined, | ||
| 690 | }, | ||
| 691 | }); | 691 | }); |
| 692 | } | 692 | } |
| 693 | 693 | ||
| 694 | fn expectUsingNamespaceRecoverable(p: *Parse) error{OutOfMemory}!Node.Index { | 694 | fn expectUsingNamespaceRecoverable(p: *Parse) error{OutOfMemory}!?Node.Index { |
| 695 | return p.expectUsingNamespace() catch |err| switch (err) { | 695 | return p.expectUsingNamespace() catch |err| switch (err) { |
| 696 | error.OutOfMemory => return error.OutOfMemory, | 696 | error.OutOfMemory => return error.OutOfMemory, |
| 697 | error.ParseError => { | 697 | error.ParseError => { |
| 698 | p.findNextContainerMember(); | 698 | p.findNextContainerMember(); |
| 699 | return null_node; | 699 | return null; |
| 700 | }, | 700 | }, |
| 701 | }; | 701 | }; |
| 702 | } | 702 | } |
| 703 | 703 | ||
| 704 | /// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? AddrSpace? LinkSection? CallConv? EXCLAMATIONMARK? TypeExpr | 704 | /// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? AddrSpace? LinkSection? CallConv? EXCLAMATIONMARK? TypeExpr |
| 705 | fn parseFnProto(p: *Parse) !Node.Index { | 705 | fn parseFnProto(p: *Parse) !?Node.Index { |
| 706 | const fn_token = p.eatToken(.keyword_fn) orelse return null_node; | 706 | const fn_token = p.eatToken(.keyword_fn) orelse return null; |
| 707 | 707 | ||
| 708 | // We want the fn proto node to be before its children in the array. | 708 | // We want the fn proto node to be before its children in the array. |
| 709 | const fn_proto_index = try p.reserveNode(.fn_proto); | 709 | const fn_proto_index = try p.reserveNode(.fn_proto); |
| ... | @@ -718,33 +718,33 @@ fn parseFnProto(p: *Parse) !Node.Index { | ... | @@ -718,33 +718,33 @@ fn parseFnProto(p: *Parse) !Node.Index { |
| 718 | _ = p.eatToken(.bang); | 718 | _ = p.eatToken(.bang); |
| 719 | 719 | ||
| 720 | const return_type_expr = try p.parseTypeExpr(); | 720 | const return_type_expr = try p.parseTypeExpr(); |
| 721 | if (return_type_expr == 0) { | 721 | if (return_type_expr == null) { |
| 722 | // most likely the user forgot to specify the return type. | 722 | // most likely the user forgot to specify the return type. |
| 723 | // Mark return type as invalid and try to continue. | 723 | // Mark return type as invalid and try to continue. |
| 724 | try p.warn(.expected_return_type); | 724 | try p.warn(.expected_return_type); |
| 725 | } | 725 | } |
| 726 | 726 | ||
| 727 | if (align_expr == 0 and section_expr == 0 and callconv_expr == 0 and addrspace_expr == 0) { | 727 | if (align_expr == null and section_expr == null and callconv_expr == null and addrspace_expr == null) { |
| 728 | switch (params) { | 728 | switch (params) { |
| 729 | .zero_or_one => |param| return p.setNode(fn_proto_index, .{ | 729 | .zero_or_one => |param| return p.setNode(fn_proto_index, .{ |
| 730 | .tag = .fn_proto_simple, | 730 | .tag = .fn_proto_simple, |
| 731 | .main_token = fn_token, | 731 | .main_token = fn_token, |
| 732 | .data = .{ | 732 | .data = .{ .opt_node_and_opt_node = .{ |
| 733 | .lhs = param, | 733 | param, |
| 734 | .rhs = return_type_expr, | 734 | .fromOptional(return_type_expr), |
| 735 | }, | 735 | } }, |
| 736 | }), | 736 | }), |
| 737 | .multi => |span| { | 737 | .multi => |span| { |
| 738 | return p.setNode(fn_proto_index, .{ | 738 | return p.setNode(fn_proto_index, .{ |
| 739 | .tag = .fn_proto_multi, | 739 | .tag = .fn_proto_multi, |
| 740 | .main_token = fn_token, | 740 | .main_token = fn_token, |
| 741 | .data = .{ | 741 | .data = .{ .extra_and_opt_node = .{ |
| 742 | .lhs = try p.addExtra(Node.SubRange{ | 742 | try p.addExtra(Node.SubRange{ |
| 743 | .start = span.start, | 743 | .start = span.start, |
| 744 | .end = span.end, | 744 | .end = span.end, |
| 745 | }), | 745 | }), |
| 746 | .rhs = return_type_expr, | 746 | .fromOptional(return_type_expr), |
| 747 | }, | 747 | } }, |
| 748 | }); | 748 | }); |
| 749 | }, | 749 | }, |
| 750 | } | 750 | } |
| ... | @@ -753,109 +753,124 @@ fn parseFnProto(p: *Parse) !Node.Index { | ... | @@ -753,109 +753,124 @@ fn parseFnProto(p: *Parse) !Node.Index { |
| 753 | .zero_or_one => |param| return p.setNode(fn_proto_index, .{ | 753 | .zero_or_one => |param| return p.setNode(fn_proto_index, .{ |
| 754 | .tag = .fn_proto_one, | 754 | .tag = .fn_proto_one, |
| 755 | .main_token = fn_token, | 755 | .main_token = fn_token, |
| 756 | .data = .{ | 756 | .data = .{ .extra_and_opt_node = .{ |
| 757 | .lhs = try p.addExtra(Node.FnProtoOne{ | 757 | try p.addExtra(Node.FnProtoOne{ |
| 758 | .param = param, | 758 | .param = param, |
| 759 | .align_expr = align_expr, | 759 | .align_expr = .fromOptional(align_expr), |
| 760 | .addrspace_expr = addrspace_expr, | 760 | .addrspace_expr = .fromOptional(addrspace_expr), |
| 761 | .section_expr = section_expr, | 761 | .section_expr = .fromOptional(section_expr), |
| 762 | .callconv_expr = callconv_expr, | 762 | .callconv_expr = .fromOptional(callconv_expr), |
| 763 | }), | 763 | }), |
| 764 | .rhs = return_type_expr, | 764 | .fromOptional(return_type_expr), |
| 765 | }, | 765 | } }, |
| 766 | }), | 766 | }), |
| 767 | .multi => |span| { | 767 | .multi => |span| { |
| 768 | return p.setNode(fn_proto_index, .{ | 768 | return p.setNode(fn_proto_index, .{ |
| 769 | .tag = .fn_proto, | 769 | .tag = .fn_proto, |
| 770 | .main_token = fn_token, | 770 | .main_token = fn_token, |
| 771 | .data = .{ | 771 | .data = .{ .extra_and_opt_node = .{ |
| 772 | .lhs = try p.addExtra(Node.FnProto{ | 772 | try p.addExtra(Node.FnProto{ |
| 773 | .params_start = span.start, | 773 | .params_start = span.start, |
| 774 | .params_end = span.end, | 774 | .params_end = span.end, |
| 775 | .align_expr = align_expr, | 775 | .align_expr = .fromOptional(align_expr), |
| 776 | .addrspace_expr = addrspace_expr, | 776 | .addrspace_expr = .fromOptional(addrspace_expr), |
| 777 | .section_expr = section_expr, | 777 | .section_expr = .fromOptional(section_expr), |
| 778 | .callconv_expr = callconv_expr, | 778 | .callconv_expr = .fromOptional(callconv_expr), |
| 779 | }), | 779 | }), |
| 780 | .rhs = return_type_expr, | 780 | .fromOptional(return_type_expr), |
| 781 | }, | 781 | } }, |
| 782 | }); | 782 | }); |
| 783 | }, | 783 | }, |
| 784 | } | 784 | } |
| 785 | } | 785 | } |
| 786 | 786 | ||
| 787 | fn setVarDeclInitExpr(p: *Parse, var_decl: Node.Index, init_expr: Node.OptionalIndex) void { | ||
| 788 | const init_expr_result = switch (p.nodeTag(var_decl)) { | ||
| 789 | .simple_var_decl => &p.nodes.items(.data)[@intFromEnum(var_decl)].opt_node_and_opt_node[1], | ||
| 790 | .aligned_var_decl => &p.nodes.items(.data)[@intFromEnum(var_decl)].node_and_opt_node[1], | ||
| 791 | .local_var_decl, .global_var_decl => &p.nodes.items(.data)[@intFromEnum(var_decl)].extra_and_opt_node[1], | ||
| 792 | else => unreachable, | ||
| 793 | }; | ||
| 794 | init_expr_result.* = init_expr; | ||
| 795 | } | ||
| 796 | |||
| 787 | /// VarDeclProto <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? AddrSpace? LinkSection? | 797 | /// VarDeclProto <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? AddrSpace? LinkSection? |
| 788 | /// Returns a `*_var_decl` node with its rhs (init expression) initialized to 0. | 798 | /// Returns a `*_var_decl` node with its rhs (init expression) initialized to .none. |
| 789 | fn parseVarDeclProto(p: *Parse) !Node.Index { | 799 | fn parseVarDeclProto(p: *Parse) !?Node.Index { |
| 790 | const mut_token = p.eatToken(.keyword_const) orelse | 800 | const mut_token = p.eatToken(.keyword_const) orelse |
| 791 | p.eatToken(.keyword_var) orelse | 801 | p.eatToken(.keyword_var) orelse |
| 792 | return null_node; | 802 | return null; |
| 793 | 803 | ||
| 794 | _ = try p.expectToken(.identifier); | 804 | _ = try p.expectToken(.identifier); |
| 795 | const type_node: Node.Index = if (p.eatToken(.colon) == null) 0 else try p.expectTypeExpr(); | 805 | const opt_type_node = if (p.eatToken(.colon) == null) null else try p.expectTypeExpr(); |
| 796 | const align_node = try p.parseByteAlign(); | 806 | const opt_align_node = try p.parseByteAlign(); |
| 797 | const addrspace_node = try p.parseAddrSpace(); | 807 | const opt_addrspace_node = try p.parseAddrSpace(); |
| 798 | const section_node = try p.parseLinkSection(); | 808 | const opt_section_node = try p.parseLinkSection(); |
| 799 | 809 | ||
| 800 | if (section_node == 0 and addrspace_node == 0) { | 810 | if (opt_section_node == null and opt_addrspace_node == null) { |
| 801 | if (align_node == 0) { | 811 | const align_node = opt_align_node orelse { |
| 802 | return p.addNode(.{ | 812 | return try p.addNode(.{ |
| 803 | .tag = .simple_var_decl, | 813 | .tag = .simple_var_decl, |
| 804 | .main_token = mut_token, | 814 | .main_token = mut_token, |
| 805 | .data = .{ | 815 | .data = .{ |
| 806 | .lhs = type_node, | 816 | .opt_node_and_opt_node = .{ |
| 807 | .rhs = 0, | 817 | .fromOptional(opt_type_node), |
| 818 | .none, // set later with `setVarDeclInitExpr | ||
| 819 | }, | ||
| 808 | }, | 820 | }, |
| 809 | }); | 821 | }); |
| 810 | } | 822 | }; |
| 811 | 823 | ||
| 812 | if (type_node == 0) { | 824 | const type_node = opt_type_node orelse { |
| 813 | return p.addNode(.{ | 825 | return try p.addNode(.{ |
| 814 | .tag = .aligned_var_decl, | 826 | .tag = .aligned_var_decl, |
| 815 | .main_token = mut_token, | 827 | .main_token = mut_token, |
| 816 | .data = .{ | 828 | .data = .{ |
| 817 | .lhs = align_node, | 829 | .node_and_opt_node = .{ |
| 818 | .rhs = 0, | 830 | align_node, |
| 831 | .none, // set later with `setVarDeclInitExpr | ||
| 832 | }, | ||
| 819 | }, | 833 | }, |
| 820 | }); | 834 | }); |
| 821 | } | 835 | }; |
| 822 | 836 | ||
| 823 | return p.addNode(.{ | 837 | return try p.addNode(.{ |
| 824 | .tag = .local_var_decl, | 838 | .tag = .local_var_decl, |
| 825 | .main_token = mut_token, | 839 | .main_token = mut_token, |
| 826 | .data = .{ | 840 | .data = .{ |
| 827 | .lhs = try p.addExtra(Node.LocalVarDecl{ | 841 | .extra_and_opt_node = .{ |
| 828 | .type_node = type_node, | 842 | try p.addExtra(Node.LocalVarDecl{ |
| 829 | .align_node = align_node, | 843 | .type_node = type_node, |
| 830 | }), | 844 | .align_node = align_node, |
| 831 | .rhs = 0, | 845 | }), |
| 846 | .none, // set later with `setVarDeclInitExpr | ||
| 847 | }, | ||
| 832 | }, | 848 | }, |
| 833 | }); | 849 | }); |
| 834 | } else { | 850 | } else { |
| 835 | return p.addNode(.{ | 851 | return try p.addNode(.{ |
| 836 | .tag = .global_var_decl, | 852 | .tag = .global_var_decl, |
| 837 | .main_token = mut_token, | 853 | .main_token = mut_token, |
| 838 | .data = .{ | 854 | .data = .{ |
| 839 | .lhs = try p.addExtra(Node.GlobalVarDecl{ | 855 | .extra_and_opt_node = .{ |
| 840 | .type_node = type_node, | 856 | try p.addExtra(Node.GlobalVarDecl{ |
| 841 | .align_node = align_node, | 857 | .type_node = .fromOptional(opt_type_node), |
| 842 | .addrspace_node = addrspace_node, | 858 | .align_node = .fromOptional(opt_align_node), |
| 843 | .section_node = section_node, | 859 | .addrspace_node = .fromOptional(opt_addrspace_node), |
| 844 | }), | 860 | .section_node = .fromOptional(opt_section_node), |
| 845 | .rhs = 0, | 861 | }), |
| 862 | .none, // set later with `setVarDeclInitExpr | ||
| 863 | }, | ||
| 846 | }, | 864 | }, |
| 847 | }); | 865 | }); |
| 848 | } | 866 | } |
| 849 | } | 867 | } |
| 850 | 868 | ||
| 851 | /// GlobalVarDecl <- VarDeclProto (EQUAL Expr?) SEMICOLON | 869 | /// GlobalVarDecl <- VarDeclProto (EQUAL Expr?) SEMICOLON |
| 852 | fn parseGlobalVarDecl(p: *Parse) !Node.Index { | 870 | fn parseGlobalVarDecl(p: *Parse) !?Node.Index { |
| 853 | const var_decl = try p.parseVarDeclProto(); | 871 | const var_decl = try p.parseVarDeclProto() orelse return null; |
| 854 | if (var_decl == 0) { | ||
| 855 | return null_node; | ||
| 856 | } | ||
| 857 | 872 | ||
| 858 | const init_node: Node.Index = switch (p.token_tags[p.tok_i]) { | 873 | const init_node: ?Node.Index = switch (p.tokenTag(p.tok_i)) { |
| 859 | .equal_equal => blk: { | 874 | .equal_equal => blk: { |
| 860 | try p.warn(.wrong_equal_var_decl); | 875 | try p.warn(.wrong_equal_var_decl); |
| 861 | p.tok_i += 1; | 876 | p.tok_i += 1; |
| ... | @@ -865,10 +880,10 @@ fn parseGlobalVarDecl(p: *Parse) !Node.Index { | ... | @@ -865,10 +880,10 @@ fn parseGlobalVarDecl(p: *Parse) !Node.Index { |
| 865 | p.tok_i += 1; | 880 | p.tok_i += 1; |
| 866 | break :blk try p.expectExpr(); | 881 | break :blk try p.expectExpr(); |
| 867 | }, | 882 | }, |
| 868 | else => 0, | 883 | else => null, |
| 869 | }; | 884 | }; |
| 870 | 885 | ||
| 871 | p.nodes.items(.data)[var_decl].rhs = init_node; | 886 | p.setVarDeclInitExpr(var_decl, .fromOptional(init_node)); |
| 872 | 887 | ||
| 873 | try p.expectSemicolon(.expected_semi_after_decl, false); | 888 | try p.expectSemicolon(.expected_semi_after_decl, false); |
| 874 | return var_decl; | 889 | return var_decl; |
| ... | @@ -878,40 +893,39 @@ fn parseGlobalVarDecl(p: *Parse) !Node.Index { | ... | @@ -878,40 +893,39 @@ fn parseGlobalVarDecl(p: *Parse) !Node.Index { |
| 878 | fn expectContainerField(p: *Parse) !Node.Index { | 893 | fn expectContainerField(p: *Parse) !Node.Index { |
| 879 | _ = p.eatToken(.keyword_comptime); | 894 | _ = p.eatToken(.keyword_comptime); |
| 880 | const main_token = p.tok_i; | 895 | const main_token = p.tok_i; |
| 881 | if (p.token_tags[p.tok_i] == .identifier and p.token_tags[p.tok_i + 1] == .colon) p.tok_i += 2; | 896 | _ = p.eatTokens(&.{ .identifier, .colon }); |
| 882 | const type_expr = try p.expectTypeExpr(); | 897 | const type_expr = try p.expectTypeExpr(); |
| 883 | const align_expr = try p.parseByteAlign(); | 898 | const align_expr = try p.parseByteAlign(); |
| 884 | const value_expr: Node.Index = if (p.eatToken(.equal) == null) 0 else try p.expectExpr(); | 899 | const value_expr = if (p.eatToken(.equal) == null) null else try p.expectExpr(); |
| 885 | 900 | ||
| 886 | if (align_expr == 0) { | 901 | if (align_expr == null) { |
| 887 | return p.addNode(.{ | 902 | return p.addNode(.{ |
| 888 | .tag = .container_field_init, | 903 | .tag = .container_field_init, |
| 889 | .main_token = main_token, | 904 | .main_token = main_token, |
| 890 | .data = .{ | 905 | .data = .{ .node_and_opt_node = .{ |
| 891 | .lhs = type_expr, | 906 | type_expr, |
| 892 | .rhs = value_expr, | 907 | .fromOptional(value_expr), |
| 893 | }, | 908 | } }, |
| 894 | }); | 909 | }); |
| 895 | } else if (value_expr == 0) { | 910 | } else if (value_expr == null) { |
| 896 | return p.addNode(.{ | 911 | return p.addNode(.{ |
| 897 | .tag = .container_field_align, | 912 | .tag = .container_field_align, |
| 898 | .main_token = main_token, | 913 | .main_token = main_token, |
| 899 | .data = .{ | 914 | .data = .{ .node_and_node = .{ |
| 900 | .lhs = type_expr, | 915 | type_expr, |
| 901 | .rhs = align_expr, | 916 | align_expr.?, |
| 902 | }, | 917 | } }, |
| 903 | }); | 918 | }); |
| 904 | } else { | 919 | } else { |
| 905 | return p.addNode(.{ | 920 | return p.addNode(.{ |
| 906 | .tag = .container_field, | 921 | .tag = .container_field, |
| 907 | .main_token = main_token, | 922 | .main_token = main_token, |
| 908 | .data = .{ | 923 | .data = .{ .node_and_extra = .{ |
| 909 | .lhs = type_expr, | 924 | type_expr, try p.addExtra(Node.ContainerField{ |
| 910 | .rhs = try p.addExtra(Node.ContainerField{ | 925 | .align_expr = align_expr.?, |
| 911 | .align_expr = align_expr, | 926 | .value_expr = value_expr.?, |
| 912 | .value_expr = value_expr, | ||
| 913 | }), | 927 | }), |
| 914 | }, | 928 | } }, |
| 915 | }); | 929 | }); |
| 916 | } | 930 | } |
| 917 | } | 931 | } |
| ... | @@ -927,15 +941,12 @@ fn expectContainerField(p: *Parse) !Node.Index { | ... | @@ -927,15 +941,12 @@ fn expectContainerField(p: *Parse) !Node.Index { |
| 927 | /// / VarDeclExprStatement | 941 | /// / VarDeclExprStatement |
| 928 | fn expectStatement(p: *Parse, allow_defer_var: bool) Error!Node.Index { | 942 | fn expectStatement(p: *Parse, allow_defer_var: bool) Error!Node.Index { |
| 929 | if (p.eatToken(.keyword_comptime)) |comptime_token| { | 943 | if (p.eatToken(.keyword_comptime)) |comptime_token| { |
| 930 | const block_expr = try p.parseBlockExpr(); | 944 | const opt_block_expr = try p.parseBlockExpr(); |
| 931 | if (block_expr != 0) { | 945 | if (opt_block_expr) |block_expr| { |
| 932 | return p.addNode(.{ | 946 | return p.addNode(.{ |
| 933 | .tag = .@"comptime", | 947 | .tag = .@"comptime", |
| 934 | .main_token = comptime_token, | 948 | .main_token = comptime_token, |
| 935 | .data = .{ | 949 | .data = .{ .node = block_expr }, |
| 936 | .lhs = block_expr, | ||
| 937 | .rhs = undefined, | ||
| 938 | }, | ||
| 939 | }); | 950 | }); |
| 940 | } | 951 | } |
| 941 | 952 | ||
| ... | @@ -947,23 +958,17 @@ fn expectStatement(p: *Parse, allow_defer_var: bool) Error!Node.Index { | ... | @@ -947,23 +958,17 @@ fn expectStatement(p: *Parse, allow_defer_var: bool) Error!Node.Index { |
| 947 | return p.addNode(.{ | 958 | return p.addNode(.{ |
| 948 | .tag = .@"comptime", | 959 | .tag = .@"comptime", |
| 949 | .main_token = comptime_token, | 960 | .main_token = comptime_token, |
| 950 | .data = .{ | 961 | .data = .{ .node = assign }, |
| 951 | .lhs = assign, | ||
| 952 | .rhs = undefined, | ||
| 953 | }, | ||
| 954 | }); | 962 | }); |
| 955 | } | 963 | } |
| 956 | } | 964 | } |
| 957 | 965 | ||
| 958 | switch (p.token_tags[p.tok_i]) { | 966 | switch (p.tokenTag(p.tok_i)) { |
| 959 | .keyword_nosuspend => { | 967 | .keyword_nosuspend => { |
| 960 | return p.addNode(.{ | 968 | return p.addNode(.{ |
| 961 | .tag = .@"nosuspend", | 969 | .tag = .@"nosuspend", |
| 962 | .main_token = p.nextToken(), | 970 | .main_token = p.nextToken(), |
| 963 | .data = .{ | 971 | .data = .{ .node = try p.expectBlockExprStatement() }, |
| 964 | .lhs = try p.expectBlockExprStatement(), | ||
| 965 | .rhs = undefined, | ||
| 966 | }, | ||
| 967 | }); | 972 | }); |
| 968 | }, | 973 | }, |
| 969 | .keyword_suspend => { | 974 | .keyword_suspend => { |
| ... | @@ -972,27 +977,21 @@ fn expectStatement(p: *Parse, allow_defer_var: bool) Error!Node.Index { | ... | @@ -972,27 +977,21 @@ fn expectStatement(p: *Parse, allow_defer_var: bool) Error!Node.Index { |
| 972 | return p.addNode(.{ | 977 | return p.addNode(.{ |
| 973 | .tag = .@"suspend", | 978 | .tag = .@"suspend", |
| 974 | .main_token = token, | 979 | .main_token = token, |
| 975 | .data = .{ | 980 | .data = .{ .node = block_expr }, |
| 976 | .lhs = block_expr, | ||
| 977 | .rhs = undefined, | ||
| 978 | }, | ||
| 979 | }); | 981 | }); |
| 980 | }, | 982 | }, |
| 981 | .keyword_defer => if (allow_defer_var) return p.addNode(.{ | 983 | .keyword_defer => if (allow_defer_var) return p.addNode(.{ |
| 982 | .tag = .@"defer", | 984 | .tag = .@"defer", |
| 983 | .main_token = p.nextToken(), | 985 | .main_token = p.nextToken(), |
| 984 | .data = .{ | 986 | .data = .{ .node = try p.expectBlockExprStatement() }, |
| 985 | .lhs = undefined, | ||
| 986 | .rhs = try p.expectBlockExprStatement(), | ||
| 987 | }, | ||
| 988 | }), | 987 | }), |
| 989 | .keyword_errdefer => if (allow_defer_var) return p.addNode(.{ | 988 | .keyword_errdefer => if (allow_defer_var) return p.addNode(.{ |
| 990 | .tag = .@"errdefer", | 989 | .tag = .@"errdefer", |
| 991 | .main_token = p.nextToken(), | 990 | .main_token = p.nextToken(), |
| 992 | .data = .{ | 991 | .data = .{ .opt_token_and_node = .{ |
| 993 | .lhs = try p.parsePayload(), | 992 | try p.parsePayload(), |
| 994 | .rhs = try p.expectBlockExprStatement(), | 993 | try p.expectBlockExprStatement(), |
| 995 | }, | 994 | } }, |
| 996 | }), | 995 | }), |
| 997 | .keyword_if => return p.expectIfStatement(), | 996 | .keyword_if => return p.expectIfStatement(), |
| 998 | .keyword_enum, .keyword_struct, .keyword_union => { | 997 | .keyword_enum, .keyword_struct, .keyword_union => { |
| ... | @@ -1002,18 +1001,14 @@ fn expectStatement(p: *Parse, allow_defer_var: bool) Error!Node.Index { | ... | @@ -1002,18 +1001,14 @@ fn expectStatement(p: *Parse, allow_defer_var: bool) Error!Node.Index { |
| 1002 | return p.addNode(.{ | 1001 | return p.addNode(.{ |
| 1003 | .tag = .identifier, | 1002 | .tag = .identifier, |
| 1004 | .main_token = identifier, | 1003 | .main_token = identifier, |
| 1005 | .data = .{ | 1004 | .data = undefined, |
| 1006 | .lhs = undefined, | ||
| 1007 | .rhs = undefined, | ||
| 1008 | }, | ||
| 1009 | }); | 1005 | }); |
| 1010 | } | 1006 | } |
| 1011 | }, | 1007 | }, |
| 1012 | else => {}, | 1008 | else => {}, |
| 1013 | } | 1009 | } |
| 1014 | 1010 | ||
| 1015 | const labeled_statement = try p.parseLabeledStatement(); | 1011 | if (try p.parseLabeledStatement()) |labeled_statement| return labeled_statement; |
| 1016 | if (labeled_statement != 0) return labeled_statement; | ||
| 1017 | 1012 | ||
| 1018 | if (allow_defer_var) { | 1013 | if (allow_defer_var) { |
| 1019 | return p.expectVarDeclExprStatement(null); | 1014 | return p.expectVarDeclExprStatement(null); |
| ... | @@ -1028,12 +1023,15 @@ fn expectStatement(p: *Parse, allow_defer_var: bool) Error!Node.Index { | ... | @@ -1028,12 +1023,15 @@ fn expectStatement(p: *Parse, allow_defer_var: bool) Error!Node.Index { |
| 1028 | /// <- BlockExpr | 1023 | /// <- BlockExpr |
| 1029 | /// / VarDeclExprStatement | 1024 | /// / VarDeclExprStatement |
| 1030 | fn expectComptimeStatement(p: *Parse, comptime_token: TokenIndex) !Node.Index { | 1025 | fn expectComptimeStatement(p: *Parse, comptime_token: TokenIndex) !Node.Index { |
| 1031 | const block_expr = try p.parseBlockExpr(); | 1026 | const maybe_block_expr = try p.parseBlockExpr(); |
| 1032 | if (block_expr != 0) { | 1027 | if (maybe_block_expr) |block_expr| { |
| 1033 | return p.addNode(.{ | 1028 | return p.addNode(.{ |
| 1034 | .tag = .@"comptime", | 1029 | .tag = .@"comptime", |
| 1035 | .main_token = comptime_token, | 1030 | .main_token = comptime_token, |
| 1036 | .data = .{ .lhs = block_expr, .rhs = undefined }, | 1031 | .data = .{ |
| 1032 | .lhs = .{ .node = block_expr }, | ||
| 1033 | .rhs = undefined, | ||
| 1034 | }, | ||
| 1037 | }); | 1035 | }); |
| 1038 | } | 1036 | } |
| 1039 | return p.expectVarDeclExprStatement(comptime_token); | 1037 | return p.expectVarDeclExprStatement(comptime_token); |
| ... | @@ -1047,12 +1045,11 @@ fn expectVarDeclExprStatement(p: *Parse, comptime_token: ?TokenIndex) !Node.Inde | ... | @@ -1047,12 +1045,11 @@ fn expectVarDeclExprStatement(p: *Parse, comptime_token: ?TokenIndex) !Node.Inde |
| 1047 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 1045 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 1048 | 1046 | ||
| 1049 | while (true) { | 1047 | while (true) { |
| 1050 | const var_decl_proto = try p.parseVarDeclProto(); | 1048 | const opt_var_decl_proto = try p.parseVarDeclProto(); |
| 1051 | if (var_decl_proto != 0) { | 1049 | if (opt_var_decl_proto) |var_decl| { |
| 1052 | try p.scratch.append(p.gpa, var_decl_proto); | 1050 | try p.scratch.append(p.gpa, var_decl); |
| 1053 | } else { | 1051 | } else { |
| 1054 | const expr = try p.parseExpr(); | 1052 | const expr = try p.parseExpr() orelse { |
| 1055 | if (expr == 0) { | ||
| 1056 | if (p.scratch.items.len == scratch_top) { | 1053 | if (p.scratch.items.len == scratch_top) { |
| 1057 | // We parsed nothing | 1054 | // We parsed nothing |
| 1058 | return p.fail(.expected_statement); | 1055 | return p.fail(.expected_statement); |
| ... | @@ -1060,7 +1057,7 @@ fn expectVarDeclExprStatement(p: *Parse, comptime_token: ?TokenIndex) !Node.Inde | ... | @@ -1060,7 +1057,7 @@ fn expectVarDeclExprStatement(p: *Parse, comptime_token: ?TokenIndex) !Node.Inde |
| 1060 | // We've had at least one LHS, but had a bad comma | 1057 | // We've had at least one LHS, but had a bad comma |
| 1061 | return p.fail(.expected_expr_or_var_decl); | 1058 | return p.fail(.expected_expr_or_var_decl); |
| 1062 | } | 1059 | } |
| 1063 | } | 1060 | }; |
| 1064 | try p.scratch.append(p.gpa, expr); | 1061 | try p.scratch.append(p.gpa, expr); |
| 1065 | } | 1062 | } |
| 1066 | _ = p.eatToken(.comma) orelse break; | 1063 | _ = p.eatToken(.comma) orelse break; |
| ... | @@ -1079,7 +1076,7 @@ fn expectVarDeclExprStatement(p: *Parse, comptime_token: ?TokenIndex) !Node.Inde | ... | @@ -1079,7 +1076,7 @@ fn expectVarDeclExprStatement(p: *Parse, comptime_token: ?TokenIndex) !Node.Inde |
| 1079 | return p.failExpected(.equal); | 1076 | return p.failExpected(.equal); |
| 1080 | } | 1077 | } |
| 1081 | const lhs = p.scratch.items[scratch_top]; | 1078 | const lhs = p.scratch.items[scratch_top]; |
| 1082 | switch (p.nodes.items(.tag)[lhs]) { | 1079 | switch (p.nodeTag(lhs)) { |
| 1083 | .global_var_decl, .local_var_decl, .simple_var_decl, .aligned_var_decl => { | 1080 | .global_var_decl, .local_var_decl, .simple_var_decl, .aligned_var_decl => { |
| 1084 | // Definitely a var decl, so allow recovering from == | 1081 | // Definitely a var decl, so allow recovering from == |
| 1085 | if (p.eatToken(.equal_equal)) |tok| { | 1082 | if (p.eatToken(.equal_equal)) |tok| { |
| ... | @@ -1097,10 +1094,7 @@ fn expectVarDeclExprStatement(p: *Parse, comptime_token: ?TokenIndex) !Node.Inde | ... | @@ -1097,10 +1094,7 @@ fn expectVarDeclExprStatement(p: *Parse, comptime_token: ?TokenIndex) !Node.Inde |
| 1097 | return p.addNode(.{ | 1094 | return p.addNode(.{ |
| 1098 | .tag = .@"comptime", | 1095 | .tag = .@"comptime", |
| 1099 | .main_token = t, | 1096 | .main_token = t, |
| 1100 | .data = .{ | 1097 | .data = .{ .node = expr }, |
| 1101 | .lhs = expr, | ||
| 1102 | .rhs = undefined, | ||
| 1103 | }, | ||
| 1104 | }); | 1098 | }); |
| 1105 | } else { | 1099 | } else { |
| 1106 | return expr; | 1100 | return expr; |
| ... | @@ -1112,9 +1106,9 @@ fn expectVarDeclExprStatement(p: *Parse, comptime_token: ?TokenIndex) !Node.Inde | ... | @@ -1112,9 +1106,9 @@ fn expectVarDeclExprStatement(p: *Parse, comptime_token: ?TokenIndex) !Node.Inde |
| 1112 | 1106 | ||
| 1113 | if (lhs_count == 1) { | 1107 | if (lhs_count == 1) { |
| 1114 | const lhs = p.scratch.items[scratch_top]; | 1108 | const lhs = p.scratch.items[scratch_top]; |
| 1115 | switch (p.nodes.items(.tag)[lhs]) { | 1109 | switch (p.nodeTag(lhs)) { |
| 1116 | .global_var_decl, .local_var_decl, .simple_var_decl, .aligned_var_decl => { | 1110 | .simple_var_decl, .aligned_var_decl, .local_var_decl, .global_var_decl => { |
| 1117 | p.nodes.items(.data)[lhs].rhs = rhs; | 1111 | p.setVarDeclInitExpr(lhs, rhs.toOptional()); |
| 1118 | // Don't need to wrap in comptime | 1112 | // Don't need to wrap in comptime |
| 1119 | return lhs; | 1113 | return lhs; |
| 1120 | }, | 1114 | }, |
| ... | @@ -1123,16 +1117,16 @@ fn expectVarDeclExprStatement(p: *Parse, comptime_token: ?TokenIndex) !Node.Inde | ... | @@ -1123,16 +1117,16 @@ fn expectVarDeclExprStatement(p: *Parse, comptime_token: ?TokenIndex) !Node.Inde |
| 1123 | const expr = try p.addNode(.{ | 1117 | const expr = try p.addNode(.{ |
| 1124 | .tag = .assign, | 1118 | .tag = .assign, |
| 1125 | .main_token = equal_token, | 1119 | .main_token = equal_token, |
| 1126 | .data = .{ .lhs = lhs, .rhs = rhs }, | 1120 | .data = .{ .node_and_node = .{ |
| 1121 | lhs, | ||
| 1122 | rhs, | ||
| 1123 | } }, | ||
| 1127 | }); | 1124 | }); |
| 1128 | if (comptime_token) |t| { | 1125 | if (comptime_token) |t| { |
| 1129 | return p.addNode(.{ | 1126 | return p.addNode(.{ |
| 1130 | .tag = .@"comptime", | 1127 | .tag = .@"comptime", |
| 1131 | .main_token = t, | 1128 | .main_token = t, |
| 1132 | .data = .{ | 1129 | .data = .{ .node = expr }, |
| 1133 | .lhs = expr, | ||
| 1134 | .rhs = undefined, | ||
| 1135 | }, | ||
| 1136 | }); | 1130 | }); |
| 1137 | } else { | 1131 | } else { |
| 1138 | return expr; | 1132 | return expr; |
| ... | @@ -1141,32 +1135,32 @@ fn expectVarDeclExprStatement(p: *Parse, comptime_token: ?TokenIndex) !Node.Inde | ... | @@ -1141,32 +1135,32 @@ fn expectVarDeclExprStatement(p: *Parse, comptime_token: ?TokenIndex) !Node.Inde |
| 1141 | 1135 | ||
| 1142 | // An actual destructure! No need for any `comptime` wrapper here. | 1136 | // An actual destructure! No need for any `comptime` wrapper here. |
| 1143 | 1137 | ||
| 1144 | const extra_start = p.extra_data.items.len; | 1138 | const extra_start: ExtraIndex = @enumFromInt(p.extra_data.items.len); |
| 1145 | try p.extra_data.ensureUnusedCapacity(p.gpa, lhs_count + 1); | 1139 | try p.extra_data.ensureUnusedCapacity(p.gpa, lhs_count + 1); |
| 1146 | p.extra_data.appendAssumeCapacity(@intCast(lhs_count)); | 1140 | p.extra_data.appendAssumeCapacity(@intCast(lhs_count)); |
| 1147 | p.extra_data.appendSliceAssumeCapacity(p.scratch.items[scratch_top..]); | 1141 | p.extra_data.appendSliceAssumeCapacity(@ptrCast(p.scratch.items[scratch_top..])); |
| 1148 | 1142 | ||
| 1149 | return p.addNode(.{ | 1143 | return p.addNode(.{ |
| 1150 | .tag = .assign_destructure, | 1144 | .tag = .assign_destructure, |
| 1151 | .main_token = equal_token, | 1145 | .main_token = equal_token, |
| 1152 | .data = .{ | 1146 | .data = .{ .extra_and_node = .{ |
| 1153 | .lhs = @intCast(extra_start), | 1147 | extra_start, |
| 1154 | .rhs = rhs, | 1148 | rhs, |
| 1155 | }, | 1149 | } }, |
| 1156 | }); | 1150 | }); |
| 1157 | } | 1151 | } |
| 1158 | 1152 | ||
| 1159 | /// If a parse error occurs, reports an error, but then finds the next statement | 1153 | /// If a parse error occurs, reports an error, but then finds the next statement |
| 1160 | /// and returns that one instead. If a parse error occurs but there is no following | 1154 | /// and returns that one instead. If a parse error occurs but there is no following |
| 1161 | /// statement, returns 0. | 1155 | /// statement, returns 0. |
| 1162 | fn expectStatementRecoverable(p: *Parse) Error!Node.Index { | 1156 | fn expectStatementRecoverable(p: *Parse) Error!?Node.Index { |
| 1163 | while (true) { | 1157 | while (true) { |
| 1164 | return p.expectStatement(true) catch |err| switch (err) { | 1158 | return p.expectStatement(true) catch |err| switch (err) { |
| 1165 | error.OutOfMemory => return error.OutOfMemory, | 1159 | error.OutOfMemory => return error.OutOfMemory, |
| 1166 | error.ParseError => { | 1160 | error.ParseError => { |
| 1167 | p.findNextStmt(); // Try to skip to the next statement. | 1161 | p.findNextStmt(); // Try to skip to the next statement. |
| 1168 | switch (p.token_tags[p.tok_i]) { | 1162 | switch (p.tokenTag(p.tok_i)) { |
| 1169 | .r_brace => return null_node, | 1163 | .r_brace => return null, |
| 1170 | .eof => return error.ParseError, | 1164 | .eof => return error.ParseError, |
| 1171 | else => continue, | 1165 | else => continue, |
| 1172 | } | 1166 | } |
| ... | @@ -1190,19 +1184,18 @@ fn expectIfStatement(p: *Parse) !Node.Index { | ... | @@ -1190,19 +1184,18 @@ fn expectIfStatement(p: *Parse) !Node.Index { |
| 1190 | var else_required = false; | 1184 | var else_required = false; |
| 1191 | const then_expr = blk: { | 1185 | const then_expr = blk: { |
| 1192 | const block_expr = try p.parseBlockExpr(); | 1186 | const block_expr = try p.parseBlockExpr(); |
| 1193 | if (block_expr != 0) break :blk block_expr; | 1187 | if (block_expr) |block| break :blk block; |
| 1194 | const assign_expr = try p.parseAssignExpr(); | 1188 | const assign_expr = try p.parseAssignExpr() orelse { |
| 1195 | if (assign_expr == 0) { | ||
| 1196 | return p.fail(.expected_block_or_assignment); | 1189 | return p.fail(.expected_block_or_assignment); |
| 1197 | } | 1190 | }; |
| 1198 | if (p.eatToken(.semicolon)) |_| { | 1191 | if (p.eatToken(.semicolon)) |_| { |
| 1199 | return p.addNode(.{ | 1192 | return p.addNode(.{ |
| 1200 | .tag = .if_simple, | 1193 | .tag = .if_simple, |
| 1201 | .main_token = if_token, | 1194 | .main_token = if_token, |
| 1202 | .data = .{ | 1195 | .data = .{ .node_and_node = .{ |
| 1203 | .lhs = condition, | 1196 | condition, |
| 1204 | .rhs = assign_expr, | 1197 | assign_expr, |
| 1205 | }, | 1198 | } }, |
| 1206 | }); | 1199 | }); |
| 1207 | } | 1200 | } |
| 1208 | else_required = true; | 1201 | else_required = true; |
| ... | @@ -1215,10 +1208,10 @@ fn expectIfStatement(p: *Parse) !Node.Index { | ... | @@ -1215,10 +1208,10 @@ fn expectIfStatement(p: *Parse) !Node.Index { |
| 1215 | return p.addNode(.{ | 1208 | return p.addNode(.{ |
| 1216 | .tag = .if_simple, | 1209 | .tag = .if_simple, |
| 1217 | .main_token = if_token, | 1210 | .main_token = if_token, |
| 1218 | .data = .{ | 1211 | .data = .{ .node_and_node = .{ |
| 1219 | .lhs = condition, | 1212 | condition, |
| 1220 | .rhs = then_expr, | 1213 | then_expr, |
| 1221 | }, | 1214 | } }, |
| 1222 | }); | 1215 | }); |
| 1223 | }; | 1216 | }; |
| 1224 | _ = try p.parsePayload(); | 1217 | _ = try p.parsePayload(); |
| ... | @@ -1226,57 +1219,46 @@ fn expectIfStatement(p: *Parse) !Node.Index { | ... | @@ -1226,57 +1219,46 @@ fn expectIfStatement(p: *Parse) !Node.Index { |
| 1226 | return p.addNode(.{ | 1219 | return p.addNode(.{ |
| 1227 | .tag = .@"if", | 1220 | .tag = .@"if", |
| 1228 | .main_token = if_token, | 1221 | .main_token = if_token, |
| 1229 | .data = .{ | 1222 | .data = .{ .node_and_extra = .{ |
| 1230 | .lhs = condition, | 1223 | condition, try p.addExtra(Node.If{ |
| 1231 | .rhs = try p.addExtra(Node.If{ | ||
| 1232 | .then_expr = then_expr, | 1224 | .then_expr = then_expr, |
| 1233 | .else_expr = else_expr, | 1225 | .else_expr = else_expr, |
| 1234 | }), | 1226 | }), |
| 1235 | }, | 1227 | } }, |
| 1236 | }); | 1228 | }); |
| 1237 | } | 1229 | } |
| 1238 | 1230 | ||
| 1239 | /// LabeledStatement <- BlockLabel? (Block / LoopStatement / SwitchExpr) | 1231 | /// LabeledStatement <- BlockLabel? (Block / LoopStatement / SwitchExpr) |
| 1240 | fn parseLabeledStatement(p: *Parse) !Node.Index { | 1232 | fn parseLabeledStatement(p: *Parse) !?Node.Index { |
| 1241 | const label_token = p.parseBlockLabel(); | 1233 | const opt_label_token = p.parseBlockLabel(); |
| 1242 | const block = try p.parseBlock(); | 1234 | |
| 1243 | if (block != 0) return block; | 1235 | if (try p.parseBlock()) |block| return block; |
| 1244 | 1236 | if (try p.parseLoopStatement()) |loop_stmt| return loop_stmt; | |
| 1245 | const loop_stmt = try p.parseLoopStatement(); | 1237 | if (try p.parseSwitchExpr(opt_label_token != null)) |switch_expr| return switch_expr; |
| 1246 | if (loop_stmt != 0) return loop_stmt; | 1238 | |
| 1247 | 1239 | const label_token = opt_label_token orelse return null; | |
| 1248 | const switch_expr = try p.parseSwitchExpr(label_token != 0); | 1240 | |
| 1249 | if (switch_expr != 0) return switch_expr; | 1241 | const after_colon = p.tok_i; |
| 1250 | 1242 | if (try p.parseTypeExpr()) |_| { | |
| 1251 | if (label_token != 0) { | 1243 | const a = try p.parseByteAlign(); |
| 1252 | const after_colon = p.tok_i; | 1244 | const b = try p.parseAddrSpace(); |
| 1253 | const node = try p.parseTypeExpr(); | 1245 | const c = try p.parseLinkSection(); |
| 1254 | if (node != 0) { | 1246 | const d = if (p.eatToken(.equal) == null) null else try p.expectExpr(); |
| 1255 | const a = try p.parseByteAlign(); | 1247 | if (a != null or b != null or c != null or d != null) { |
| 1256 | const b = try p.parseAddrSpace(); | 1248 | return p.failMsg(.{ .tag = .expected_var_const, .token = label_token }); |
| 1257 | const c = try p.parseLinkSection(); | ||
| 1258 | const d = if (p.eatToken(.equal) == null) 0 else try p.expectExpr(); | ||
| 1259 | if (a != 0 or b != 0 or c != 0 or d != 0) { | ||
| 1260 | return p.failMsg(.{ .tag = .expected_var_const, .token = label_token }); | ||
| 1261 | } | ||
| 1262 | } | 1249 | } |
| 1263 | return p.failMsg(.{ .tag = .expected_labelable, .token = after_colon }); | ||
| 1264 | } | 1250 | } |
| 1265 | 1251 | return p.failMsg(.{ .tag = .expected_labelable, .token = after_colon }); | |
| 1266 | return null_node; | ||
| 1267 | } | 1252 | } |
| 1268 | 1253 | ||
| 1269 | /// LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement) | 1254 | /// LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement) |
| 1270 | fn parseLoopStatement(p: *Parse) !Node.Index { | 1255 | fn parseLoopStatement(p: *Parse) !?Node.Index { |
| 1271 | const inline_token = p.eatToken(.keyword_inline); | 1256 | const inline_token = p.eatToken(.keyword_inline); |
| 1272 | 1257 | ||
| 1273 | const for_statement = try p.parseForStatement(); | 1258 | if (try p.parseForStatement()) |for_statement| return for_statement; |
| 1274 | if (for_statement != 0) return for_statement; | 1259 | if (try p.parseWhileStatement()) |while_statement| return while_statement; |
| 1275 | 1260 | ||
| 1276 | const while_statement = try p.parseWhileStatement(); | 1261 | if (inline_token == null) return null; |
| 1277 | if (while_statement != 0) return while_statement; | ||
| 1278 | |||
| 1279 | if (inline_token == null) return null_node; | ||
| 1280 | 1262 | ||
| 1281 | // If we've seen "inline", there should have been a "for" or "while" | 1263 | // If we've seen "inline", there should have been a "for" or "while" |
| 1282 | return p.fail(.expected_inlinable); | 1264 | return p.fail(.expected_inlinable); |
| ... | @@ -1285,8 +1267,8 @@ fn parseLoopStatement(p: *Parse) !Node.Index { | ... | @@ -1285,8 +1267,8 @@ fn parseLoopStatement(p: *Parse) !Node.Index { |
| 1285 | /// ForStatement | 1267 | /// ForStatement |
| 1286 | /// <- ForPrefix BlockExpr ( KEYWORD_else Statement )? | 1268 | /// <- ForPrefix BlockExpr ( KEYWORD_else Statement )? |
| 1287 | /// / ForPrefix AssignExpr ( SEMICOLON / KEYWORD_else Statement ) | 1269 | /// / ForPrefix AssignExpr ( SEMICOLON / KEYWORD_else Statement ) |
| 1288 | fn parseForStatement(p: *Parse) !Node.Index { | 1270 | fn parseForStatement(p: *Parse) !?Node.Index { |
| 1289 | const for_token = p.eatToken(.keyword_for) orelse return null_node; | 1271 | const for_token = p.eatToken(.keyword_for) orelse return null; |
| 1290 | 1272 | ||
| 1291 | const scratch_top = p.scratch.items.len; | 1273 | const scratch_top = p.scratch.items.len; |
| 1292 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 1274 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| ... | @@ -1296,11 +1278,10 @@ fn parseForStatement(p: *Parse) !Node.Index { | ... | @@ -1296,11 +1278,10 @@ fn parseForStatement(p: *Parse) !Node.Index { |
| 1296 | var seen_semicolon = false; | 1278 | var seen_semicolon = false; |
| 1297 | const then_expr = blk: { | 1279 | const then_expr = blk: { |
| 1298 | const block_expr = try p.parseBlockExpr(); | 1280 | const block_expr = try p.parseBlockExpr(); |
| 1299 | if (block_expr != 0) break :blk block_expr; | 1281 | if (block_expr) |block| break :blk block; |
| 1300 | const assign_expr = try p.parseAssignExpr(); | 1282 | const assign_expr = try p.parseAssignExpr() orelse { |
| 1301 | if (assign_expr == 0) { | ||
| 1302 | return p.fail(.expected_block_or_assignment); | 1283 | return p.fail(.expected_block_or_assignment); |
| 1303 | } | 1284 | }; |
| 1304 | if (p.eatToken(.semicolon)) |_| { | 1285 | if (p.eatToken(.semicolon)) |_| { |
| 1305 | seen_semicolon = true; | 1286 | seen_semicolon = true; |
| 1306 | break :blk assign_expr; | 1287 | break :blk assign_expr; |
| ... | @@ -1316,28 +1297,25 @@ fn parseForStatement(p: *Parse) !Node.Index { | ... | @@ -1316,28 +1297,25 @@ fn parseForStatement(p: *Parse) !Node.Index { |
| 1316 | has_else = true; | 1297 | has_else = true; |
| 1317 | } else if (inputs == 1) { | 1298 | } else if (inputs == 1) { |
| 1318 | if (else_required) try p.warn(.expected_semi_or_else); | 1299 | if (else_required) try p.warn(.expected_semi_or_else); |
| 1319 | return p.addNode(.{ | 1300 | return try p.addNode(.{ |
| 1320 | .tag = .for_simple, | 1301 | .tag = .for_simple, |
| 1321 | .main_token = for_token, | 1302 | .main_token = for_token, |
| 1322 | .data = .{ | 1303 | .data = .{ .node_and_node = .{ |
| 1323 | .lhs = p.scratch.items[scratch_top], | 1304 | p.scratch.items[scratch_top], |
| 1324 | .rhs = then_expr, | 1305 | then_expr, |
| 1325 | }, | 1306 | } }, |
| 1326 | }); | 1307 | }); |
| 1327 | } else { | 1308 | } else { |
| 1328 | if (else_required) try p.warn(.expected_semi_or_else); | 1309 | if (else_required) try p.warn(.expected_semi_or_else); |
| 1329 | try p.scratch.append(p.gpa, then_expr); | 1310 | try p.scratch.append(p.gpa, then_expr); |
| 1330 | } | 1311 | } |
| 1331 | return p.addNode(.{ | 1312 | return try p.addNode(.{ |
| 1332 | .tag = .@"for", | 1313 | .tag = .@"for", |
| 1333 | .main_token = for_token, | 1314 | .main_token = for_token, |
| 1334 | .data = .{ | 1315 | .data = .{ .@"for" = .{ |
| 1335 | .lhs = (try p.listToSpan(p.scratch.items[scratch_top..])).start, | 1316 | (try p.listToSpan(p.scratch.items[scratch_top..])).start, |
| 1336 | .rhs = @as(u32, @bitCast(Node.For{ | 1317 | .{ .inputs = @intCast(inputs), .has_else = has_else }, |
| 1337 | .inputs = @as(u31, @intCast(inputs)), | 1318 | } }, |
| 1338 | .has_else = has_else, | ||
| 1339 | })), | ||
| 1340 | }, | ||
| 1341 | }); | 1319 | }); |
| 1342 | } | 1320 | } |
| 1343 | 1321 | ||
| ... | @@ -1346,8 +1324,8 @@ fn parseForStatement(p: *Parse) !Node.Index { | ... | @@ -1346,8 +1324,8 @@ fn parseForStatement(p: *Parse) !Node.Index { |
| 1346 | /// WhileStatement | 1324 | /// WhileStatement |
| 1347 | /// <- WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )? | 1325 | /// <- WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )? |
| 1348 | /// / WhilePrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement ) | 1326 | /// / WhilePrefix AssignExpr ( SEMICOLON / KEYWORD_else Payload? Statement ) |
| 1349 | fn parseWhileStatement(p: *Parse) !Node.Index { | 1327 | fn parseWhileStatement(p: *Parse) !?Node.Index { |
| 1350 | const while_token = p.eatToken(.keyword_while) orelse return null_node; | 1328 | const while_token = p.eatToken(.keyword_while) orelse return null; |
| 1351 | _ = try p.expectToken(.l_paren); | 1329 | _ = try p.expectToken(.l_paren); |
| 1352 | const condition = try p.expectExpr(); | 1330 | const condition = try p.expectExpr(); |
| 1353 | _ = try p.expectToken(.r_paren); | 1331 | _ = try p.expectToken(.r_paren); |
| ... | @@ -1359,32 +1337,31 @@ fn parseWhileStatement(p: *Parse) !Node.Index { | ... | @@ -1359,32 +1337,31 @@ fn parseWhileStatement(p: *Parse) !Node.Index { |
| 1359 | var else_required = false; | 1337 | var else_required = false; |
| 1360 | const then_expr = blk: { | 1338 | const then_expr = blk: { |
| 1361 | const block_expr = try p.parseBlockExpr(); | 1339 | const block_expr = try p.parseBlockExpr(); |
| 1362 | if (block_expr != 0) break :blk block_expr; | 1340 | if (block_expr) |block| break :blk block; |
| 1363 | const assign_expr = try p.parseAssignExpr(); | 1341 | const assign_expr = try p.parseAssignExpr() orelse { |
| 1364 | if (assign_expr == 0) { | ||
| 1365 | return p.fail(.expected_block_or_assignment); | 1342 | return p.fail(.expected_block_or_assignment); |
| 1366 | } | 1343 | }; |
| 1367 | if (p.eatToken(.semicolon)) |_| { | 1344 | if (p.eatToken(.semicolon)) |_| { |
| 1368 | if (cont_expr == 0) { | 1345 | if (cont_expr == null) { |
| 1369 | return p.addNode(.{ | 1346 | return try p.addNode(.{ |
| 1370 | .tag = .while_simple, | 1347 | .tag = .while_simple, |
| 1371 | .main_token = while_token, | 1348 | .main_token = while_token, |
| 1372 | .data = .{ | 1349 | .data = .{ .node_and_node = .{ |
| 1373 | .lhs = condition, | 1350 | condition, |
| 1374 | .rhs = assign_expr, | 1351 | assign_expr, |
| 1375 | }, | 1352 | } }, |
| 1376 | }); | 1353 | }); |
| 1377 | } else { | 1354 | } else { |
| 1378 | return p.addNode(.{ | 1355 | return try p.addNode(.{ |
| 1379 | .tag = .while_cont, | 1356 | .tag = .while_cont, |
| 1380 | .main_token = while_token, | 1357 | .main_token = while_token, |
| 1381 | .data = .{ | 1358 | .data = .{ .node_and_extra = .{ |
| 1382 | .lhs = condition, | 1359 | condition, |
| 1383 | .rhs = try p.addExtra(Node.WhileCont{ | 1360 | try p.addExtra(Node.WhileCont{ |
| 1384 | .cont_expr = cont_expr, | 1361 | .cont_expr = cont_expr.?, |
| 1385 | .then_expr = assign_expr, | 1362 | .then_expr = assign_expr, |
| 1386 | }), | 1363 | }), |
| 1387 | }, | 1364 | } }, |
| 1388 | }); | 1365 | }); |
| 1389 | } | 1366 | } |
| 1390 | } | 1367 | } |
| ... | @@ -1395,84 +1372,77 @@ fn parseWhileStatement(p: *Parse) !Node.Index { | ... | @@ -1395,84 +1372,77 @@ fn parseWhileStatement(p: *Parse) !Node.Index { |
| 1395 | if (else_required) { | 1372 | if (else_required) { |
| 1396 | try p.warn(.expected_semi_or_else); | 1373 | try p.warn(.expected_semi_or_else); |
| 1397 | } | 1374 | } |
| 1398 | if (cont_expr == 0) { | 1375 | if (cont_expr == null) { |
| 1399 | return p.addNode(.{ | 1376 | return try p.addNode(.{ |
| 1400 | .tag = .while_simple, | 1377 | .tag = .while_simple, |
| 1401 | .main_token = while_token, | 1378 | .main_token = while_token, |
| 1402 | .data = .{ | 1379 | .data = .{ .node_and_node = .{ |
| 1403 | .lhs = condition, | 1380 | condition, |
| 1404 | .rhs = then_expr, | 1381 | then_expr, |
| 1405 | }, | 1382 | } }, |
| 1406 | }); | 1383 | }); |
| 1407 | } else { | 1384 | } else { |
| 1408 | return p.addNode(.{ | 1385 | return try p.addNode(.{ |
| 1409 | .tag = .while_cont, | 1386 | .tag = .while_cont, |
| 1410 | .main_token = while_token, | 1387 | .main_token = while_token, |
| 1411 | .data = .{ | 1388 | .data = .{ .node_and_extra = .{ |
| 1412 | .lhs = condition, | 1389 | condition, |
| 1413 | .rhs = try p.addExtra(Node.WhileCont{ | 1390 | try p.addExtra(Node.WhileCont{ |
| 1414 | .cont_expr = cont_expr, | 1391 | .cont_expr = cont_expr.?, |
| 1415 | .then_expr = then_expr, | 1392 | .then_expr = then_expr, |
| 1416 | }), | 1393 | }), |
| 1417 | }, | 1394 | } }, |
| 1418 | }); | 1395 | }); |
| 1419 | } | 1396 | } |
| 1420 | }; | 1397 | }; |
| 1421 | _ = try p.parsePayload(); | 1398 | _ = try p.parsePayload(); |
| 1422 | const else_expr = try p.expectStatement(false); | 1399 | const else_expr = try p.expectStatement(false); |
| 1423 | return p.addNode(.{ | 1400 | return try p.addNode(.{ |
| 1424 | .tag = .@"while", | 1401 | .tag = .@"while", |
| 1425 | .main_token = while_token, | 1402 | .main_token = while_token, |
| 1426 | .data = .{ | 1403 | .data = .{ .node_and_extra = .{ |
| 1427 | .lhs = condition, | 1404 | condition, try p.addExtra(Node.While{ |
| 1428 | .rhs = try p.addExtra(Node.While{ | 1405 | .cont_expr = .fromOptional(cont_expr), |
| 1429 | .cont_expr = cont_expr, | ||
| 1430 | .then_expr = then_expr, | 1406 | .then_expr = then_expr, |
| 1431 | .else_expr = else_expr, | 1407 | .else_expr = else_expr, |
| 1432 | }), | 1408 | }), |
| 1433 | }, | 1409 | } }, |
| 1434 | }); | 1410 | }); |
| 1435 | } | 1411 | } |
| 1436 | 1412 | ||
| 1437 | /// BlockExprStatement | 1413 | /// BlockExprStatement |
| 1438 | /// <- BlockExpr | 1414 | /// <- BlockExpr |
| 1439 | /// / AssignExpr SEMICOLON | 1415 | /// / AssignExpr SEMICOLON |
| 1440 | fn parseBlockExprStatement(p: *Parse) !Node.Index { | 1416 | fn parseBlockExprStatement(p: *Parse) !?Node.Index { |
| 1441 | const block_expr = try p.parseBlockExpr(); | 1417 | const block_expr = try p.parseBlockExpr(); |
| 1442 | if (block_expr != 0) { | 1418 | if (block_expr) |expr| return expr; |
| 1443 | return block_expr; | ||
| 1444 | } | ||
| 1445 | const assign_expr = try p.parseAssignExpr(); | 1419 | const assign_expr = try p.parseAssignExpr(); |
| 1446 | if (assign_expr != 0) { | 1420 | if (assign_expr) |expr| { |
| 1447 | try p.expectSemicolon(.expected_semi_after_stmt, true); | 1421 | try p.expectSemicolon(.expected_semi_after_stmt, true); |
| 1448 | return assign_expr; | 1422 | return expr; |
| 1449 | } | 1423 | } |
| 1450 | return null_node; | 1424 | return null; |
| 1451 | } | 1425 | } |
| 1452 | 1426 | ||
| 1453 | fn expectBlockExprStatement(p: *Parse) !Node.Index { | 1427 | fn expectBlockExprStatement(p: *Parse) !Node.Index { |
| 1454 | const node = try p.parseBlockExprStatement(); | 1428 | return try p.parseBlockExprStatement() orelse return p.fail(.expected_block_or_expr); |
| 1455 | if (node == 0) { | ||
| 1456 | return p.fail(.expected_block_or_expr); | ||
| 1457 | } | ||
| 1458 | return node; | ||
| 1459 | } | 1429 | } |
| 1460 | 1430 | ||
| 1461 | /// BlockExpr <- BlockLabel? Block | 1431 | /// BlockExpr <- BlockLabel? Block |
| 1462 | fn parseBlockExpr(p: *Parse) Error!Node.Index { | 1432 | fn parseBlockExpr(p: *Parse) Error!?Node.Index { |
| 1463 | switch (p.token_tags[p.tok_i]) { | 1433 | switch (p.tokenTag(p.tok_i)) { |
| 1464 | .identifier => { | 1434 | .identifier => { |
| 1465 | if (p.token_tags[p.tok_i + 1] == .colon and | 1435 | if (p.tokenTag(p.tok_i + 1) == .colon and |
| 1466 | p.token_tags[p.tok_i + 2] == .l_brace) | 1436 | p.tokenTag(p.tok_i + 2) == .l_brace) |
| 1467 | { | 1437 | { |
| 1468 | p.tok_i += 2; | 1438 | p.tok_i += 2; |
| 1469 | return p.parseBlock(); | 1439 | return p.parseBlock(); |
| 1470 | } else { | 1440 | } else { |
| 1471 | return null_node; | 1441 | return null; |
| 1472 | } | 1442 | } |
| 1473 | }, | 1443 | }, |
| 1474 | .l_brace => return p.parseBlock(), | 1444 | .l_brace => return p.parseBlock(), |
| 1475 | else => return null_node, | 1445 | else => return null, |
| 1476 | } | 1446 | } |
| 1477 | } | 1447 | } |
| 1478 | 1448 | ||
| ... | @@ -1497,38 +1467,36 @@ fn parseBlockExpr(p: *Parse) Error!Node.Index { | ... | @@ -1497,38 +1467,36 @@ fn parseBlockExpr(p: *Parse) Error!Node.Index { |
| 1497 | /// / PLUSPERCENTEQUAL | 1467 | /// / PLUSPERCENTEQUAL |
| 1498 | /// / MINUSPERCENTEQUAL | 1468 | /// / MINUSPERCENTEQUAL |
| 1499 | /// / EQUAL | 1469 | /// / EQUAL |
| 1500 | fn parseAssignExpr(p: *Parse) !Node.Index { | 1470 | fn parseAssignExpr(p: *Parse) !?Node.Index { |
| 1501 | const expr = try p.parseExpr(); | 1471 | const expr = try p.parseExpr() orelse return null; |
| 1502 | if (expr == 0) return null_node; | 1472 | return try p.finishAssignExpr(expr); |
| 1503 | return p.finishAssignExpr(expr); | ||
| 1504 | } | 1473 | } |
| 1505 | 1474 | ||
| 1506 | /// SingleAssignExpr <- Expr (AssignOp Expr)? | 1475 | /// SingleAssignExpr <- Expr (AssignOp Expr)? |
| 1507 | fn parseSingleAssignExpr(p: *Parse) !Node.Index { | 1476 | fn parseSingleAssignExpr(p: *Parse) !?Node.Index { |
| 1508 | const lhs = try p.parseExpr(); | 1477 | const lhs = try p.parseExpr() orelse return null; |
| 1509 | if (lhs == 0) return null_node; | 1478 | const tag = assignOpNode(p.tokenTag(p.tok_i)) orelse return lhs; |
| 1510 | const tag = assignOpNode(p.token_tags[p.tok_i]) orelse return lhs; | 1479 | return try p.addNode(.{ |
| 1511 | return p.addNode(.{ | ||
| 1512 | .tag = tag, | 1480 | .tag = tag, |
| 1513 | .main_token = p.nextToken(), | 1481 | .main_token = p.nextToken(), |
| 1514 | .data = .{ | 1482 | .data = .{ .node_and_node = .{ |
| 1515 | .lhs = lhs, | 1483 | lhs, |
| 1516 | .rhs = try p.expectExpr(), | 1484 | try p.expectExpr(), |
| 1517 | }, | 1485 | } }, |
| 1518 | }); | 1486 | }); |
| 1519 | } | 1487 | } |
| 1520 | 1488 | ||
| 1521 | fn finishAssignExpr(p: *Parse, lhs: Node.Index) !Node.Index { | 1489 | fn finishAssignExpr(p: *Parse, lhs: Node.Index) !Node.Index { |
| 1522 | const tok = p.token_tags[p.tok_i]; | 1490 | const tok = p.tokenTag(p.tok_i); |
| 1523 | if (tok == .comma) return p.finishAssignDestructureExpr(lhs); | 1491 | if (tok == .comma) return p.finishAssignDestructureExpr(lhs); |
| 1524 | const tag = assignOpNode(tok) orelse return lhs; | 1492 | const tag = assignOpNode(tok) orelse return lhs; |
| 1525 | return p.addNode(.{ | 1493 | return p.addNode(.{ |
| 1526 | .tag = tag, | 1494 | .tag = tag, |
| 1527 | .main_token = p.nextToken(), | 1495 | .main_token = p.nextToken(), |
| 1528 | .data = .{ | 1496 | .data = .{ .node_and_node = .{ |
| 1529 | .lhs = lhs, | 1497 | lhs, |
| 1530 | .rhs = try p.expectExpr(), | 1498 | try p.expectExpr(), |
| 1531 | }, | 1499 | } }, |
| 1532 | }); | 1500 | }); |
| 1533 | } | 1501 | } |
| 1534 | 1502 | ||
| ... | @@ -1574,48 +1542,35 @@ fn finishAssignDestructureExpr(p: *Parse, first_lhs: Node.Index) !Node.Index { | ... | @@ -1574,48 +1542,35 @@ fn finishAssignDestructureExpr(p: *Parse, first_lhs: Node.Index) !Node.Index { |
| 1574 | const lhs_count = p.scratch.items.len - scratch_top; | 1542 | const lhs_count = p.scratch.items.len - scratch_top; |
| 1575 | assert(lhs_count > 1); // we already had first_lhs, and must have at least one more lvalue | 1543 | assert(lhs_count > 1); // we already had first_lhs, and must have at least one more lvalue |
| 1576 | 1544 | ||
| 1577 | const extra_start = p.extra_data.items.len; | 1545 | const extra_start: ExtraIndex = @enumFromInt(p.extra_data.items.len); |
| 1578 | try p.extra_data.ensureUnusedCapacity(p.gpa, lhs_count + 1); | 1546 | try p.extra_data.ensureUnusedCapacity(p.gpa, lhs_count + 1); |
| 1579 | p.extra_data.appendAssumeCapacity(@intCast(lhs_count)); | 1547 | p.extra_data.appendAssumeCapacity(@intCast(lhs_count)); |
| 1580 | p.extra_data.appendSliceAssumeCapacity(p.scratch.items[scratch_top..]); | 1548 | p.extra_data.appendSliceAssumeCapacity(@ptrCast(p.scratch.items[scratch_top..])); |
| 1581 | 1549 | ||
| 1582 | return p.addNode(.{ | 1550 | return p.addNode(.{ |
| 1583 | .tag = .assign_destructure, | 1551 | .tag = .assign_destructure, |
| 1584 | .main_token = equal_token, | 1552 | .main_token = equal_token, |
| 1585 | .data = .{ | 1553 | .data = .{ .extra_and_node = .{ |
| 1586 | .lhs = @intCast(extra_start), | 1554 | extra_start, |
| 1587 | .rhs = rhs, | 1555 | rhs, |
| 1588 | }, | 1556 | } }, |
| 1589 | }); | 1557 | }); |
| 1590 | } | 1558 | } |
| 1591 | 1559 | ||
| 1592 | fn expectSingleAssignExpr(p: *Parse) !Node.Index { | 1560 | fn expectSingleAssignExpr(p: *Parse) !Node.Index { |
| 1593 | const expr = try p.parseSingleAssignExpr(); | 1561 | return try p.parseSingleAssignExpr() orelse return p.fail(.expected_expr_or_assignment); |
| 1594 | if (expr == 0) { | ||
| 1595 | return p.fail(.expected_expr_or_assignment); | ||
| 1596 | } | ||
| 1597 | return expr; | ||
| 1598 | } | 1562 | } |
| 1599 | 1563 | ||
| 1600 | fn expectAssignExpr(p: *Parse) !Node.Index { | 1564 | fn expectAssignExpr(p: *Parse) !Node.Index { |
| 1601 | const expr = try p.parseAssignExpr(); | 1565 | return try p.parseAssignExpr() orelse return p.fail(.expected_expr_or_assignment); |
| 1602 | if (expr == 0) { | ||
| 1603 | return p.fail(.expected_expr_or_assignment); | ||
| 1604 | } | ||
| 1605 | return expr; | ||
| 1606 | } | 1566 | } |
| 1607 | 1567 | ||
| 1608 | fn parseExpr(p: *Parse) Error!Node.Index { | 1568 | fn parseExpr(p: *Parse) Error!?Node.Index { |
| 1609 | return p.parseExprPrecedence(0); | 1569 | return p.parseExprPrecedence(0); |
| 1610 | } | 1570 | } |
| 1611 | 1571 | ||
| 1612 | fn expectExpr(p: *Parse) Error!Node.Index { | 1572 | fn expectExpr(p: *Parse) Error!Node.Index { |
| 1613 | const node = try p.parseExpr(); | 1573 | return try p.parseExpr() orelse return p.fail(.expected_expr); |
| 1614 | if (node == 0) { | ||
| 1615 | return p.fail(.expected_expr); | ||
| 1616 | } else { | ||
| 1617 | return node; | ||
| 1618 | } | ||
| 1619 | } | 1574 | } |
| 1620 | 1575 | ||
| 1621 | const Assoc = enum { | 1576 | const Assoc = enum { |
| ... | @@ -1671,17 +1626,14 @@ const operTable = std.enums.directEnumArrayDefault(Token.Tag, OperInfo, .{ .prec | ... | @@ -1671,17 +1626,14 @@ const operTable = std.enums.directEnumArrayDefault(Token.Tag, OperInfo, .{ .prec |
| 1671 | .asterisk_pipe = .{ .prec = 70, .tag = .mul_sat }, | 1626 | .asterisk_pipe = .{ .prec = 70, .tag = .mul_sat }, |
| 1672 | }); | 1627 | }); |
| 1673 | 1628 | ||
| 1674 | fn parseExprPrecedence(p: *Parse, min_prec: i32) Error!Node.Index { | 1629 | fn parseExprPrecedence(p: *Parse, min_prec: i32) Error!?Node.Index { |
| 1675 | assert(min_prec >= 0); | 1630 | assert(min_prec >= 0); |
| 1676 | var node = try p.parsePrefixExpr(); | 1631 | var node = try p.parsePrefixExpr() orelse return null; |
| 1677 | if (node == 0) { | ||
| 1678 | return null_node; | ||
| 1679 | } | ||
| 1680 | 1632 | ||
| 1681 | var banned_prec: i8 = -1; | 1633 | var banned_prec: i8 = -1; |
| 1682 | 1634 | ||
| 1683 | while (true) { | 1635 | while (true) { |
| 1684 | const tok_tag = p.token_tags[p.tok_i]; | 1636 | const tok_tag = p.tokenTag(p.tok_i); |
| 1685 | const info = operTable[@as(usize, @intCast(@intFromEnum(tok_tag)))]; | 1637 | const info = operTable[@as(usize, @intCast(@intFromEnum(tok_tag)))]; |
| 1686 | if (info.prec < min_prec) { | 1638 | if (info.prec < min_prec) { |
| 1687 | break; | 1639 | break; |
| ... | @@ -1695,16 +1647,15 @@ fn parseExprPrecedence(p: *Parse, min_prec: i32) Error!Node.Index { | ... | @@ -1695,16 +1647,15 @@ fn parseExprPrecedence(p: *Parse, min_prec: i32) Error!Node.Index { |
| 1695 | if (tok_tag == .keyword_catch) { | 1647 | if (tok_tag == .keyword_catch) { |
| 1696 | _ = try p.parsePayload(); | 1648 | _ = try p.parsePayload(); |
| 1697 | } | 1649 | } |
| 1698 | const rhs = try p.parseExprPrecedence(info.prec + 1); | 1650 | const rhs = try p.parseExprPrecedence(info.prec + 1) orelse { |
| 1699 | if (rhs == 0) { | ||
| 1700 | try p.warn(.expected_expr); | 1651 | try p.warn(.expected_expr); |
| 1701 | return node; | 1652 | return node; |
| 1702 | } | 1653 | }; |
| 1703 | 1654 | ||
| 1704 | { | 1655 | { |
| 1705 | const tok_len = tok_tag.lexeme().?.len; | 1656 | const tok_len = tok_tag.lexeme().?.len; |
| 1706 | const char_before = p.source[p.token_starts[oper_token] - 1]; | 1657 | const char_before = p.source[p.tokenStart(oper_token) - 1]; |
| 1707 | const char_after = p.source[p.token_starts[oper_token] + tok_len]; | 1658 | const char_after = p.source[p.tokenStart(oper_token) + tok_len]; |
| 1708 | if (tok_tag == .ampersand and char_after == '&') { | 1659 | if (tok_tag == .ampersand and char_after == '&') { |
| 1709 | // without types we don't know if '&&' was intended as 'bitwise_and address_of', or a c-style logical_and | 1660 | // without types we don't know if '&&' was intended as 'bitwise_and address_of', or a c-style logical_and |
| 1710 | // The best the parser can do is recommend changing it to 'and' or ' & &' | 1661 | // The best the parser can do is recommend changing it to 'and' or ' & &' |
| ... | @@ -1717,10 +1668,7 @@ fn parseExprPrecedence(p: *Parse, min_prec: i32) Error!Node.Index { | ... | @@ -1717,10 +1668,7 @@ fn parseExprPrecedence(p: *Parse, min_prec: i32) Error!Node.Index { |
| 1717 | node = try p.addNode(.{ | 1668 | node = try p.addNode(.{ |
| 1718 | .tag = info.tag, | 1669 | .tag = info.tag, |
| 1719 | .main_token = oper_token, | 1670 | .main_token = oper_token, |
| 1720 | .data = .{ | 1671 | .data = .{ .node_and_node = .{ node, rhs } }, |
| 1721 | .lhs = node, | ||
| 1722 | .rhs = rhs, | ||
| 1723 | }, | ||
| 1724 | }); | 1672 | }); |
| 1725 | 1673 | ||
| 1726 | if (info.assoc == Assoc.none) { | 1674 | if (info.assoc == Assoc.none) { |
| ... | @@ -1741,8 +1689,8 @@ fn parseExprPrecedence(p: *Parse, min_prec: i32) Error!Node.Index { | ... | @@ -1741,8 +1689,8 @@ fn parseExprPrecedence(p: *Parse, min_prec: i32) Error!Node.Index { |
| 1741 | /// / AMPERSAND | 1689 | /// / AMPERSAND |
| 1742 | /// / KEYWORD_try | 1690 | /// / KEYWORD_try |
| 1743 | /// / KEYWORD_await | 1691 | /// / KEYWORD_await |
| 1744 | fn parsePrefixExpr(p: *Parse) Error!Node.Index { | 1692 | fn parsePrefixExpr(p: *Parse) Error!?Node.Index { |
| 1745 | const tag: Node.Tag = switch (p.token_tags[p.tok_i]) { | 1693 | const tag: Node.Tag = switch (p.tokenTag(p.tok_i)) { |
| 1746 | .bang => .bool_not, | 1694 | .bang => .bool_not, |
| 1747 | .minus => .negation, | 1695 | .minus => .negation, |
| 1748 | .tilde => .bit_not, | 1696 | .tilde => .bit_not, |
| ... | @@ -1752,22 +1700,15 @@ fn parsePrefixExpr(p: *Parse) Error!Node.Index { | ... | @@ -1752,22 +1700,15 @@ fn parsePrefixExpr(p: *Parse) Error!Node.Index { |
| 1752 | .keyword_await => .@"await", | 1700 | .keyword_await => .@"await", |
| 1753 | else => return p.parsePrimaryExpr(), | 1701 | else => return p.parsePrimaryExpr(), |
| 1754 | }; | 1702 | }; |
| 1755 | return p.addNode(.{ | 1703 | return try p.addNode(.{ |
| 1756 | .tag = tag, | 1704 | .tag = tag, |
| 1757 | .main_token = p.nextToken(), | 1705 | .main_token = p.nextToken(), |
| 1758 | .data = .{ | 1706 | .data = .{ .node = try p.expectPrefixExpr() }, |
| 1759 | .lhs = try p.expectPrefixExpr(), | ||
| 1760 | .rhs = undefined, | ||
| 1761 | }, | ||
| 1762 | }); | 1707 | }); |
| 1763 | } | 1708 | } |
| 1764 | 1709 | ||
| 1765 | fn expectPrefixExpr(p: *Parse) Error!Node.Index { | 1710 | fn expectPrefixExpr(p: *Parse) Error!Node.Index { |
| 1766 | const node = try p.parsePrefixExpr(); | 1711 | return try p.parsePrefixExpr() orelse return p.fail(.expected_prefix_expr); |
| 1767 | if (node == 0) { | ||
| 1768 | return p.fail(.expected_prefix_expr); | ||
| 1769 | } | ||
| 1770 | return node; | ||
| 1771 | } | 1712 | } |
| 1772 | 1713 | ||
| 1773 | /// TypeExpr <- PrefixTypeOp* ErrorUnionExpr | 1714 | /// TypeExpr <- PrefixTypeOp* ErrorUnionExpr |
| ... | @@ -1787,67 +1728,64 @@ fn expectPrefixExpr(p: *Parse) Error!Node.Index { | ... | @@ -1787,67 +1728,64 @@ fn expectPrefixExpr(p: *Parse) Error!Node.Index { |
| 1787 | /// / LBRACKET ASTERISK (LETTERC / COLON Expr)? RBRACKET | 1728 | /// / LBRACKET ASTERISK (LETTERC / COLON Expr)? RBRACKET |
| 1788 | /// | 1729 | /// |
| 1789 | /// ArrayTypeStart <- LBRACKET Expr (COLON Expr)? RBRACKET | 1730 | /// ArrayTypeStart <- LBRACKET Expr (COLON Expr)? RBRACKET |
| 1790 | fn parseTypeExpr(p: *Parse) Error!Node.Index { | 1731 | fn parseTypeExpr(p: *Parse) Error!?Node.Index { |
| 1791 | switch (p.token_tags[p.tok_i]) { | 1732 | switch (p.tokenTag(p.tok_i)) { |
| 1792 | .question_mark => return p.addNode(.{ | 1733 | .question_mark => return try p.addNode(.{ |
| 1793 | .tag = .optional_type, | 1734 | .tag = .optional_type, |
| 1794 | .main_token = p.nextToken(), | 1735 | .main_token = p.nextToken(), |
| 1795 | .data = .{ | 1736 | .data = .{ .node = try p.expectTypeExpr() }, |
| 1796 | .lhs = try p.expectTypeExpr(), | ||
| 1797 | .rhs = undefined, | ||
| 1798 | }, | ||
| 1799 | }), | 1737 | }), |
| 1800 | .keyword_anyframe => switch (p.token_tags[p.tok_i + 1]) { | 1738 | .keyword_anyframe => switch (p.tokenTag(p.tok_i + 1)) { |
| 1801 | .arrow => return p.addNode(.{ | 1739 | .arrow => return try p.addNode(.{ |
| 1802 | .tag = .anyframe_type, | 1740 | .tag = .anyframe_type, |
| 1803 | .main_token = p.nextToken(), | 1741 | .main_token = p.nextToken(), |
| 1804 | .data = .{ | 1742 | .data = .{ .token_and_node = .{ |
| 1805 | .lhs = p.nextToken(), | 1743 | p.nextToken(), |
| 1806 | .rhs = try p.expectTypeExpr(), | 1744 | try p.expectTypeExpr(), |
| 1807 | }, | 1745 | } }, |
| 1808 | }), | 1746 | }), |
| 1809 | else => return p.parseErrorUnionExpr(), | 1747 | else => return try p.parseErrorUnionExpr(), |
| 1810 | }, | 1748 | }, |
| 1811 | .asterisk => { | 1749 | .asterisk => { |
| 1812 | const asterisk = p.nextToken(); | 1750 | const asterisk = p.nextToken(); |
| 1813 | const mods = try p.parsePtrModifiers(); | 1751 | const mods = try p.parsePtrModifiers(); |
| 1814 | const elem_type = try p.expectTypeExpr(); | 1752 | const elem_type = try p.expectTypeExpr(); |
| 1815 | if (mods.bit_range_start != 0) { | 1753 | if (mods.bit_range_start != .none) { |
| 1816 | return p.addNode(.{ | 1754 | return try p.addNode(.{ |
| 1817 | .tag = .ptr_type_bit_range, | 1755 | .tag = .ptr_type_bit_range, |
| 1818 | .main_token = asterisk, | 1756 | .main_token = asterisk, |
| 1819 | .data = .{ | 1757 | .data = .{ .extra_and_node = .{ |
| 1820 | .lhs = try p.addExtra(Node.PtrTypeBitRange{ | 1758 | try p.addExtra(Node.PtrTypeBitRange{ |
| 1821 | .sentinel = 0, | 1759 | .sentinel = .none, |
| 1822 | .align_node = mods.align_node, | 1760 | .align_node = mods.align_node.unwrap().?, |
| 1823 | .addrspace_node = mods.addrspace_node, | 1761 | .addrspace_node = mods.addrspace_node, |
| 1824 | .bit_range_start = mods.bit_range_start, | 1762 | .bit_range_start = mods.bit_range_start.unwrap().?, |
| 1825 | .bit_range_end = mods.bit_range_end, | 1763 | .bit_range_end = mods.bit_range_end.unwrap().?, |
| 1826 | }), | 1764 | }), |
| 1827 | .rhs = elem_type, | 1765 | elem_type, |
| 1828 | }, | 1766 | } }, |
| 1829 | }); | 1767 | }); |
| 1830 | } else if (mods.addrspace_node != 0) { | 1768 | } else if (mods.addrspace_node != .none) { |
| 1831 | return p.addNode(.{ | 1769 | return try p.addNode(.{ |
| 1832 | .tag = .ptr_type, | 1770 | .tag = .ptr_type, |
| 1833 | .main_token = asterisk, | 1771 | .main_token = asterisk, |
| 1834 | .data = .{ | 1772 | .data = .{ .extra_and_node = .{ |
| 1835 | .lhs = try p.addExtra(Node.PtrType{ | 1773 | try p.addExtra(Node.PtrType{ |
| 1836 | .sentinel = 0, | 1774 | .sentinel = .none, |
| 1837 | .align_node = mods.align_node, | 1775 | .align_node = mods.align_node, |
| 1838 | .addrspace_node = mods.addrspace_node, | 1776 | .addrspace_node = mods.addrspace_node, |
| 1839 | }), | 1777 | }), |
| 1840 | .rhs = elem_type, | 1778 | elem_type, |
| 1841 | }, | 1779 | } }, |
| 1842 | }); | 1780 | }); |
| 1843 | } else { | 1781 | } else { |
| 1844 | return p.addNode(.{ | 1782 | return try p.addNode(.{ |
| 1845 | .tag = .ptr_type_aligned, | 1783 | .tag = .ptr_type_aligned, |
| 1846 | .main_token = asterisk, | 1784 | .main_token = asterisk, |
| 1847 | .data = .{ | 1785 | .data = .{ .opt_node_and_node = .{ |
| 1848 | .lhs = mods.align_node, | 1786 | mods.align_node, |
| 1849 | .rhs = elem_type, | 1787 | elem_type, |
| 1850 | }, | 1788 | } }, |
| 1851 | }); | 1789 | }); |
| 1852 | } | 1790 | } |
| 1853 | }, | 1791 | }, |
| ... | @@ -1856,61 +1794,61 @@ fn parseTypeExpr(p: *Parse) Error!Node.Index { | ... | @@ -1856,61 +1794,61 @@ fn parseTypeExpr(p: *Parse) Error!Node.Index { |
| 1856 | const mods = try p.parsePtrModifiers(); | 1794 | const mods = try p.parsePtrModifiers(); |
| 1857 | const elem_type = try p.expectTypeExpr(); | 1795 | const elem_type = try p.expectTypeExpr(); |
| 1858 | const inner: Node.Index = inner: { | 1796 | const inner: Node.Index = inner: { |
| 1859 | if (mods.bit_range_start != 0) { | 1797 | if (mods.bit_range_start != .none) { |
| 1860 | break :inner try p.addNode(.{ | 1798 | break :inner try p.addNode(.{ |
| 1861 | .tag = .ptr_type_bit_range, | 1799 | .tag = .ptr_type_bit_range, |
| 1862 | .main_token = asterisk, | 1800 | .main_token = asterisk, |
| 1863 | .data = .{ | 1801 | .data = .{ .extra_and_node = .{ |
| 1864 | .lhs = try p.addExtra(Node.PtrTypeBitRange{ | 1802 | try p.addExtra(Node.PtrTypeBitRange{ |
| 1865 | .sentinel = 0, | 1803 | .sentinel = .none, |
| 1866 | .align_node = mods.align_node, | 1804 | .align_node = mods.align_node.unwrap().?, |
| 1867 | .addrspace_node = mods.addrspace_node, | 1805 | .addrspace_node = mods.addrspace_node, |
| 1868 | .bit_range_start = mods.bit_range_start, | 1806 | .bit_range_start = mods.bit_range_start.unwrap().?, |
| 1869 | .bit_range_end = mods.bit_range_end, | 1807 | .bit_range_end = mods.bit_range_end.unwrap().?, |
| 1870 | }), | 1808 | }), |
| 1871 | .rhs = elem_type, | 1809 | elem_type, |
| 1872 | }, | 1810 | } }, |
| 1873 | }); | 1811 | }); |
| 1874 | } else if (mods.addrspace_node != 0) { | 1812 | } else if (mods.addrspace_node != .none) { |
| 1875 | break :inner try p.addNode(.{ | 1813 | break :inner try p.addNode(.{ |
| 1876 | .tag = .ptr_type, | 1814 | .tag = .ptr_type, |
| 1877 | .main_token = asterisk, | 1815 | .main_token = asterisk, |
| 1878 | .data = .{ | 1816 | .data = .{ .extra_and_node = .{ |
| 1879 | .lhs = try p.addExtra(Node.PtrType{ | 1817 | try p.addExtra(Node.PtrType{ |
| 1880 | .sentinel = 0, | 1818 | .sentinel = .none, |
| 1881 | .align_node = mods.align_node, | 1819 | .align_node = mods.align_node, |
| 1882 | .addrspace_node = mods.addrspace_node, | 1820 | .addrspace_node = mods.addrspace_node, |
| 1883 | }), | 1821 | }), |
| 1884 | .rhs = elem_type, | 1822 | elem_type, |
| 1885 | }, | 1823 | } }, |
| 1886 | }); | 1824 | }); |
| 1887 | } else { | 1825 | } else { |
| 1888 | break :inner try p.addNode(.{ | 1826 | break :inner try p.addNode(.{ |
| 1889 | .tag = .ptr_type_aligned, | 1827 | .tag = .ptr_type_aligned, |
| 1890 | .main_token = asterisk, | 1828 | .main_token = asterisk, |
| 1891 | .data = .{ | 1829 | .data = .{ .opt_node_and_node = .{ |
| 1892 | .lhs = mods.align_node, | 1830 | mods.align_node, |
| 1893 | .rhs = elem_type, | 1831 | elem_type, |
| 1894 | }, | 1832 | } }, |
| 1895 | }); | 1833 | }); |
| 1896 | } | 1834 | } |
| 1897 | }; | 1835 | }; |
| 1898 | return p.addNode(.{ | 1836 | return try p.addNode(.{ |
| 1899 | .tag = .ptr_type_aligned, | 1837 | .tag = .ptr_type_aligned, |
| 1900 | .main_token = asterisk, | 1838 | .main_token = asterisk, |
| 1901 | .data = .{ | 1839 | .data = .{ .opt_node_and_node = .{ |
| 1902 | .lhs = 0, | 1840 | .none, |
| 1903 | .rhs = inner, | 1841 | inner, |
| 1904 | }, | 1842 | } }, |
| 1905 | }); | 1843 | }); |
| 1906 | }, | 1844 | }, |
| 1907 | .l_bracket => switch (p.token_tags[p.tok_i + 1]) { | 1845 | .l_bracket => switch (p.tokenTag(p.tok_i + 1)) { |
| 1908 | .asterisk => { | 1846 | .asterisk => { |
| 1909 | const l_bracket = p.nextToken(); | 1847 | const l_bracket = p.nextToken(); |
| 1910 | _ = p.nextToken(); | 1848 | _ = p.nextToken(); |
| 1911 | var sentinel: Node.Index = 0; | 1849 | var sentinel: ?Node.Index = null; |
| 1912 | if (p.eatToken(.identifier)) |ident| { | 1850 | if (p.eatToken(.identifier)) |ident| { |
| 1913 | const ident_slice = p.source[p.token_starts[ident]..p.token_starts[ident + 1]]; | 1851 | const ident_slice = p.source[p.tokenStart(ident)..p.tokenStart(ident + 1)]; |
| 1914 | if (!std.mem.eql(u8, std.mem.trimRight(u8, ident_slice, &std.ascii.whitespace), "c")) { | 1852 | if (!std.mem.eql(u8, std.mem.trimRight(u8, ident_slice, &std.ascii.whitespace), "c")) { |
| 1915 | p.tok_i -= 1; | 1853 | p.tok_i -= 1; |
| 1916 | } | 1854 | } |
| ... | @@ -1920,107 +1858,107 @@ fn parseTypeExpr(p: *Parse) Error!Node.Index { | ... | @@ -1920,107 +1858,107 @@ fn parseTypeExpr(p: *Parse) Error!Node.Index { |
| 1920 | _ = try p.expectToken(.r_bracket); | 1858 | _ = try p.expectToken(.r_bracket); |
| 1921 | const mods = try p.parsePtrModifiers(); | 1859 | const mods = try p.parsePtrModifiers(); |
| 1922 | const elem_type = try p.expectTypeExpr(); | 1860 | const elem_type = try p.expectTypeExpr(); |
| 1923 | if (mods.bit_range_start == 0) { | 1861 | if (mods.bit_range_start == .none) { |
| 1924 | if (sentinel == 0 and mods.addrspace_node == 0) { | 1862 | if (sentinel == null and mods.addrspace_node == .none) { |
| 1925 | return p.addNode(.{ | 1863 | return try p.addNode(.{ |
| 1926 | .tag = .ptr_type_aligned, | 1864 | .tag = .ptr_type_aligned, |
| 1927 | .main_token = l_bracket, | 1865 | .main_token = l_bracket, |
| 1928 | .data = .{ | 1866 | .data = .{ .opt_node_and_node = .{ |
| 1929 | .lhs = mods.align_node, | 1867 | mods.align_node, |
| 1930 | .rhs = elem_type, | 1868 | elem_type, |
| 1931 | }, | 1869 | } }, |
| 1932 | }); | 1870 | }); |
| 1933 | } else if (mods.align_node == 0 and mods.addrspace_node == 0) { | 1871 | } else if (mods.align_node == .none and mods.addrspace_node == .none) { |
| 1934 | return p.addNode(.{ | 1872 | return try p.addNode(.{ |
| 1935 | .tag = .ptr_type_sentinel, | 1873 | .tag = .ptr_type_sentinel, |
| 1936 | .main_token = l_bracket, | 1874 | .main_token = l_bracket, |
| 1937 | .data = .{ | 1875 | .data = .{ .opt_node_and_node = .{ |
| 1938 | .lhs = sentinel, | 1876 | .fromOptional(sentinel), |
| 1939 | .rhs = elem_type, | 1877 | elem_type, |
| 1940 | }, | 1878 | } }, |
| 1941 | }); | 1879 | }); |
| 1942 | } else { | 1880 | } else { |
| 1943 | return p.addNode(.{ | 1881 | return try p.addNode(.{ |
| 1944 | .tag = .ptr_type, | 1882 | .tag = .ptr_type, |
| 1945 | .main_token = l_bracket, | 1883 | .main_token = l_bracket, |
| 1946 | .data = .{ | 1884 | .data = .{ .extra_and_node = .{ |
| 1947 | .lhs = try p.addExtra(Node.PtrType{ | 1885 | try p.addExtra(Node.PtrType{ |
| 1948 | .sentinel = sentinel, | 1886 | .sentinel = .fromOptional(sentinel), |
| 1949 | .align_node = mods.align_node, | 1887 | .align_node = mods.align_node, |
| 1950 | .addrspace_node = mods.addrspace_node, | 1888 | .addrspace_node = mods.addrspace_node, |
| 1951 | }), | 1889 | }), |
| 1952 | .rhs = elem_type, | 1890 | elem_type, |
| 1953 | }, | 1891 | } }, |
| 1954 | }); | 1892 | }); |
| 1955 | } | 1893 | } |
| 1956 | } else { | 1894 | } else { |
| 1957 | return p.addNode(.{ | 1895 | return try p.addNode(.{ |
| 1958 | .tag = .ptr_type_bit_range, | 1896 | .tag = .ptr_type_bit_range, |
| 1959 | .main_token = l_bracket, | 1897 | .main_token = l_bracket, |
| 1960 | .data = .{ | 1898 | .data = .{ .extra_and_node = .{ |
| 1961 | .lhs = try p.addExtra(Node.PtrTypeBitRange{ | 1899 | try p.addExtra(Node.PtrTypeBitRange{ |
| 1962 | .sentinel = sentinel, | 1900 | .sentinel = .fromOptional(sentinel), |
| 1963 | .align_node = mods.align_node, | 1901 | .align_node = mods.align_node.unwrap().?, |
| 1964 | .addrspace_node = mods.addrspace_node, | 1902 | .addrspace_node = mods.addrspace_node, |
| 1965 | .bit_range_start = mods.bit_range_start, | 1903 | .bit_range_start = mods.bit_range_start.unwrap().?, |
| 1966 | .bit_range_end = mods.bit_range_end, | 1904 | .bit_range_end = mods.bit_range_end.unwrap().?, |
| 1967 | }), | 1905 | }), |
| 1968 | .rhs = elem_type, | 1906 | elem_type, |
| 1969 | }, | 1907 | } }, |
| 1970 | }); | 1908 | }); |
| 1971 | } | 1909 | } |
| 1972 | }, | 1910 | }, |
| 1973 | else => { | 1911 | else => { |
| 1974 | const lbracket = p.nextToken(); | 1912 | const lbracket = p.nextToken(); |
| 1975 | const len_expr = try p.parseExpr(); | 1913 | const len_expr = try p.parseExpr(); |
| 1976 | const sentinel: Node.Index = if (p.eatToken(.colon)) |_| | 1914 | const sentinel: ?Node.Index = if (p.eatToken(.colon)) |_| |
| 1977 | try p.expectExpr() | 1915 | try p.expectExpr() |
| 1978 | else | 1916 | else |
| 1979 | 0; | 1917 | null; |
| 1980 | _ = try p.expectToken(.r_bracket); | 1918 | _ = try p.expectToken(.r_bracket); |
| 1981 | if (len_expr == 0) { | 1919 | if (len_expr == null) { |
| 1982 | const mods = try p.parsePtrModifiers(); | 1920 | const mods = try p.parsePtrModifiers(); |
| 1983 | const elem_type = try p.expectTypeExpr(); | 1921 | const elem_type = try p.expectTypeExpr(); |
| 1984 | if (mods.bit_range_start != 0) { | 1922 | if (mods.bit_range_start.unwrap()) |bit_range_start| { |
| 1985 | try p.warnMsg(.{ | 1923 | try p.warnMsg(.{ |
| 1986 | .tag = .invalid_bit_range, | 1924 | .tag = .invalid_bit_range, |
| 1987 | .token = p.nodes.items(.main_token)[mods.bit_range_start], | 1925 | .token = p.nodeMainToken(bit_range_start), |
| 1988 | }); | 1926 | }); |
| 1989 | } | 1927 | } |
| 1990 | if (sentinel == 0 and mods.addrspace_node == 0) { | 1928 | if (sentinel == null and mods.addrspace_node == .none) { |
| 1991 | return p.addNode(.{ | 1929 | return try p.addNode(.{ |
| 1992 | .tag = .ptr_type_aligned, | 1930 | .tag = .ptr_type_aligned, |
| 1993 | .main_token = lbracket, | 1931 | .main_token = lbracket, |
| 1994 | .data = .{ | 1932 | .data = .{ .opt_node_and_node = .{ |
| 1995 | .lhs = mods.align_node, | 1933 | mods.align_node, |
| 1996 | .rhs = elem_type, | 1934 | elem_type, |
| 1997 | }, | 1935 | } }, |
| 1998 | }); | 1936 | }); |
| 1999 | } else if (mods.align_node == 0 and mods.addrspace_node == 0) { | 1937 | } else if (mods.align_node == .none and mods.addrspace_node == .none) { |
| 2000 | return p.addNode(.{ | 1938 | return try p.addNode(.{ |
| 2001 | .tag = .ptr_type_sentinel, | 1939 | .tag = .ptr_type_sentinel, |
| 2002 | .main_token = lbracket, | 1940 | .main_token = lbracket, |
| 2003 | .data = .{ | 1941 | .data = .{ .opt_node_and_node = .{ |
| 2004 | .lhs = sentinel, | 1942 | .fromOptional(sentinel), |
| 2005 | .rhs = elem_type, | 1943 | elem_type, |
| 2006 | }, | 1944 | } }, |
| 2007 | }); | 1945 | }); |
| 2008 | } else { | 1946 | } else { |
| 2009 | return p.addNode(.{ | 1947 | return try p.addNode(.{ |
| 2010 | .tag = .ptr_type, | 1948 | .tag = .ptr_type, |
| 2011 | .main_token = lbracket, | 1949 | .main_token = lbracket, |
| 2012 | .data = .{ | 1950 | .data = .{ .extra_and_node = .{ |
| 2013 | .lhs = try p.addExtra(Node.PtrType{ | 1951 | try p.addExtra(Node.PtrType{ |
| 2014 | .sentinel = sentinel, | 1952 | .sentinel = .fromOptional(sentinel), |
| 2015 | .align_node = mods.align_node, | 1953 | .align_node = mods.align_node, |
| 2016 | .addrspace_node = mods.addrspace_node, | 1954 | .addrspace_node = mods.addrspace_node, |
| 2017 | }), | 1955 | }), |
| 2018 | .rhs = elem_type, | 1956 | elem_type, |
| 2019 | }, | 1957 | } }, |
| 2020 | }); | 1958 | }); |
| 2021 | } | 1959 | } |
| 2022 | } else { | 1960 | } else { |
| 2023 | switch (p.token_tags[p.tok_i]) { | 1961 | switch (p.tokenTag(p.tok_i)) { |
| 2024 | .keyword_align, | 1962 | .keyword_align, |
| 2025 | .keyword_const, | 1963 | .keyword_const, |
| 2026 | .keyword_volatile, | 1964 | .keyword_volatile, |
| ... | @@ -2030,26 +1968,25 @@ fn parseTypeExpr(p: *Parse) Error!Node.Index { | ... | @@ -2030,26 +1968,25 @@ fn parseTypeExpr(p: *Parse) Error!Node.Index { |
| 2030 | else => {}, | 1968 | else => {}, |
| 2031 | } | 1969 | } |
| 2032 | const elem_type = try p.expectTypeExpr(); | 1970 | const elem_type = try p.expectTypeExpr(); |
| 2033 | if (sentinel == 0) { | 1971 | if (sentinel == null) { |
| 2034 | return p.addNode(.{ | 1972 | return try p.addNode(.{ |
| 2035 | .tag = .array_type, | 1973 | .tag = .array_type, |
| 2036 | .main_token = lbracket, | 1974 | .main_token = lbracket, |
| 2037 | .data = .{ | 1975 | .data = .{ .node_and_node = .{ |
| 2038 | .lhs = len_expr, | 1976 | len_expr.?, |
| 2039 | .rhs = elem_type, | 1977 | elem_type, |
| 2040 | }, | 1978 | } }, |
| 2041 | }); | 1979 | }); |
| 2042 | } else { | 1980 | } else { |
| 2043 | return p.addNode(.{ | 1981 | return try p.addNode(.{ |
| 2044 | .tag = .array_type_sentinel, | 1982 | .tag = .array_type_sentinel, |
| 2045 | .main_token = lbracket, | 1983 | .main_token = lbracket, |
| 2046 | .data = .{ | 1984 | .data = .{ .node_and_extra = .{ |
| 2047 | .lhs = len_expr, | 1985 | len_expr.?, try p.addExtra(Node.ArrayTypeSentinel{ |
| 2048 | .rhs = try p.addExtra(Node.ArrayTypeSentinel{ | 1986 | .sentinel = sentinel.?, |
| 2049 | .sentinel = sentinel, | ||
| 2050 | .elem_type = elem_type, | 1987 | .elem_type = elem_type, |
| 2051 | }), | 1988 | }), |
| 2052 | }, | 1989 | } }, |
| 2053 | }); | 1990 | }); |
| 2054 | } | 1991 | } |
| 2055 | } | 1992 | } |
| ... | @@ -2060,11 +1997,7 @@ fn parseTypeExpr(p: *Parse) Error!Node.Index { | ... | @@ -2060,11 +1997,7 @@ fn parseTypeExpr(p: *Parse) Error!Node.Index { |
| 2060 | } | 1997 | } |
| 2061 | 1998 | ||
| 2062 | fn expectTypeExpr(p: *Parse) Error!Node.Index { | 1999 | fn expectTypeExpr(p: *Parse) Error!Node.Index { |
| 2063 | const node = try p.parseTypeExpr(); | 2000 | return try p.parseTypeExpr() orelse return p.fail(.expected_type_expr); |
| 2064 | if (node == 0) { | ||
| 2065 | return p.fail(.expected_type_expr); | ||
| 2066 | } | ||
| 2067 | return node; | ||
| 2068 | } | 2001 | } |
| 2069 | 2002 | ||
| 2070 | /// PrimaryExpr | 2003 | /// PrimaryExpr |
| ... | @@ -2079,169 +2012,135 @@ fn expectTypeExpr(p: *Parse) Error!Node.Index { | ... | @@ -2079,169 +2012,135 @@ fn expectTypeExpr(p: *Parse) Error!Node.Index { |
| 2079 | /// / BlockLabel? LoopExpr | 2012 | /// / BlockLabel? LoopExpr |
| 2080 | /// / Block | 2013 | /// / Block |
| 2081 | /// / CurlySuffixExpr | 2014 | /// / CurlySuffixExpr |
| 2082 | fn parsePrimaryExpr(p: *Parse) !Node.Index { | 2015 | fn parsePrimaryExpr(p: *Parse) !?Node.Index { |
| 2083 | switch (p.token_tags[p.tok_i]) { | 2016 | switch (p.tokenTag(p.tok_i)) { |
| 2084 | .keyword_asm => return p.expectAsmExpr(), | 2017 | .keyword_asm => return try p.expectAsmExpr(), |
| 2085 | .keyword_if => return p.parseIfExpr(), | 2018 | .keyword_if => return try p.parseIfExpr(), |
| 2086 | .keyword_break => { | 2019 | .keyword_break => { |
| 2087 | return p.addNode(.{ | 2020 | return try p.addNode(.{ |
| 2088 | .tag = .@"break", | 2021 | .tag = .@"break", |
| 2089 | .main_token = p.nextToken(), | 2022 | .main_token = p.nextToken(), |
| 2090 | .data = .{ | 2023 | .data = .{ .opt_token_and_opt_node = .{ |
| 2091 | .lhs = try p.parseBreakLabel(), | 2024 | try p.parseBreakLabel(), |
| 2092 | .rhs = try p.parseExpr(), | 2025 | .fromOptional(try p.parseExpr()), |
| 2093 | }, | 2026 | } }, |
| 2094 | }); | 2027 | }); |
| 2095 | }, | 2028 | }, |
| 2096 | .keyword_continue => { | 2029 | .keyword_continue => { |
| 2097 | return p.addNode(.{ | 2030 | return try p.addNode(.{ |
| 2098 | .tag = .@"continue", | 2031 | .tag = .@"continue", |
| 2099 | .main_token = p.nextToken(), | 2032 | .main_token = p.nextToken(), |
| 2100 | .data = .{ | 2033 | .data = .{ .opt_token_and_opt_node = .{ |
| 2101 | .lhs = try p.parseBreakLabel(), | 2034 | try p.parseBreakLabel(), |
| 2102 | .rhs = try p.parseExpr(), | 2035 | .fromOptional(try p.parseExpr()), |
| 2103 | }, | 2036 | } }, |
| 2104 | }); | 2037 | }); |
| 2105 | }, | 2038 | }, |
| 2106 | .keyword_comptime => { | 2039 | .keyword_comptime => { |
| 2107 | return p.addNode(.{ | 2040 | return try p.addNode(.{ |
| 2108 | .tag = .@"comptime", | 2041 | .tag = .@"comptime", |
| 2109 | .main_token = p.nextToken(), | 2042 | .main_token = p.nextToken(), |
| 2110 | .data = .{ | 2043 | .data = .{ .node = try p.expectExpr() }, |
| 2111 | .lhs = try p.expectExpr(), | ||
| 2112 | .rhs = undefined, | ||
| 2113 | }, | ||
| 2114 | }); | 2044 | }); |
| 2115 | }, | 2045 | }, |
| 2116 | .keyword_nosuspend => { | 2046 | .keyword_nosuspend => { |
| 2117 | return p.addNode(.{ | 2047 | return try p.addNode(.{ |
| 2118 | .tag = .@"nosuspend", | 2048 | .tag = .@"nosuspend", |
| 2119 | .main_token = p.nextToken(), | 2049 | .main_token = p.nextToken(), |
| 2120 | .data = .{ | 2050 | .data = .{ .node = try p.expectExpr() }, |
| 2121 | .lhs = try p.expectExpr(), | ||
| 2122 | .rhs = undefined, | ||
| 2123 | }, | ||
| 2124 | }); | 2051 | }); |
| 2125 | }, | 2052 | }, |
| 2126 | .keyword_resume => { | 2053 | .keyword_resume => { |
| 2127 | return p.addNode(.{ | 2054 | return try p.addNode(.{ |
| 2128 | .tag = .@"resume", | 2055 | .tag = .@"resume", |
| 2129 | .main_token = p.nextToken(), | 2056 | .main_token = p.nextToken(), |
| 2130 | .data = .{ | 2057 | .data = .{ .node = try p.expectExpr() }, |
| 2131 | .lhs = try p.expectExpr(), | ||
| 2132 | .rhs = undefined, | ||
| 2133 | }, | ||
| 2134 | }); | 2058 | }); |
| 2135 | }, | 2059 | }, |
| 2136 | .keyword_return => { | 2060 | .keyword_return => { |
| 2137 | return p.addNode(.{ | 2061 | return try p.addNode(.{ |
| 2138 | .tag = .@"return", | 2062 | .tag = .@"return", |
| 2139 | .main_token = p.nextToken(), | 2063 | .main_token = p.nextToken(), |
| 2140 | .data = .{ | 2064 | .data = .{ .opt_node = .fromOptional(try p.parseExpr()) }, |
| 2141 | .lhs = try p.parseExpr(), | ||
| 2142 | .rhs = undefined, | ||
| 2143 | }, | ||
| 2144 | }); | 2065 | }); |
| 2145 | }, | 2066 | }, |
| 2146 | .identifier => { | 2067 | .identifier => { |
| 2147 | if (p.token_tags[p.tok_i + 1] == .colon) { | 2068 | if (p.tokenTag(p.tok_i + 1) == .colon) { |
| 2148 | switch (p.token_tags[p.tok_i + 2]) { | 2069 | switch (p.tokenTag(p.tok_i + 2)) { |
| 2149 | .keyword_inline => { | 2070 | .keyword_inline => { |
| 2150 | p.tok_i += 3; | 2071 | p.tok_i += 3; |
| 2151 | switch (p.token_tags[p.tok_i]) { | 2072 | switch (p.tokenTag(p.tok_i)) { |
| 2152 | .keyword_for => return p.parseFor(expectExpr), | 2073 | .keyword_for => return try p.parseFor(expectExpr), |
| 2153 | .keyword_while => return p.parseWhileExpr(), | 2074 | .keyword_while => return try p.parseWhileExpr(), |
| 2154 | else => return p.fail(.expected_inlinable), | 2075 | else => return p.fail(.expected_inlinable), |
| 2155 | } | 2076 | } |
| 2156 | }, | 2077 | }, |
| 2157 | .keyword_for => { | 2078 | .keyword_for => { |
| 2158 | p.tok_i += 2; | 2079 | p.tok_i += 2; |
| 2159 | return p.parseFor(expectExpr); | 2080 | return try p.parseFor(expectExpr); |
| 2160 | }, | 2081 | }, |
| 2161 | .keyword_while => { | 2082 | .keyword_while => { |
| 2162 | p.tok_i += 2; | 2083 | p.tok_i += 2; |
| 2163 | return p.parseWhileExpr(); | 2084 | return try p.parseWhileExpr(); |
| 2164 | }, | 2085 | }, |
| 2165 | .l_brace => { | 2086 | .l_brace => { |
| 2166 | p.tok_i += 2; | 2087 | p.tok_i += 2; |
| 2167 | return p.parseBlock(); | 2088 | return try p.parseBlock(); |
| 2168 | }, | 2089 | }, |
| 2169 | else => return p.parseCurlySuffixExpr(), | 2090 | else => return try p.parseCurlySuffixExpr(), |
| 2170 | } | 2091 | } |
| 2171 | } else { | 2092 | } else { |
| 2172 | return p.parseCurlySuffixExpr(); | 2093 | return try p.parseCurlySuffixExpr(); |
| 2173 | } | 2094 | } |
| 2174 | }, | 2095 | }, |
| 2175 | .keyword_inline => { | 2096 | .keyword_inline => { |
| 2176 | p.tok_i += 1; | 2097 | p.tok_i += 1; |
| 2177 | switch (p.token_tags[p.tok_i]) { | 2098 | switch (p.tokenTag(p.tok_i)) { |
| 2178 | .keyword_for => return p.parseFor(expectExpr), | 2099 | .keyword_for => return try p.parseFor(expectExpr), |
| 2179 | .keyword_while => return p.parseWhileExpr(), | 2100 | .keyword_while => return try p.parseWhileExpr(), |
| 2180 | else => return p.fail(.expected_inlinable), | 2101 | else => return p.fail(.expected_inlinable), |
| 2181 | } | 2102 | } |
| 2182 | }, | 2103 | }, |
| 2183 | .keyword_for => return p.parseFor(expectExpr), | 2104 | .keyword_for => return try p.parseFor(expectExpr), |
| 2184 | .keyword_while => return p.parseWhileExpr(), | 2105 | .keyword_while => return try p.parseWhileExpr(), |
| 2185 | .l_brace => return p.parseBlock(), | 2106 | .l_brace => return try p.parseBlock(), |
| 2186 | else => return p.parseCurlySuffixExpr(), | 2107 | else => return try p.parseCurlySuffixExpr(), |
| 2187 | } | 2108 | } |
| 2188 | } | 2109 | } |
| 2189 | 2110 | ||
| 2190 | /// IfExpr <- IfPrefix Expr (KEYWORD_else Payload? Expr)? | 2111 | /// IfExpr <- IfPrefix Expr (KEYWORD_else Payload? Expr)? |
| 2191 | fn parseIfExpr(p: *Parse) !Node.Index { | 2112 | fn parseIfExpr(p: *Parse) !?Node.Index { |
| 2192 | return p.parseIf(expectExpr); | 2113 | return try p.parseIf(expectExpr); |
| 2193 | } | 2114 | } |
| 2194 | 2115 | ||
| 2195 | /// Block <- LBRACE Statement* RBRACE | 2116 | /// Block <- LBRACE Statement* RBRACE |
| 2196 | fn parseBlock(p: *Parse) !Node.Index { | 2117 | fn parseBlock(p: *Parse) !?Node.Index { |
| 2197 | const lbrace = p.eatToken(.l_brace) orelse return null_node; | 2118 | const lbrace = p.eatToken(.l_brace) orelse return null; |
| 2198 | const scratch_top = p.scratch.items.len; | 2119 | const scratch_top = p.scratch.items.len; |
| 2199 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 2120 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2200 | while (true) { | 2121 | while (true) { |
| 2201 | if (p.token_tags[p.tok_i] == .r_brace) break; | 2122 | if (p.tokenTag(p.tok_i) == .r_brace) break; |
| 2202 | const statement = try p.expectStatementRecoverable(); | 2123 | const statement = try p.expectStatementRecoverable() orelse break; |
| 2203 | if (statement == 0) break; | ||
| 2204 | try p.scratch.append(p.gpa, statement); | 2124 | try p.scratch.append(p.gpa, statement); |
| 2205 | } | 2125 | } |
| 2206 | _ = try p.expectToken(.r_brace); | 2126 | _ = try p.expectToken(.r_brace); |
| 2207 | const semicolon = (p.token_tags[p.tok_i - 2] == .semicolon); | ||
| 2208 | const statements = p.scratch.items[scratch_top..]; | 2127 | const statements = p.scratch.items[scratch_top..]; |
| 2209 | switch (statements.len) { | 2128 | const semicolon = statements.len != 0 and (p.tokenTag(p.tok_i - 2)) == .semicolon; |
| 2210 | 0 => return p.addNode(.{ | 2129 | if (statements.len <= 2) { |
| 2211 | .tag = .block_two, | 2130 | return try p.addNode(.{ |
| 2212 | .main_token = lbrace, | ||
| 2213 | .data = .{ | ||
| 2214 | .lhs = 0, | ||
| 2215 | .rhs = 0, | ||
| 2216 | }, | ||
| 2217 | }), | ||
| 2218 | 1 => return p.addNode(.{ | ||
| 2219 | .tag = if (semicolon) .block_two_semicolon else .block_two, | 2131 | .tag = if (semicolon) .block_two_semicolon else .block_two, |
| 2220 | .main_token = lbrace, | 2132 | .main_token = lbrace, |
| 2221 | .data = .{ | 2133 | .data = .{ .opt_node_and_opt_node = .{ |
| 2222 | .lhs = statements[0], | 2134 | if (statements.len >= 1) statements[0].toOptional() else .none, |
| 2223 | .rhs = 0, | 2135 | if (statements.len >= 2) statements[1].toOptional() else .none, |
| 2224 | }, | 2136 | } }, |
| 2225 | }), | 2137 | }); |
| 2226 | 2 => return p.addNode(.{ | 2138 | } else { |
| 2227 | .tag = if (semicolon) .block_two_semicolon else .block_two, | 2139 | return try p.addNode(.{ |
| 2140 | .tag = if (semicolon) .block_semicolon else .block, | ||
| 2228 | .main_token = lbrace, | 2141 | .main_token = lbrace, |
| 2229 | .data = .{ | 2142 | .data = .{ .extra_range = try p.listToSpan(statements) }, |
| 2230 | .lhs = statements[0], | 2143 | }); |
| 2231 | .rhs = statements[1], | ||
| 2232 | }, | ||
| 2233 | }), | ||
| 2234 | else => { | ||
| 2235 | const span = try p.listToSpan(statements); | ||
| 2236 | return p.addNode(.{ | ||
| 2237 | .tag = if (semicolon) .block_semicolon else .block, | ||
| 2238 | .main_token = lbrace, | ||
| 2239 | .data = .{ | ||
| 2240 | .lhs = span.start, | ||
| 2241 | .rhs = span.end, | ||
| 2242 | }, | ||
| 2243 | }); | ||
| 2244 | }, | ||
| 2245 | } | 2144 | } |
| 2246 | } | 2145 | } |
| 2247 | 2146 | ||
| ... | @@ -2260,15 +2159,15 @@ fn forPrefix(p: *Parse) Error!usize { | ... | @@ -2260,15 +2159,15 @@ fn forPrefix(p: *Parse) Error!usize { |
| 2260 | input = try p.addNode(.{ | 2159 | input = try p.addNode(.{ |
| 2261 | .tag = .for_range, | 2160 | .tag = .for_range, |
| 2262 | .main_token = ellipsis, | 2161 | .main_token = ellipsis, |
| 2263 | .data = .{ | 2162 | .data = .{ .node_and_opt_node = .{ |
| 2264 | .lhs = input, | 2163 | input, |
| 2265 | .rhs = try p.parseExpr(), | 2164 | .fromOptional(try p.parseExpr()), |
| 2266 | }, | 2165 | } }, |
| 2267 | }); | 2166 | }); |
| 2268 | } | 2167 | } |
| 2269 | 2168 | ||
| 2270 | try p.scratch.append(p.gpa, input); | 2169 | try p.scratch.append(p.gpa, input); |
| 2271 | switch (p.token_tags[p.tok_i]) { | 2170 | switch (p.tokenTag(p.tok_i)) { |
| 2272 | .comma => p.tok_i += 1, | 2171 | .comma => p.tok_i += 1, |
| 2273 | .r_paren => { | 2172 | .r_paren => { |
| 2274 | p.tok_i += 1; | 2173 | p.tok_i += 1; |
| ... | @@ -2297,7 +2196,7 @@ fn forPrefix(p: *Parse) Error!usize { | ... | @@ -2297,7 +2196,7 @@ fn forPrefix(p: *Parse) Error!usize { |
| 2297 | try p.warnMsg(.{ .tag = .extra_for_capture, .token = identifier }); | 2196 | try p.warnMsg(.{ .tag = .extra_for_capture, .token = identifier }); |
| 2298 | warned_excess = true; | 2197 | warned_excess = true; |
| 2299 | } | 2198 | } |
| 2300 | switch (p.token_tags[p.tok_i]) { | 2199 | switch (p.tokenTag(p.tok_i)) { |
| 2301 | .comma => p.tok_i += 1, | 2200 | .comma => p.tok_i += 1, |
| 2302 | .pipe => { | 2201 | .pipe => { |
| 2303 | p.tok_i += 1; | 2202 | p.tok_i += 1; |
| ... | @@ -2311,7 +2210,7 @@ fn forPrefix(p: *Parse) Error!usize { | ... | @@ -2311,7 +2210,7 @@ fn forPrefix(p: *Parse) Error!usize { |
| 2311 | 2210 | ||
| 2312 | if (captures < inputs) { | 2211 | if (captures < inputs) { |
| 2313 | const index = p.scratch.items.len - captures; | 2212 | const index = p.scratch.items.len - captures; |
| 2314 | const input = p.nodes.items(.main_token)[p.scratch.items[index]]; | 2213 | const input = p.nodeMainToken(p.scratch.items[index]); |
| 2315 | try p.warnMsg(.{ .tag = .for_input_not_captured, .token = input }); | 2214 | try p.warnMsg(.{ .tag = .for_input_not_captured, .token = input }); |
| 2316 | } | 2215 | } |
| 2317 | return inputs; | 2216 | return inputs; |
| ... | @@ -2320,8 +2219,8 @@ fn forPrefix(p: *Parse) Error!usize { | ... | @@ -2320,8 +2219,8 @@ fn forPrefix(p: *Parse) Error!usize { |
| 2320 | /// WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr? | 2219 | /// WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr? |
| 2321 | /// | 2220 | /// |
| 2322 | /// WhileExpr <- WhilePrefix Expr (KEYWORD_else Payload? Expr)? | 2221 | /// WhileExpr <- WhilePrefix Expr (KEYWORD_else Payload? Expr)? |
| 2323 | fn parseWhileExpr(p: *Parse) !Node.Index { | 2222 | fn parseWhileExpr(p: *Parse) !?Node.Index { |
| 2324 | const while_token = p.eatToken(.keyword_while) orelse return null_node; | 2223 | const while_token = p.eatToken(.keyword_while) orelse return null; |
| 2325 | _ = try p.expectToken(.l_paren); | 2224 | _ = try p.expectToken(.l_paren); |
| 2326 | const condition = try p.expectExpr(); | 2225 | const condition = try p.expectExpr(); |
| 2327 | _ = try p.expectToken(.r_paren); | 2226 | _ = try p.expectToken(.r_paren); |
| ... | @@ -2330,42 +2229,42 @@ fn parseWhileExpr(p: *Parse) !Node.Index { | ... | @@ -2330,42 +2229,42 @@ fn parseWhileExpr(p: *Parse) !Node.Index { |
| 2330 | 2229 | ||
| 2331 | const then_expr = try p.expectExpr(); | 2230 | const then_expr = try p.expectExpr(); |
| 2332 | _ = p.eatToken(.keyword_else) orelse { | 2231 | _ = p.eatToken(.keyword_else) orelse { |
| 2333 | if (cont_expr == 0) { | 2232 | if (cont_expr == null) { |
| 2334 | return p.addNode(.{ | 2233 | return try p.addNode(.{ |
| 2335 | .tag = .while_simple, | 2234 | .tag = .while_simple, |
| 2336 | .main_token = while_token, | 2235 | .main_token = while_token, |
| 2337 | .data = .{ | 2236 | .data = .{ .node_and_node = .{ |
| 2338 | .lhs = condition, | 2237 | condition, |
| 2339 | .rhs = then_expr, | 2238 | then_expr, |
| 2340 | }, | 2239 | } }, |
| 2341 | }); | 2240 | }); |
| 2342 | } else { | 2241 | } else { |
| 2343 | return p.addNode(.{ | 2242 | return try p.addNode(.{ |
| 2344 | .tag = .while_cont, | 2243 | .tag = .while_cont, |
| 2345 | .main_token = while_token, | 2244 | .main_token = while_token, |
| 2346 | .data = .{ | 2245 | .data = .{ .node_and_extra = .{ |
| 2347 | .lhs = condition, | 2246 | condition, |
| 2348 | .rhs = try p.addExtra(Node.WhileCont{ | 2247 | try p.addExtra(Node.WhileCont{ |
| 2349 | .cont_expr = cont_expr, | 2248 | .cont_expr = cont_expr.?, |
| 2350 | .then_expr = then_expr, | 2249 | .then_expr = then_expr, |
| 2351 | }), | 2250 | }), |
| 2352 | }, | 2251 | } }, |
| 2353 | }); | 2252 | }); |
| 2354 | } | 2253 | } |
| 2355 | }; | 2254 | }; |
| 2356 | _ = try p.parsePayload(); | 2255 | _ = try p.parsePayload(); |
| 2357 | const else_expr = try p.expectExpr(); | 2256 | const else_expr = try p.expectExpr(); |
| 2358 | return p.addNode(.{ | 2257 | return try p.addNode(.{ |
| 2359 | .tag = .@"while", | 2258 | .tag = .@"while", |
| 2360 | .main_token = while_token, | 2259 | .main_token = while_token, |
| 2361 | .data = .{ | 2260 | .data = .{ .node_and_extra = .{ |
| 2362 | .lhs = condition, | 2261 | condition, |
| 2363 | .rhs = try p.addExtra(Node.While{ | 2262 | try p.addExtra(Node.While{ |
| 2364 | .cont_expr = cont_expr, | 2263 | .cont_expr = .fromOptional(cont_expr), |
| 2365 | .then_expr = then_expr, | 2264 | .then_expr = then_expr, |
| 2366 | .else_expr = else_expr, | 2265 | .else_expr = else_expr, |
| 2367 | }), | 2266 | }), |
| 2368 | }, | 2267 | } }, |
| 2369 | }); | 2268 | }); |
| 2370 | } | 2269 | } |
| 2371 | 2270 | ||
| ... | @@ -2375,9 +2274,8 @@ fn parseWhileExpr(p: *Parse) !Node.Index { | ... | @@ -2375,9 +2274,8 @@ fn parseWhileExpr(p: *Parse) !Node.Index { |
| 2375 | /// <- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE | 2274 | /// <- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE |
| 2376 | /// / LBRACE Expr (COMMA Expr)* COMMA? RBRACE | 2275 | /// / LBRACE Expr (COMMA Expr)* COMMA? RBRACE |
| 2377 | /// / LBRACE RBRACE | 2276 | /// / LBRACE RBRACE |
| 2378 | fn parseCurlySuffixExpr(p: *Parse) !Node.Index { | 2277 | fn parseCurlySuffixExpr(p: *Parse) !?Node.Index { |
| 2379 | const lhs = try p.parseTypeExpr(); | 2278 | const lhs = try p.parseTypeExpr() orelse return null; |
| 2380 | if (lhs == 0) return null_node; | ||
| 2381 | const lbrace = p.eatToken(.l_brace) orelse return lhs; | 2279 | const lbrace = p.eatToken(.l_brace) orelse return lhs; |
| 2382 | 2280 | ||
| 2383 | // If there are 0 or 1 items, we can use ArrayInitOne/StructInitOne; | 2281 | // If there are 0 or 1 items, we can use ArrayInitOne/StructInitOne; |
| ... | @@ -2385,11 +2283,11 @@ fn parseCurlySuffixExpr(p: *Parse) !Node.Index { | ... | @@ -2385,11 +2283,11 @@ fn parseCurlySuffixExpr(p: *Parse) !Node.Index { |
| 2385 | 2283 | ||
| 2386 | const scratch_top = p.scratch.items.len; | 2284 | const scratch_top = p.scratch.items.len; |
| 2387 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 2285 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2388 | const field_init = try p.parseFieldInit(); | 2286 | const opt_field_init = try p.parseFieldInit(); |
| 2389 | if (field_init != 0) { | 2287 | if (opt_field_init) |field_init| { |
| 2390 | try p.scratch.append(p.gpa, field_init); | 2288 | try p.scratch.append(p.gpa, field_init); |
| 2391 | while (true) { | 2289 | while (true) { |
| 2392 | switch (p.token_tags[p.tok_i]) { | 2290 | switch (p.tokenTag(p.tok_i)) { |
| 2393 | .comma => p.tok_i += 1, | 2291 | .comma => p.tok_i += 1, |
| 2394 | .r_brace => { | 2292 | .r_brace => { |
| 2395 | p.tok_i += 1; | 2293 | p.tok_i += 1; |
| ... | @@ -2403,26 +2301,27 @@ fn parseCurlySuffixExpr(p: *Parse) !Node.Index { | ... | @@ -2403,26 +2301,27 @@ fn parseCurlySuffixExpr(p: *Parse) !Node.Index { |
| 2403 | const next = try p.expectFieldInit(); | 2301 | const next = try p.expectFieldInit(); |
| 2404 | try p.scratch.append(p.gpa, next); | 2302 | try p.scratch.append(p.gpa, next); |
| 2405 | } | 2303 | } |
| 2406 | const comma = (p.token_tags[p.tok_i - 2] == .comma); | 2304 | const comma = (p.tokenTag(p.tok_i - 2)) == .comma; |
| 2407 | const inits = p.scratch.items[scratch_top..]; | 2305 | const inits = p.scratch.items[scratch_top..]; |
| 2408 | switch (inits.len) { | 2306 | std.debug.assert(inits.len != 0); |
| 2409 | 0 => unreachable, | 2307 | if (inits.len <= 1) { |
| 2410 | 1 => return p.addNode(.{ | 2308 | return try p.addNode(.{ |
| 2411 | .tag = if (comma) .struct_init_one_comma else .struct_init_one, | 2309 | .tag = if (comma) .struct_init_one_comma else .struct_init_one, |
| 2412 | .main_token = lbrace, | 2310 | .main_token = lbrace, |
| 2413 | .data = .{ | 2311 | .data = .{ .node_and_opt_node = .{ |
| 2414 | .lhs = lhs, | 2312 | lhs, |
| 2415 | .rhs = inits[0], | 2313 | inits[0].toOptional(), |
| 2416 | }, | 2314 | } }, |
| 2417 | }), | 2315 | }); |
| 2418 | else => return p.addNode(.{ | 2316 | } else { |
| 2317 | return try p.addNode(.{ | ||
| 2419 | .tag = if (comma) .struct_init_comma else .struct_init, | 2318 | .tag = if (comma) .struct_init_comma else .struct_init, |
| 2420 | .main_token = lbrace, | 2319 | .main_token = lbrace, |
| 2421 | .data = .{ | 2320 | .data = .{ .node_and_extra = .{ |
| 2422 | .lhs = lhs, | 2321 | lhs, |
| 2423 | .rhs = try p.addExtra(try p.listToSpan(inits)), | 2322 | try p.addExtra(try p.listToSpan(inits)), |
| 2424 | }, | 2323 | } }, |
| 2425 | }), | 2324 | }); |
| 2426 | } | 2325 | } |
| 2427 | } | 2326 | } |
| 2428 | 2327 | ||
| ... | @@ -2430,7 +2329,7 @@ fn parseCurlySuffixExpr(p: *Parse) !Node.Index { | ... | @@ -2430,7 +2329,7 @@ fn parseCurlySuffixExpr(p: *Parse) !Node.Index { |
| 2430 | if (p.eatToken(.r_brace)) |_| break; | 2329 | if (p.eatToken(.r_brace)) |_| break; |
| 2431 | const elem_init = try p.expectExpr(); | 2330 | const elem_init = try p.expectExpr(); |
| 2432 | try p.scratch.append(p.gpa, elem_init); | 2331 | try p.scratch.append(p.gpa, elem_init); |
| 2433 | switch (p.token_tags[p.tok_i]) { | 2332 | switch (p.tokenTag(p.tok_i)) { |
| 2434 | .comma => p.tok_i += 1, | 2333 | .comma => p.tok_i += 1, |
| 2435 | .r_brace => { | 2334 | .r_brace => { |
| 2436 | p.tok_i += 1; | 2335 | p.tok_i += 1; |
| ... | @@ -2441,48 +2340,47 @@ fn parseCurlySuffixExpr(p: *Parse) !Node.Index { | ... | @@ -2441,48 +2340,47 @@ fn parseCurlySuffixExpr(p: *Parse) !Node.Index { |
| 2441 | else => try p.warn(.expected_comma_after_initializer), | 2340 | else => try p.warn(.expected_comma_after_initializer), |
| 2442 | } | 2341 | } |
| 2443 | } | 2342 | } |
| 2444 | const comma = (p.token_tags[p.tok_i - 2] == .comma); | 2343 | const comma = (p.tokenTag(p.tok_i - 2)) == .comma; |
| 2445 | const inits = p.scratch.items[scratch_top..]; | 2344 | const inits = p.scratch.items[scratch_top..]; |
| 2446 | switch (inits.len) { | 2345 | switch (inits.len) { |
| 2447 | 0 => return p.addNode(.{ | 2346 | 0 => return try p.addNode(.{ |
| 2448 | .tag = .struct_init_one, | 2347 | .tag = .struct_init_one, |
| 2449 | .main_token = lbrace, | 2348 | .main_token = lbrace, |
| 2450 | .data = .{ | 2349 | .data = .{ .node_and_opt_node = .{ |
| 2451 | .lhs = lhs, | 2350 | lhs, |
| 2452 | .rhs = 0, | 2351 | .none, |
| 2453 | }, | 2352 | } }, |
| 2454 | }), | 2353 | }), |
| 2455 | 1 => return p.addNode(.{ | 2354 | 1 => return try p.addNode(.{ |
| 2456 | .tag = if (comma) .array_init_one_comma else .array_init_one, | 2355 | .tag = if (comma) .array_init_one_comma else .array_init_one, |
| 2457 | .main_token = lbrace, | 2356 | .main_token = lbrace, |
| 2458 | .data = .{ | 2357 | .data = .{ .node_and_node = .{ |
| 2459 | .lhs = lhs, | 2358 | lhs, |
| 2460 | .rhs = inits[0], | 2359 | inits[0], |
| 2461 | }, | 2360 | } }, |
| 2462 | }), | 2361 | }), |
| 2463 | else => return p.addNode(.{ | 2362 | else => return try p.addNode(.{ |
| 2464 | .tag = if (comma) .array_init_comma else .array_init, | 2363 | .tag = if (comma) .array_init_comma else .array_init, |
| 2465 | .main_token = lbrace, | 2364 | .main_token = lbrace, |
| 2466 | .data = .{ | 2365 | .data = .{ .node_and_extra = .{ |
| 2467 | .lhs = lhs, | 2366 | lhs, |
| 2468 | .rhs = try p.addExtra(try p.listToSpan(inits)), | 2367 | try p.addExtra(try p.listToSpan(inits)), |
| 2469 | }, | 2368 | } }, |
| 2470 | }), | 2369 | }), |
| 2471 | } | 2370 | } |
| 2472 | } | 2371 | } |
| 2473 | 2372 | ||
| 2474 | /// ErrorUnionExpr <- SuffixExpr (EXCLAMATIONMARK TypeExpr)? | 2373 | /// ErrorUnionExpr <- SuffixExpr (EXCLAMATIONMARK TypeExpr)? |
| 2475 | fn parseErrorUnionExpr(p: *Parse) !Node.Index { | 2374 | fn parseErrorUnionExpr(p: *Parse) !?Node.Index { |
| 2476 | const suffix_expr = try p.parseSuffixExpr(); | 2375 | const suffix_expr = try p.parseSuffixExpr() orelse return null; |
| 2477 | if (suffix_expr == 0) return null_node; | ||
| 2478 | const bang = p.eatToken(.bang) orelse return suffix_expr; | 2376 | const bang = p.eatToken(.bang) orelse return suffix_expr; |
| 2479 | return p.addNode(.{ | 2377 | return try p.addNode(.{ |
| 2480 | .tag = .error_union, | 2378 | .tag = .error_union, |
| 2481 | .main_token = bang, | 2379 | .main_token = bang, |
| 2482 | .data = .{ | 2380 | .data = .{ .node_and_node = .{ |
| 2483 | .lhs = suffix_expr, | 2381 | suffix_expr, |
| 2484 | .rhs = try p.expectTypeExpr(), | 2382 | try p.expectTypeExpr(), |
| 2485 | }, | 2383 | } }, |
| 2486 | }); | 2384 | }); |
| 2487 | } | 2385 | } |
| 2488 | 2386 | ||
| ... | @@ -2493,13 +2391,11 @@ fn parseErrorUnionExpr(p: *Parse) !Node.Index { | ... | @@ -2493,13 +2391,11 @@ fn parseErrorUnionExpr(p: *Parse) !Node.Index { |
| 2493 | /// FnCallArguments <- LPAREN ExprList RPAREN | 2391 | /// FnCallArguments <- LPAREN ExprList RPAREN |
| 2494 | /// | 2392 | /// |
| 2495 | /// ExprList <- (Expr COMMA)* Expr? | 2393 | /// ExprList <- (Expr COMMA)* Expr? |
| 2496 | fn parseSuffixExpr(p: *Parse) !Node.Index { | 2394 | fn parseSuffixExpr(p: *Parse) !?Node.Index { |
| 2497 | if (p.eatToken(.keyword_async)) |_| { | 2395 | if (p.eatToken(.keyword_async)) |_| { |
| 2498 | var res = try p.expectPrimaryTypeExpr(); | 2396 | var res = try p.expectPrimaryTypeExpr(); |
| 2499 | while (true) { | 2397 | while (true) { |
| 2500 | const node = try p.parseSuffixOp(res); | 2398 | res = try p.parseSuffixOp(res) orelse break; |
| 2501 | if (node == 0) break; | ||
| 2502 | res = node; | ||
| 2503 | } | 2399 | } |
| 2504 | const lparen = p.eatToken(.l_paren) orelse { | 2400 | const lparen = p.eatToken(.l_paren) orelse { |
| 2505 | try p.warn(.expected_param_list); | 2401 | try p.warn(.expected_param_list); |
| ... | @@ -2511,7 +2407,7 @@ fn parseSuffixExpr(p: *Parse) !Node.Index { | ... | @@ -2511,7 +2407,7 @@ fn parseSuffixExpr(p: *Parse) !Node.Index { |
| 2511 | if (p.eatToken(.r_paren)) |_| break; | 2407 | if (p.eatToken(.r_paren)) |_| break; |
| 2512 | const param = try p.expectExpr(); | 2408 | const param = try p.expectExpr(); |
| 2513 | try p.scratch.append(p.gpa, param); | 2409 | try p.scratch.append(p.gpa, param); |
| 2514 | switch (p.token_tags[p.tok_i]) { | 2410 | switch (p.tokenTag(p.tok_i)) { |
| 2515 | .comma => p.tok_i += 1, | 2411 | .comma => p.tok_i += 1, |
| 2516 | .r_paren => { | 2412 | .r_paren => { |
| 2517 | p.tok_i += 1; | 2413 | p.tok_i += 1; |
| ... | @@ -2522,41 +2418,33 @@ fn parseSuffixExpr(p: *Parse) !Node.Index { | ... | @@ -2522,41 +2418,33 @@ fn parseSuffixExpr(p: *Parse) !Node.Index { |
| 2522 | else => try p.warn(.expected_comma_after_arg), | 2418 | else => try p.warn(.expected_comma_after_arg), |
| 2523 | } | 2419 | } |
| 2524 | } | 2420 | } |
| 2525 | const comma = (p.token_tags[p.tok_i - 2] == .comma); | 2421 | const comma = (p.tokenTag(p.tok_i - 2)) == .comma; |
| 2526 | const params = p.scratch.items[scratch_top..]; | 2422 | const params = p.scratch.items[scratch_top..]; |
| 2527 | switch (params.len) { | 2423 | if (params.len <= 1) { |
| 2528 | 0 => return p.addNode(.{ | 2424 | return try p.addNode(.{ |
| 2529 | .tag = if (comma) .async_call_one_comma else .async_call_one, | 2425 | .tag = if (comma) .async_call_one_comma else .async_call_one, |
| 2530 | .main_token = lparen, | 2426 | .main_token = lparen, |
| 2531 | .data = .{ | 2427 | .data = .{ .node_and_opt_node = .{ |
| 2532 | .lhs = res, | 2428 | res, |
| 2533 | .rhs = 0, | 2429 | if (params.len >= 1) params[0].toOptional() else .none, |
| 2534 | }, | 2430 | } }, |
| 2535 | }), | 2431 | }); |
| 2536 | 1 => return p.addNode(.{ | 2432 | } else { |
| 2537 | .tag = if (comma) .async_call_one_comma else .async_call_one, | 2433 | return try p.addNode(.{ |
| 2538 | .main_token = lparen, | ||
| 2539 | .data = .{ | ||
| 2540 | .lhs = res, | ||
| 2541 | .rhs = params[0], | ||
| 2542 | }, | ||
| 2543 | }), | ||
| 2544 | else => return p.addNode(.{ | ||
| 2545 | .tag = if (comma) .async_call_comma else .async_call, | 2434 | .tag = if (comma) .async_call_comma else .async_call, |
| 2546 | .main_token = lparen, | 2435 | .main_token = lparen, |
| 2547 | .data = .{ | 2436 | .data = .{ .node_and_extra = .{ |
| 2548 | .lhs = res, | 2437 | res, |
| 2549 | .rhs = try p.addExtra(try p.listToSpan(params)), | 2438 | try p.addExtra(try p.listToSpan(params)), |
| 2550 | }, | 2439 | } }, |
| 2551 | }), | 2440 | }); |
| 2552 | } | 2441 | } |
| 2553 | } | 2442 | } |
| 2554 | 2443 | ||
| 2555 | var res = try p.parsePrimaryTypeExpr(); | 2444 | var res = try p.parsePrimaryTypeExpr() orelse return null; |
| 2556 | if (res == 0) return res; | ||
| 2557 | while (true) { | 2445 | while (true) { |
| 2558 | const suffix_op = try p.parseSuffixOp(res); | 2446 | const opt_suffix_op = try p.parseSuffixOp(res); |
| 2559 | if (suffix_op != 0) { | 2447 | if (opt_suffix_op) |suffix_op| { |
| 2560 | res = suffix_op; | 2448 | res = suffix_op; |
| 2561 | continue; | 2449 | continue; |
| 2562 | } | 2450 | } |
| ... | @@ -2567,7 +2455,7 @@ fn parseSuffixExpr(p: *Parse) !Node.Index { | ... | @@ -2567,7 +2455,7 @@ fn parseSuffixExpr(p: *Parse) !Node.Index { |
| 2567 | if (p.eatToken(.r_paren)) |_| break; | 2455 | if (p.eatToken(.r_paren)) |_| break; |
| 2568 | const param = try p.expectExpr(); | 2456 | const param = try p.expectExpr(); |
| 2569 | try p.scratch.append(p.gpa, param); | 2457 | try p.scratch.append(p.gpa, param); |
| 2570 | switch (p.token_tags[p.tok_i]) { | 2458 | switch (p.tokenTag(p.tok_i)) { |
| 2571 | .comma => p.tok_i += 1, | 2459 | .comma => p.tok_i += 1, |
| 2572 | .r_paren => { | 2460 | .r_paren => { |
| 2573 | p.tok_i += 1; | 2461 | p.tok_i += 1; |
| ... | @@ -2578,32 +2466,24 @@ fn parseSuffixExpr(p: *Parse) !Node.Index { | ... | @@ -2578,32 +2466,24 @@ fn parseSuffixExpr(p: *Parse) !Node.Index { |
| 2578 | else => try p.warn(.expected_comma_after_arg), | 2466 | else => try p.warn(.expected_comma_after_arg), |
| 2579 | } | 2467 | } |
| 2580 | } | 2468 | } |
| 2581 | const comma = (p.token_tags[p.tok_i - 2] == .comma); | 2469 | const comma = (p.tokenTag(p.tok_i - 2)) == .comma; |
| 2582 | const params = p.scratch.items[scratch_top..]; | 2470 | const params = p.scratch.items[scratch_top..]; |
| 2583 | res = switch (params.len) { | 2471 | res = switch (params.len) { |
| 2584 | 0 => try p.addNode(.{ | 2472 | 0, 1 => try p.addNode(.{ |
| 2585 | .tag = if (comma) .call_one_comma else .call_one, | 2473 | .tag = if (comma) .call_one_comma else .call_one, |
| 2586 | .main_token = lparen, | 2474 | .main_token = lparen, |
| 2587 | .data = .{ | 2475 | .data = .{ .node_and_opt_node = .{ |
| 2588 | .lhs = res, | 2476 | res, |
| 2589 | .rhs = 0, | 2477 | if (params.len >= 1) .fromOptional(params[0]) else .none, |
| 2590 | }, | 2478 | } }, |
| 2591 | }), | ||
| 2592 | 1 => try p.addNode(.{ | ||
| 2593 | .tag = if (comma) .call_one_comma else .call_one, | ||
| 2594 | .main_token = lparen, | ||
| 2595 | .data = .{ | ||
| 2596 | .lhs = res, | ||
| 2597 | .rhs = params[0], | ||
| 2598 | }, | ||
| 2599 | }), | 2479 | }), |
| 2600 | else => try p.addNode(.{ | 2480 | else => try p.addNode(.{ |
| 2601 | .tag = if (comma) .call_comma else .call, | 2481 | .tag = if (comma) .call_comma else .call, |
| 2602 | .main_token = lparen, | 2482 | .main_token = lparen, |
| 2603 | .data = .{ | 2483 | .data = .{ .node_and_extra = .{ |
| 2604 | .lhs = res, | 2484 | res, |
| 2605 | .rhs = try p.addExtra(try p.listToSpan(params)), | 2485 | try p.addExtra(try p.listToSpan(params)), |
| 2606 | }, | 2486 | } }, |
| 2607 | }), | 2487 | }), |
| 2608 | }; | 2488 | }; |
| 2609 | } | 2489 | } |
| ... | @@ -2650,153 +2530,126 @@ fn parseSuffixExpr(p: *Parse) !Node.Index { | ... | @@ -2650,153 +2530,126 @@ fn parseSuffixExpr(p: *Parse) !Node.Index { |
| 2650 | /// / BlockLabel? SwitchExpr | 2530 | /// / BlockLabel? SwitchExpr |
| 2651 | /// | 2531 | /// |
| 2652 | /// LoopTypeExpr <- KEYWORD_inline? (ForTypeExpr / WhileTypeExpr) | 2532 | /// LoopTypeExpr <- KEYWORD_inline? (ForTypeExpr / WhileTypeExpr) |
| 2653 | fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { | 2533 | fn parsePrimaryTypeExpr(p: *Parse) !?Node.Index { |
| 2654 | switch (p.token_tags[p.tok_i]) { | 2534 | switch (p.tokenTag(p.tok_i)) { |
| 2655 | .char_literal => return p.addNode(.{ | 2535 | .char_literal => return try p.addNode(.{ |
| 2656 | .tag = .char_literal, | 2536 | .tag = .char_literal, |
| 2657 | .main_token = p.nextToken(), | 2537 | .main_token = p.nextToken(), |
| 2658 | .data = .{ | 2538 | .data = undefined, |
| 2659 | .lhs = undefined, | ||
| 2660 | .rhs = undefined, | ||
| 2661 | }, | ||
| 2662 | }), | 2539 | }), |
| 2663 | .number_literal => return p.addNode(.{ | 2540 | .number_literal => return try p.addNode(.{ |
| 2664 | .tag = .number_literal, | 2541 | .tag = .number_literal, |
| 2665 | .main_token = p.nextToken(), | 2542 | .main_token = p.nextToken(), |
| 2666 | .data = .{ | 2543 | .data = undefined, |
| 2667 | .lhs = undefined, | ||
| 2668 | .rhs = undefined, | ||
| 2669 | }, | ||
| 2670 | }), | 2544 | }), |
| 2671 | .keyword_unreachable => return p.addNode(.{ | 2545 | .keyword_unreachable => return try p.addNode(.{ |
| 2672 | .tag = .unreachable_literal, | 2546 | .tag = .unreachable_literal, |
| 2673 | .main_token = p.nextToken(), | 2547 | .main_token = p.nextToken(), |
| 2674 | .data = .{ | 2548 | .data = undefined, |
| 2675 | .lhs = undefined, | ||
| 2676 | .rhs = undefined, | ||
| 2677 | }, | ||
| 2678 | }), | 2549 | }), |
| 2679 | .keyword_anyframe => return p.addNode(.{ | 2550 | .keyword_anyframe => return try p.addNode(.{ |
| 2680 | .tag = .anyframe_literal, | 2551 | .tag = .anyframe_literal, |
| 2681 | .main_token = p.nextToken(), | 2552 | .main_token = p.nextToken(), |
| 2682 | .data = .{ | 2553 | .data = undefined, |
| 2683 | .lhs = undefined, | ||
| 2684 | .rhs = undefined, | ||
| 2685 | }, | ||
| 2686 | }), | 2554 | }), |
| 2687 | .string_literal => { | 2555 | .string_literal => { |
| 2688 | const main_token = p.nextToken(); | 2556 | const main_token = p.nextToken(); |
| 2689 | return p.addNode(.{ | 2557 | return try p.addNode(.{ |
| 2690 | .tag = .string_literal, | 2558 | .tag = .string_literal, |
| 2691 | .main_token = main_token, | 2559 | .main_token = main_token, |
| 2692 | .data = .{ | 2560 | .data = undefined, |
| 2693 | .lhs = undefined, | ||
| 2694 | .rhs = undefined, | ||
| 2695 | }, | ||
| 2696 | }); | 2561 | }); |
| 2697 | }, | 2562 | }, |
| 2698 | 2563 | ||
| 2699 | .builtin => return p.parseBuiltinCall(), | 2564 | .builtin => return try p.parseBuiltinCall(), |
| 2700 | .keyword_fn => return p.parseFnProto(), | 2565 | .keyword_fn => return try p.parseFnProto(), |
| 2701 | .keyword_if => return p.parseIf(expectTypeExpr), | 2566 | .keyword_if => return try p.parseIf(expectTypeExpr), |
| 2702 | .keyword_switch => return p.expectSwitchExpr(false), | 2567 | .keyword_switch => return try p.expectSwitchExpr(false), |
| 2703 | 2568 | ||
| 2704 | .keyword_extern, | 2569 | .keyword_extern, |
| 2705 | .keyword_packed, | 2570 | .keyword_packed, |
| 2706 | => { | 2571 | => { |
| 2707 | p.tok_i += 1; | 2572 | p.tok_i += 1; |
| 2708 | return p.parseContainerDeclAuto(); | 2573 | return try p.parseContainerDeclAuto(); |
| 2709 | }, | 2574 | }, |
| 2710 | 2575 | ||
| 2711 | .keyword_struct, | 2576 | .keyword_struct, |
| 2712 | .keyword_opaque, | 2577 | .keyword_opaque, |
| 2713 | .keyword_enum, | 2578 | .keyword_enum, |
| 2714 | .keyword_union, | 2579 | .keyword_union, |
| 2715 | => return p.parseContainerDeclAuto(), | 2580 | => return try p.parseContainerDeclAuto(), |
| 2716 | 2581 | ||
| 2717 | .keyword_comptime => return p.addNode(.{ | 2582 | .keyword_comptime => return try p.addNode(.{ |
| 2718 | .tag = .@"comptime", | 2583 | .tag = .@"comptime", |
| 2719 | .main_token = p.nextToken(), | 2584 | .main_token = p.nextToken(), |
| 2720 | .data = .{ | 2585 | .data = .{ .node = try p.expectTypeExpr() }, |
| 2721 | .lhs = try p.expectTypeExpr(), | ||
| 2722 | .rhs = undefined, | ||
| 2723 | }, | ||
| 2724 | }), | 2586 | }), |
| 2725 | .multiline_string_literal_line => { | 2587 | .multiline_string_literal_line => { |
| 2726 | const first_line = p.nextToken(); | 2588 | const first_line = p.nextToken(); |
| 2727 | while (p.token_tags[p.tok_i] == .multiline_string_literal_line) { | 2589 | while (p.tokenTag(p.tok_i) == .multiline_string_literal_line) { |
| 2728 | p.tok_i += 1; | 2590 | p.tok_i += 1; |
| 2729 | } | 2591 | } |
| 2730 | return p.addNode(.{ | 2592 | return try p.addNode(.{ |
| 2731 | .tag = .multiline_string_literal, | 2593 | .tag = .multiline_string_literal, |
| 2732 | .main_token = first_line, | 2594 | .main_token = first_line, |
| 2733 | .data = .{ | 2595 | .data = .{ .token_and_token = .{ |
| 2734 | .lhs = first_line, | 2596 | first_line, |
| 2735 | .rhs = p.tok_i - 1, | 2597 | p.tok_i - 1, |
| 2736 | }, | 2598 | } }, |
| 2737 | }); | 2599 | }); |
| 2738 | }, | 2600 | }, |
| 2739 | .identifier => switch (p.token_tags[p.tok_i + 1]) { | 2601 | .identifier => switch (p.tokenTag(p.tok_i + 1)) { |
| 2740 | .colon => switch (p.token_tags[p.tok_i + 2]) { | 2602 | .colon => switch (p.tokenTag(p.tok_i + 2)) { |
| 2741 | .keyword_inline => { | 2603 | .keyword_inline => { |
| 2742 | p.tok_i += 3; | 2604 | p.tok_i += 3; |
| 2743 | switch (p.token_tags[p.tok_i]) { | 2605 | switch (p.tokenTag(p.tok_i)) { |
| 2744 | .keyword_for => return p.parseFor(expectTypeExpr), | 2606 | .keyword_for => return try p.parseFor(expectTypeExpr), |
| 2745 | .keyword_while => return p.parseWhileTypeExpr(), | 2607 | .keyword_while => return try p.parseWhileTypeExpr(), |
| 2746 | else => return p.fail(.expected_inlinable), | 2608 | else => return p.fail(.expected_inlinable), |
| 2747 | } | 2609 | } |
| 2748 | }, | 2610 | }, |
| 2749 | .keyword_for => { | 2611 | .keyword_for => { |
| 2750 | p.tok_i += 2; | 2612 | p.tok_i += 2; |
| 2751 | return p.parseFor(expectTypeExpr); | 2613 | return try p.parseFor(expectTypeExpr); |
| 2752 | }, | 2614 | }, |
| 2753 | .keyword_while => { | 2615 | .keyword_while => { |
| 2754 | p.tok_i += 2; | 2616 | p.tok_i += 2; |
| 2755 | return p.parseWhileTypeExpr(); | 2617 | return try p.parseWhileTypeExpr(); |
| 2756 | }, | 2618 | }, |
| 2757 | .keyword_switch => { | 2619 | .keyword_switch => { |
| 2758 | p.tok_i += 2; | 2620 | p.tok_i += 2; |
| 2759 | return p.expectSwitchExpr(true); | 2621 | return try p.expectSwitchExpr(true); |
| 2760 | }, | 2622 | }, |
| 2761 | .l_brace => { | 2623 | .l_brace => { |
| 2762 | p.tok_i += 2; | 2624 | p.tok_i += 2; |
| 2763 | return p.parseBlock(); | 2625 | return try p.parseBlock(); |
| 2764 | }, | 2626 | }, |
| 2765 | else => return p.addNode(.{ | 2627 | else => return try p.addNode(.{ |
| 2766 | .tag = .identifier, | 2628 | .tag = .identifier, |
| 2767 | .main_token = p.nextToken(), | 2629 | .main_token = p.nextToken(), |
| 2768 | .data = .{ | 2630 | .data = undefined, |
| 2769 | .lhs = undefined, | ||
| 2770 | .rhs = undefined, | ||
| 2771 | }, | ||
| 2772 | }), | 2631 | }), |
| 2773 | }, | 2632 | }, |
| 2774 | else => return p.addNode(.{ | 2633 | else => return try p.addNode(.{ |
| 2775 | .tag = .identifier, | 2634 | .tag = .identifier, |
| 2776 | .main_token = p.nextToken(), | 2635 | .main_token = p.nextToken(), |
| 2777 | .data = .{ | 2636 | .data = undefined, |
| 2778 | .lhs = undefined, | ||
| 2779 | .rhs = undefined, | ||
| 2780 | }, | ||
| 2781 | }), | 2637 | }), |
| 2782 | }, | 2638 | }, |
| 2783 | .keyword_inline => { | 2639 | .keyword_inline => { |
| 2784 | p.tok_i += 1; | 2640 | p.tok_i += 1; |
| 2785 | switch (p.token_tags[p.tok_i]) { | 2641 | switch (p.tokenTag(p.tok_i)) { |
| 2786 | .keyword_for => return p.parseFor(expectTypeExpr), | 2642 | .keyword_for => return try p.parseFor(expectTypeExpr), |
| 2787 | .keyword_while => return p.parseWhileTypeExpr(), | 2643 | .keyword_while => return try p.parseWhileTypeExpr(), |
| 2788 | else => return p.fail(.expected_inlinable), | 2644 | else => return p.fail(.expected_inlinable), |
| 2789 | } | 2645 | } |
| 2790 | }, | 2646 | }, |
| 2791 | .keyword_for => return p.parseFor(expectTypeExpr), | 2647 | .keyword_for => return try p.parseFor(expectTypeExpr), |
| 2792 | .keyword_while => return p.parseWhileTypeExpr(), | 2648 | .keyword_while => return try p.parseWhileTypeExpr(), |
| 2793 | .period => switch (p.token_tags[p.tok_i + 1]) { | 2649 | .period => switch (p.tokenTag(p.tok_i + 1)) { |
| 2794 | .identifier => return p.addNode(.{ | 2650 | .identifier => return try p.addNode(.{ |
| 2795 | .tag = .enum_literal, | 2651 | .tag = .enum_literal, |
| 2796 | .data = .{ | 2652 | .data = .{ .token = p.nextToken() }, // dot |
| 2797 | .lhs = p.nextToken(), // dot | ||
| 2798 | .rhs = undefined, | ||
| 2799 | }, | ||
| 2800 | .main_token = p.nextToken(), // identifier | 2653 | .main_token = p.nextToken(), // identifier |
| 2801 | }), | 2654 | }), |
| 2802 | .l_brace => { | 2655 | .l_brace => { |
| ... | @@ -2808,11 +2661,11 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2808,11 +2661,11 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2808 | 2661 | ||
| 2809 | const scratch_top = p.scratch.items.len; | 2662 | const scratch_top = p.scratch.items.len; |
| 2810 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 2663 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2811 | const field_init = try p.parseFieldInit(); | 2664 | const opt_field_init = try p.parseFieldInit(); |
| 2812 | if (field_init != 0) { | 2665 | if (opt_field_init) |field_init| { |
| 2813 | try p.scratch.append(p.gpa, field_init); | 2666 | try p.scratch.append(p.gpa, field_init); |
| 2814 | while (true) { | 2667 | while (true) { |
| 2815 | switch (p.token_tags[p.tok_i]) { | 2668 | switch (p.tokenTag(p.tok_i)) { |
| 2816 | .comma => p.tok_i += 1, | 2669 | .comma => p.tok_i += 1, |
| 2817 | .r_brace => { | 2670 | .r_brace => { |
| 2818 | p.tok_i += 1; | 2671 | p.tok_i += 1; |
| ... | @@ -2826,37 +2679,24 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2826,37 +2679,24 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2826 | const next = try p.expectFieldInit(); | 2679 | const next = try p.expectFieldInit(); |
| 2827 | try p.scratch.append(p.gpa, next); | 2680 | try p.scratch.append(p.gpa, next); |
| 2828 | } | 2681 | } |
| 2829 | const comma = (p.token_tags[p.tok_i - 2] == .comma); | 2682 | const comma = (p.tokenTag(p.tok_i - 2)) == .comma; |
| 2830 | const inits = p.scratch.items[scratch_top..]; | 2683 | const inits = p.scratch.items[scratch_top..]; |
| 2831 | switch (inits.len) { | 2684 | std.debug.assert(inits.len != 0); |
| 2832 | 0 => unreachable, | 2685 | if (inits.len <= 2) { |
| 2833 | 1 => return p.addNode(.{ | 2686 | return try p.addNode(.{ |
| 2834 | .tag = if (comma) .struct_init_dot_two_comma else .struct_init_dot_two, | 2687 | .tag = if (comma) .struct_init_dot_two_comma else .struct_init_dot_two, |
| 2835 | .main_token = lbrace, | 2688 | .main_token = lbrace, |
| 2836 | .data = .{ | 2689 | .data = .{ .opt_node_and_opt_node = .{ |
| 2837 | .lhs = inits[0], | 2690 | if (inits.len >= 1) .fromOptional(inits[0]) else .none, |
| 2838 | .rhs = 0, | 2691 | if (inits.len >= 2) .fromOptional(inits[1]) else .none, |
| 2839 | }, | 2692 | } }, |
| 2840 | }), | 2693 | }); |
| 2841 | 2 => return p.addNode(.{ | 2694 | } else { |
| 2842 | .tag = if (comma) .struct_init_dot_two_comma else .struct_init_dot_two, | 2695 | return try p.addNode(.{ |
| 2696 | .tag = if (comma) .struct_init_dot_comma else .struct_init_dot, | ||
| 2843 | .main_token = lbrace, | 2697 | .main_token = lbrace, |
| 2844 | .data = .{ | 2698 | .data = .{ .extra_range = try p.listToSpan(inits) }, |
| 2845 | .lhs = inits[0], | 2699 | }); |
| 2846 | .rhs = inits[1], | ||
| 2847 | }, | ||
| 2848 | }), | ||
| 2849 | else => { | ||
| 2850 | const span = try p.listToSpan(inits); | ||
| 2851 | return p.addNode(.{ | ||
| 2852 | .tag = if (comma) .struct_init_dot_comma else .struct_init_dot, | ||
| 2853 | .main_token = lbrace, | ||
| 2854 | .data = .{ | ||
| 2855 | .lhs = span.start, | ||
| 2856 | .rhs = span.end, | ||
| 2857 | }, | ||
| 2858 | }); | ||
| 2859 | }, | ||
| 2860 | } | 2700 | } |
| 2861 | } | 2701 | } |
| 2862 | 2702 | ||
| ... | @@ -2864,7 +2704,7 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2864,7 +2704,7 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2864 | if (p.eatToken(.r_brace)) |_| break; | 2704 | if (p.eatToken(.r_brace)) |_| break; |
| 2865 | const elem_init = try p.expectExpr(); | 2705 | const elem_init = try p.expectExpr(); |
| 2866 | try p.scratch.append(p.gpa, elem_init); | 2706 | try p.scratch.append(p.gpa, elem_init); |
| 2867 | switch (p.token_tags[p.tok_i]) { | 2707 | switch (p.tokenTag(p.tok_i)) { |
| 2868 | .comma => p.tok_i += 1, | 2708 | .comma => p.tok_i += 1, |
| 2869 | .r_brace => { | 2709 | .r_brace => { |
| 2870 | p.tok_i += 1; | 2710 | p.tok_i += 1; |
| ... | @@ -2875,49 +2715,30 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2875,49 +2715,30 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2875 | else => try p.warn(.expected_comma_after_initializer), | 2715 | else => try p.warn(.expected_comma_after_initializer), |
| 2876 | } | 2716 | } |
| 2877 | } | 2717 | } |
| 2878 | const comma = (p.token_tags[p.tok_i - 2] == .comma); | 2718 | const comma = (p.tokenTag(p.tok_i - 2)) == .comma; |
| 2879 | const inits = p.scratch.items[scratch_top..]; | 2719 | const inits = p.scratch.items[scratch_top..]; |
| 2880 | switch (inits.len) { | 2720 | if (inits.len <= 2) { |
| 2881 | 0 => return p.addNode(.{ | 2721 | return try p.addNode(.{ |
| 2882 | .tag = .struct_init_dot_two, | 2722 | .tag = if (inits.len == 0) |
| 2883 | .main_token = lbrace, | 2723 | .struct_init_dot_two |
| 2884 | .data = .{ | 2724 | else if (comma) .array_init_dot_two_comma else .array_init_dot_two, |
| 2885 | .lhs = 0, | ||
| 2886 | .rhs = 0, | ||
| 2887 | }, | ||
| 2888 | }), | ||
| 2889 | 1 => return p.addNode(.{ | ||
| 2890 | .tag = if (comma) .array_init_dot_two_comma else .array_init_dot_two, | ||
| 2891 | .main_token = lbrace, | 2725 | .main_token = lbrace, |
| 2892 | .data = .{ | 2726 | .data = .{ .opt_node_and_opt_node = .{ |
| 2893 | .lhs = inits[0], | 2727 | if (inits.len >= 1) inits[0].toOptional() else .none, |
| 2894 | .rhs = 0, | 2728 | if (inits.len >= 2) inits[1].toOptional() else .none, |
| 2895 | }, | 2729 | } }, |
| 2896 | }), | 2730 | }); |
| 2897 | 2 => return p.addNode(.{ | 2731 | } else { |
| 2898 | .tag = if (comma) .array_init_dot_two_comma else .array_init_dot_two, | 2732 | return try p.addNode(.{ |
| 2733 | .tag = if (comma) .array_init_dot_comma else .array_init_dot, | ||
| 2899 | .main_token = lbrace, | 2734 | .main_token = lbrace, |
| 2900 | .data = .{ | 2735 | .data = .{ .extra_range = try p.listToSpan(inits) }, |
| 2901 | .lhs = inits[0], | 2736 | }); |
| 2902 | .rhs = inits[1], | ||
| 2903 | }, | ||
| 2904 | }), | ||
| 2905 | else => { | ||
| 2906 | const span = try p.listToSpan(inits); | ||
| 2907 | return p.addNode(.{ | ||
| 2908 | .tag = if (comma) .array_init_dot_comma else .array_init_dot, | ||
| 2909 | .main_token = lbrace, | ||
| 2910 | .data = .{ | ||
| 2911 | .lhs = span.start, | ||
| 2912 | .rhs = span.end, | ||
| 2913 | }, | ||
| 2914 | }); | ||
| 2915 | }, | ||
| 2916 | } | 2737 | } |
| 2917 | }, | 2738 | }, |
| 2918 | else => return null_node, | 2739 | else => return null, |
| 2919 | }, | 2740 | }, |
| 2920 | .keyword_error => switch (p.token_tags[p.tok_i + 1]) { | 2741 | .keyword_error => switch (p.tokenTag(p.tok_i + 1)) { |
| 2921 | .l_brace => { | 2742 | .l_brace => { |
| 2922 | const error_token = p.tok_i; | 2743 | const error_token = p.tok_i; |
| 2923 | p.tok_i += 2; | 2744 | p.tok_i += 2; |
| ... | @@ -2925,7 +2746,7 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2925,7 +2746,7 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2925 | if (p.eatToken(.r_brace)) |_| break; | 2746 | if (p.eatToken(.r_brace)) |_| break; |
| 2926 | _ = try p.eatDocComments(); | 2747 | _ = try p.eatDocComments(); |
| 2927 | _ = try p.expectToken(.identifier); | 2748 | _ = try p.expectToken(.identifier); |
| 2928 | switch (p.token_tags[p.tok_i]) { | 2749 | switch (p.tokenTag(p.tok_i)) { |
| 2929 | .comma => p.tok_i += 1, | 2750 | .comma => p.tok_i += 1, |
| 2930 | .r_brace => { | 2751 | .r_brace => { |
| 2931 | p.tok_i += 1; | 2752 | p.tok_i += 1; |
| ... | @@ -2936,13 +2757,10 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2936,13 +2757,10 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2936 | else => try p.warn(.expected_comma_after_field), | 2757 | else => try p.warn(.expected_comma_after_field), |
| 2937 | } | 2758 | } |
| 2938 | } | 2759 | } |
| 2939 | return p.addNode(.{ | 2760 | return try p.addNode(.{ |
| 2940 | .tag = .error_set_decl, | 2761 | .tag = .error_set_decl, |
| 2941 | .main_token = error_token, | 2762 | .main_token = error_token, |
| 2942 | .data = .{ | 2763 | .data = .{ .token = p.tok_i - 1 }, // rbrace |
| 2943 | .lhs = undefined, | ||
| 2944 | .rhs = p.tok_i - 1, // rbrace | ||
| 2945 | }, | ||
| 2946 | }); | 2764 | }); |
| 2947 | }, | 2765 | }, |
| 2948 | else => { | 2766 | else => { |
| ... | @@ -2951,41 +2769,37 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2951,41 +2769,37 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2951 | if (period == null) try p.warnExpected(.period); | 2769 | if (period == null) try p.warnExpected(.period); |
| 2952 | const identifier = p.eatToken(.identifier); | 2770 | const identifier = p.eatToken(.identifier); |
| 2953 | if (identifier == null) try p.warnExpected(.identifier); | 2771 | if (identifier == null) try p.warnExpected(.identifier); |
| 2954 | return p.addNode(.{ | 2772 | return try p.addNode(.{ |
| 2955 | .tag = .error_value, | 2773 | .tag = .error_value, |
| 2956 | .main_token = main_token, | 2774 | .main_token = main_token, |
| 2957 | .data = .{ | 2775 | .data = .{ .opt_token_and_opt_token = .{ |
| 2958 | .lhs = period orelse 0, | 2776 | .fromOptional(period), |
| 2959 | .rhs = identifier orelse 0, | 2777 | .fromOptional(identifier), |
| 2960 | }, | 2778 | } }, |
| 2961 | }); | 2779 | }); |
| 2962 | }, | 2780 | }, |
| 2963 | }, | 2781 | }, |
| 2964 | .l_paren => return p.addNode(.{ | 2782 | .l_paren => return try p.addNode(.{ |
| 2965 | .tag = .grouped_expression, | 2783 | .tag = .grouped_expression, |
| 2966 | .main_token = p.nextToken(), | 2784 | .main_token = p.nextToken(), |
| 2967 | .data = .{ | 2785 | .data = .{ .node_and_token = .{ |
| 2968 | .lhs = try p.expectExpr(), | 2786 | try p.expectExpr(), |
| 2969 | .rhs = try p.expectToken(.r_paren), | 2787 | try p.expectToken(.r_paren), |
| 2970 | }, | 2788 | } }, |
| 2971 | }), | 2789 | }), |
| 2972 | else => return null_node, | 2790 | else => return null, |
| 2973 | } | 2791 | } |
| 2974 | } | 2792 | } |
| 2975 | 2793 | ||
| 2976 | fn expectPrimaryTypeExpr(p: *Parse) !Node.Index { | 2794 | fn expectPrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2977 | const node = try p.parsePrimaryTypeExpr(); | 2795 | return try p.parsePrimaryTypeExpr() orelse return p.fail(.expected_primary_type_expr); |
| 2978 | if (node == 0) { | ||
| 2979 | return p.fail(.expected_primary_type_expr); | ||
| 2980 | } | ||
| 2981 | return node; | ||
| 2982 | } | 2796 | } |
| 2983 | 2797 | ||
| 2984 | /// WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr? | 2798 | /// WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr? |
| 2985 | /// | 2799 | /// |
| 2986 | /// WhileTypeExpr <- WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)? | 2800 | /// WhileTypeExpr <- WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)? |
| 2987 | fn parseWhileTypeExpr(p: *Parse) !Node.Index { | 2801 | fn parseWhileTypeExpr(p: *Parse) !?Node.Index { |
| 2988 | const while_token = p.eatToken(.keyword_while) orelse return null_node; | 2802 | const while_token = p.eatToken(.keyword_while) orelse return null; |
| 2989 | _ = try p.expectToken(.l_paren); | 2803 | _ = try p.expectToken(.l_paren); |
| 2990 | const condition = try p.expectExpr(); | 2804 | const condition = try p.expectExpr(); |
| 2991 | _ = try p.expectToken(.r_paren); | 2805 | _ = try p.expectToken(.r_paren); |
| ... | @@ -2994,54 +2808,52 @@ fn parseWhileTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2994,54 +2808,52 @@ fn parseWhileTypeExpr(p: *Parse) !Node.Index { |
| 2994 | 2808 | ||
| 2995 | const then_expr = try p.expectTypeExpr(); | 2809 | const then_expr = try p.expectTypeExpr(); |
| 2996 | _ = p.eatToken(.keyword_else) orelse { | 2810 | _ = p.eatToken(.keyword_else) orelse { |
| 2997 | if (cont_expr == 0) { | 2811 | if (cont_expr == null) { |
| 2998 | return p.addNode(.{ | 2812 | return try p.addNode(.{ |
| 2999 | .tag = .while_simple, | 2813 | .tag = .while_simple, |
| 3000 | .main_token = while_token, | 2814 | .main_token = while_token, |
| 3001 | .data = .{ | 2815 | .data = .{ .node_and_node = .{ |
| 3002 | .lhs = condition, | 2816 | condition, |
| 3003 | .rhs = then_expr, | 2817 | then_expr, |
| 3004 | }, | 2818 | } }, |
| 3005 | }); | 2819 | }); |
| 3006 | } else { | 2820 | } else { |
| 3007 | return p.addNode(.{ | 2821 | return try p.addNode(.{ |
| 3008 | .tag = .while_cont, | 2822 | .tag = .while_cont, |
| 3009 | .main_token = while_token, | 2823 | .main_token = while_token, |
| 3010 | .data = .{ | 2824 | .data = .{ .node_and_extra = .{ |
| 3011 | .lhs = condition, | 2825 | condition, try p.addExtra(Node.WhileCont{ |
| 3012 | .rhs = try p.addExtra(Node.WhileCont{ | 2826 | .cont_expr = cont_expr.?, |
| 3013 | .cont_expr = cont_expr, | ||
| 3014 | .then_expr = then_expr, | 2827 | .then_expr = then_expr, |
| 3015 | }), | 2828 | }), |
| 3016 | }, | 2829 | } }, |
| 3017 | }); | 2830 | }); |
| 3018 | } | 2831 | } |
| 3019 | }; | 2832 | }; |
| 3020 | _ = try p.parsePayload(); | 2833 | _ = try p.parsePayload(); |
| 3021 | const else_expr = try p.expectTypeExpr(); | 2834 | const else_expr = try p.expectTypeExpr(); |
| 3022 | return p.addNode(.{ | 2835 | return try p.addNode(.{ |
| 3023 | .tag = .@"while", | 2836 | .tag = .@"while", |
| 3024 | .main_token = while_token, | 2837 | .main_token = while_token, |
| 3025 | .data = .{ | 2838 | .data = .{ .node_and_extra = .{ |
| 3026 | .lhs = condition, | 2839 | condition, try p.addExtra(Node.While{ |
| 3027 | .rhs = try p.addExtra(Node.While{ | 2840 | .cont_expr = .fromOptional(cont_expr), |
| 3028 | .cont_expr = cont_expr, | ||
| 3029 | .then_expr = then_expr, | 2841 | .then_expr = then_expr, |
| 3030 | .else_expr = else_expr, | 2842 | .else_expr = else_expr, |
| 3031 | }), | 2843 | }), |
| 3032 | }, | 2844 | } }, |
| 3033 | }); | 2845 | }); |
| 3034 | } | 2846 | } |
| 3035 | 2847 | ||
| 3036 | /// SwitchExpr <- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE | 2848 | /// SwitchExpr <- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE |
| 3037 | fn parseSwitchExpr(p: *Parse, is_labeled: bool) !Node.Index { | 2849 | fn parseSwitchExpr(p: *Parse, is_labeled: bool) !?Node.Index { |
| 3038 | const switch_token = p.eatToken(.keyword_switch) orelse return null_node; | 2850 | const switch_token = p.eatToken(.keyword_switch) orelse return null; |
| 3039 | return p.expectSwitchSuffix(if (is_labeled) switch_token - 2 else switch_token); | 2851 | return try p.expectSwitchSuffix(if (is_labeled) switch_token - 2 else switch_token); |
| 3040 | } | 2852 | } |
| 3041 | 2853 | ||
| 3042 | fn expectSwitchExpr(p: *Parse, is_labeled: bool) !Node.Index { | 2854 | fn expectSwitchExpr(p: *Parse, is_labeled: bool) !Node.Index { |
| 3043 | const switch_token = p.assertToken(.keyword_switch); | 2855 | const switch_token = p.assertToken(.keyword_switch); |
| 3044 | return p.expectSwitchSuffix(if (is_labeled) switch_token - 2 else switch_token); | 2856 | return try p.expectSwitchSuffix(if (is_labeled) switch_token - 2 else switch_token); |
| 3045 | } | 2857 | } |
| 3046 | 2858 | ||
| 3047 | fn expectSwitchSuffix(p: *Parse, main_token: TokenIndex) !Node.Index { | 2859 | fn expectSwitchSuffix(p: *Parse, main_token: TokenIndex) !Node.Index { |
| ... | @@ -3050,19 +2862,19 @@ fn expectSwitchSuffix(p: *Parse, main_token: TokenIndex) !Node.Index { | ... | @@ -3050,19 +2862,19 @@ fn expectSwitchSuffix(p: *Parse, main_token: TokenIndex) !Node.Index { |
| 3050 | _ = try p.expectToken(.r_paren); | 2862 | _ = try p.expectToken(.r_paren); |
| 3051 | _ = try p.expectToken(.l_brace); | 2863 | _ = try p.expectToken(.l_brace); |
| 3052 | const cases = try p.parseSwitchProngList(); | 2864 | const cases = try p.parseSwitchProngList(); |
| 3053 | const trailing_comma = p.token_tags[p.tok_i - 1] == .comma; | 2865 | const trailing_comma = p.tokenTag(p.tok_i - 1) == .comma; |
| 3054 | _ = try p.expectToken(.r_brace); | 2866 | _ = try p.expectToken(.r_brace); |
| 3055 | 2867 | ||
| 3056 | return p.addNode(.{ | 2868 | return p.addNode(.{ |
| 3057 | .tag = if (trailing_comma) .switch_comma else .@"switch", | 2869 | .tag = if (trailing_comma) .switch_comma else .@"switch", |
| 3058 | .main_token = main_token, | 2870 | .main_token = main_token, |
| 3059 | .data = .{ | 2871 | .data = .{ .node_and_extra = .{ |
| 3060 | .lhs = expr_node, | 2872 | expr_node, |
| 3061 | .rhs = try p.addExtra(Node.SubRange{ | 2873 | try p.addExtra(Node.SubRange{ |
| 3062 | .start = cases.start, | 2874 | .start = cases.start, |
| 3063 | .end = cases.end, | 2875 | .end = cases.end, |
| 3064 | }), | 2876 | }), |
| 3065 | }, | 2877 | } }, |
| 3066 | }); | 2878 | }); |
| 3067 | } | 2879 | } |
| 3068 | 2880 | ||
| ... | @@ -3089,10 +2901,10 @@ fn expectAsmExpr(p: *Parse) !Node.Index { | ... | @@ -3089,10 +2901,10 @@ fn expectAsmExpr(p: *Parse) !Node.Index { |
| 3089 | return p.addNode(.{ | 2901 | return p.addNode(.{ |
| 3090 | .tag = .asm_simple, | 2902 | .tag = .asm_simple, |
| 3091 | .main_token = asm_token, | 2903 | .main_token = asm_token, |
| 3092 | .data = .{ | 2904 | .data = .{ .node_and_token = .{ |
| 3093 | .lhs = template, | 2905 | template, |
| 3094 | .rhs = rparen, | 2906 | rparen, |
| 3095 | }, | 2907 | } }, |
| 3096 | }); | 2908 | }); |
| 3097 | } | 2909 | } |
| 3098 | 2910 | ||
| ... | @@ -3102,10 +2914,9 @@ fn expectAsmExpr(p: *Parse) !Node.Index { | ... | @@ -3102,10 +2914,9 @@ fn expectAsmExpr(p: *Parse) !Node.Index { |
| 3102 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 2914 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 3103 | 2915 | ||
| 3104 | while (true) { | 2916 | while (true) { |
| 3105 | const output_item = try p.parseAsmOutputItem(); | 2917 | const output_item = try p.parseAsmOutputItem() orelse break; |
| 3106 | if (output_item == 0) break; | ||
| 3107 | try p.scratch.append(p.gpa, output_item); | 2918 | try p.scratch.append(p.gpa, output_item); |
| 3108 | switch (p.token_tags[p.tok_i]) { | 2919 | switch (p.tokenTag(p.tok_i)) { |
| 3109 | .comma => p.tok_i += 1, | 2920 | .comma => p.tok_i += 1, |
| 3110 | // All possible delimiters. | 2921 | // All possible delimiters. |
| 3111 | .colon, .r_paren, .r_brace, .r_bracket => break, | 2922 | .colon, .r_paren, .r_brace, .r_bracket => break, |
| ... | @@ -3115,10 +2926,9 @@ fn expectAsmExpr(p: *Parse) !Node.Index { | ... | @@ -3115,10 +2926,9 @@ fn expectAsmExpr(p: *Parse) !Node.Index { |
| 3115 | } | 2926 | } |
| 3116 | if (p.eatToken(.colon)) |_| { | 2927 | if (p.eatToken(.colon)) |_| { |
| 3117 | while (true) { | 2928 | while (true) { |
| 3118 | const input_item = try p.parseAsmInputItem(); | 2929 | const input_item = try p.parseAsmInputItem() orelse break; |
| 3119 | if (input_item == 0) break; | ||
| 3120 | try p.scratch.append(p.gpa, input_item); | 2930 | try p.scratch.append(p.gpa, input_item); |
| 3121 | switch (p.token_tags[p.tok_i]) { | 2931 | switch (p.tokenTag(p.tok_i)) { |
| 3122 | .comma => p.tok_i += 1, | 2932 | .comma => p.tok_i += 1, |
| 3123 | // All possible delimiters. | 2933 | // All possible delimiters. |
| 3124 | .colon, .r_paren, .r_brace, .r_bracket => break, | 2934 | .colon, .r_paren, .r_brace, .r_bracket => break, |
| ... | @@ -3128,7 +2938,7 @@ fn expectAsmExpr(p: *Parse) !Node.Index { | ... | @@ -3128,7 +2938,7 @@ fn expectAsmExpr(p: *Parse) !Node.Index { |
| 3128 | } | 2938 | } |
| 3129 | if (p.eatToken(.colon)) |_| { | 2939 | if (p.eatToken(.colon)) |_| { |
| 3130 | while (p.eatToken(.string_literal)) |_| { | 2940 | while (p.eatToken(.string_literal)) |_| { |
| 3131 | switch (p.token_tags[p.tok_i]) { | 2941 | switch (p.tokenTag(p.tok_i)) { |
| 3132 | .comma => p.tok_i += 1, | 2942 | .comma => p.tok_i += 1, |
| 3133 | .colon, .r_paren, .r_brace, .r_bracket => break, | 2943 | .colon, .r_paren, .r_brace, .r_bracket => break, |
| 3134 | // Likely just a missing comma; give error but continue parsing. | 2944 | // Likely just a missing comma; give error but continue parsing. |
| ... | @@ -3142,121 +2952,106 @@ fn expectAsmExpr(p: *Parse) !Node.Index { | ... | @@ -3142,121 +2952,106 @@ fn expectAsmExpr(p: *Parse) !Node.Index { |
| 3142 | return p.addNode(.{ | 2952 | return p.addNode(.{ |
| 3143 | .tag = .@"asm", | 2953 | .tag = .@"asm", |
| 3144 | .main_token = asm_token, | 2954 | .main_token = asm_token, |
| 3145 | .data = .{ | 2955 | .data = .{ .node_and_extra = .{ |
| 3146 | .lhs = template, | 2956 | template, |
| 3147 | .rhs = try p.addExtra(Node.Asm{ | 2957 | try p.addExtra(Node.Asm{ |
| 3148 | .items_start = span.start, | 2958 | .items_start = span.start, |
| 3149 | .items_end = span.end, | 2959 | .items_end = span.end, |
| 3150 | .rparen = rparen, | 2960 | .rparen = rparen, |
| 3151 | }), | 2961 | }), |
| 3152 | }, | 2962 | } }, |
| 3153 | }); | 2963 | }); |
| 3154 | } | 2964 | } |
| 3155 | 2965 | ||
| 3156 | /// AsmOutputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN | 2966 | /// AsmOutputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN |
| 3157 | fn parseAsmOutputItem(p: *Parse) !Node.Index { | 2967 | fn parseAsmOutputItem(p: *Parse) !?Node.Index { |
| 3158 | _ = p.eatToken(.l_bracket) orelse return null_node; | 2968 | _ = p.eatToken(.l_bracket) orelse return null; |
| 3159 | const identifier = try p.expectToken(.identifier); | 2969 | const identifier = try p.expectToken(.identifier); |
| 3160 | _ = try p.expectToken(.r_bracket); | 2970 | _ = try p.expectToken(.r_bracket); |
| 3161 | _ = try p.expectToken(.string_literal); | 2971 | _ = try p.expectToken(.string_literal); |
| 3162 | _ = try p.expectToken(.l_paren); | 2972 | _ = try p.expectToken(.l_paren); |
| 3163 | const type_expr: Node.Index = blk: { | 2973 | const type_expr: Node.OptionalIndex = blk: { |
| 3164 | if (p.eatToken(.arrow)) |_| { | 2974 | if (p.eatToken(.arrow)) |_| { |
| 3165 | break :blk try p.expectTypeExpr(); | 2975 | break :blk .fromOptional(try p.expectTypeExpr()); |
| 3166 | } else { | 2976 | } else { |
| 3167 | _ = try p.expectToken(.identifier); | 2977 | _ = try p.expectToken(.identifier); |
| 3168 | break :blk null_node; | 2978 | break :blk .none; |
| 3169 | } | 2979 | } |
| 3170 | }; | 2980 | }; |
| 3171 | const rparen = try p.expectToken(.r_paren); | 2981 | const rparen = try p.expectToken(.r_paren); |
| 3172 | return p.addNode(.{ | 2982 | return try p.addNode(.{ |
| 3173 | .tag = .asm_output, | 2983 | .tag = .asm_output, |
| 3174 | .main_token = identifier, | 2984 | .main_token = identifier, |
| 3175 | .data = .{ | 2985 | .data = .{ .opt_node_and_token = .{ |
| 3176 | .lhs = type_expr, | 2986 | type_expr, |
| 3177 | .rhs = rparen, | 2987 | rparen, |
| 3178 | }, | 2988 | } }, |
| 3179 | }); | 2989 | }); |
| 3180 | } | 2990 | } |
| 3181 | 2991 | ||
| 3182 | /// AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN | 2992 | /// AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN |
| 3183 | fn parseAsmInputItem(p: *Parse) !Node.Index { | 2993 | fn parseAsmInputItem(p: *Parse) !?Node.Index { |
| 3184 | _ = p.eatToken(.l_bracket) orelse return null_node; | 2994 | _ = p.eatToken(.l_bracket) orelse return null; |
| 3185 | const identifier = try p.expectToken(.identifier); | 2995 | const identifier = try p.expectToken(.identifier); |
| 3186 | _ = try p.expectToken(.r_bracket); | 2996 | _ = try p.expectToken(.r_bracket); |
| 3187 | _ = try p.expectToken(.string_literal); | 2997 | _ = try p.expectToken(.string_literal); |
| 3188 | _ = try p.expectToken(.l_paren); | 2998 | _ = try p.expectToken(.l_paren); |
| 3189 | const expr = try p.expectExpr(); | 2999 | const expr = try p.expectExpr(); |
| 3190 | const rparen = try p.expectToken(.r_paren); | 3000 | const rparen = try p.expectToken(.r_paren); |
| 3191 | return p.addNode(.{ | 3001 | return try p.addNode(.{ |
| 3192 | .tag = .asm_input, | 3002 | .tag = .asm_input, |
| 3193 | .main_token = identifier, | 3003 | .main_token = identifier, |
| 3194 | .data = .{ | 3004 | .data = .{ .node_and_token = .{ |
| 3195 | .lhs = expr, | 3005 | expr, |
| 3196 | .rhs = rparen, | 3006 | rparen, |
| 3197 | }, | 3007 | } }, |
| 3198 | }); | 3008 | }); |
| 3199 | } | 3009 | } |
| 3200 | 3010 | ||
| 3201 | /// BreakLabel <- COLON IDENTIFIER | 3011 | /// BreakLabel <- COLON IDENTIFIER |
| 3202 | fn parseBreakLabel(p: *Parse) !TokenIndex { | 3012 | fn parseBreakLabel(p: *Parse) Error!OptionalTokenIndex { |
| 3203 | _ = p.eatToken(.colon) orelse return null_node; | 3013 | _ = p.eatToken(.colon) orelse return .none; |
| 3204 | return p.expectToken(.identifier); | 3014 | const next_token = try p.expectToken(.identifier); |
| 3015 | return .fromToken(next_token); | ||
| 3205 | } | 3016 | } |
| 3206 | 3017 | ||
| 3207 | /// BlockLabel <- IDENTIFIER COLON | 3018 | /// BlockLabel <- IDENTIFIER COLON |
| 3208 | fn parseBlockLabel(p: *Parse) TokenIndex { | 3019 | fn parseBlockLabel(p: *Parse) ?TokenIndex { |
| 3209 | if (p.token_tags[p.tok_i] == .identifier and | 3020 | return p.eatTokens(&.{ .identifier, .colon }); |
| 3210 | p.token_tags[p.tok_i + 1] == .colon) | ||
| 3211 | { | ||
| 3212 | const identifier = p.tok_i; | ||
| 3213 | p.tok_i += 2; | ||
| 3214 | return identifier; | ||
| 3215 | } | ||
| 3216 | return null_node; | ||
| 3217 | } | 3021 | } |
| 3218 | 3022 | ||
| 3219 | /// FieldInit <- DOT IDENTIFIER EQUAL Expr | 3023 | /// FieldInit <- DOT IDENTIFIER EQUAL Expr |
| 3220 | fn parseFieldInit(p: *Parse) !Node.Index { | 3024 | fn parseFieldInit(p: *Parse) !?Node.Index { |
| 3221 | if (p.token_tags[p.tok_i + 0] == .period and | 3025 | if (p.eatTokens(&.{ .period, .identifier, .equal })) |_| { |
| 3222 | p.token_tags[p.tok_i + 1] == .identifier and | 3026 | return try p.expectExpr(); |
| 3223 | p.token_tags[p.tok_i + 2] == .equal) | ||
| 3224 | { | ||
| 3225 | p.tok_i += 3; | ||
| 3226 | return p.expectExpr(); | ||
| 3227 | } else { | ||
| 3228 | return null_node; | ||
| 3229 | } | 3027 | } |
| 3028 | return null; | ||
| 3230 | } | 3029 | } |
| 3231 | 3030 | ||
| 3232 | fn expectFieldInit(p: *Parse) !Node.Index { | 3031 | fn expectFieldInit(p: *Parse) !Node.Index { |
| 3233 | if (p.token_tags[p.tok_i] != .period or | 3032 | if (p.eatTokens(&.{ .period, .identifier, .equal })) |_| { |
| 3234 | p.token_tags[p.tok_i + 1] != .identifier or | 3033 | return try p.expectExpr(); |
| 3235 | p.token_tags[p.tok_i + 2] != .equal) | 3034 | } |
| 3236 | return p.fail(.expected_initializer); | 3035 | return p.fail(.expected_initializer); |
| 3237 | |||
| 3238 | p.tok_i += 3; | ||
| 3239 | return p.expectExpr(); | ||
| 3240 | } | 3036 | } |
| 3241 | 3037 | ||
| 3242 | /// WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN | 3038 | /// WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN |
| 3243 | fn parseWhileContinueExpr(p: *Parse) !Node.Index { | 3039 | fn parseWhileContinueExpr(p: *Parse) !?Node.Index { |
| 3244 | _ = p.eatToken(.colon) orelse { | 3040 | _ = p.eatToken(.colon) orelse { |
| 3245 | if (p.token_tags[p.tok_i] == .l_paren and | 3041 | if (p.tokenTag(p.tok_i) == .l_paren and |
| 3246 | p.tokensOnSameLine(p.tok_i - 1, p.tok_i)) | 3042 | p.tokensOnSameLine(p.tok_i - 1, p.tok_i)) |
| 3247 | return p.fail(.expected_continue_expr); | 3043 | return p.fail(.expected_continue_expr); |
| 3248 | return null_node; | 3044 | return null; |
| 3249 | }; | 3045 | }; |
| 3250 | _ = try p.expectToken(.l_paren); | 3046 | _ = try p.expectToken(.l_paren); |
| 3251 | const node = try p.parseAssignExpr(); | 3047 | const node = try p.parseAssignExpr() orelse return p.fail(.expected_expr_or_assignment); |
| 3252 | if (node == 0) return p.fail(.expected_expr_or_assignment); | ||
| 3253 | _ = try p.expectToken(.r_paren); | 3048 | _ = try p.expectToken(.r_paren); |
| 3254 | return node; | 3049 | return node; |
| 3255 | } | 3050 | } |
| 3256 | 3051 | ||
| 3257 | /// LinkSection <- KEYWORD_linksection LPAREN Expr RPAREN | 3052 | /// LinkSection <- KEYWORD_linksection LPAREN Expr RPAREN |
| 3258 | fn parseLinkSection(p: *Parse) !Node.Index { | 3053 | fn parseLinkSection(p: *Parse) !?Node.Index { |
| 3259 | _ = p.eatToken(.keyword_linksection) orelse return null_node; | 3054 | _ = p.eatToken(.keyword_linksection) orelse return null; |
| 3260 | _ = try p.expectToken(.l_paren); | 3055 | _ = try p.expectToken(.l_paren); |
| 3261 | const expr_node = try p.expectExpr(); | 3056 | const expr_node = try p.expectExpr(); |
| 3262 | _ = try p.expectToken(.r_paren); | 3057 | _ = try p.expectToken(.r_paren); |
| ... | @@ -3264,8 +3059,8 @@ fn parseLinkSection(p: *Parse) !Node.Index { | ... | @@ -3264,8 +3059,8 @@ fn parseLinkSection(p: *Parse) !Node.Index { |
| 3264 | } | 3059 | } |
| 3265 | 3060 | ||
| 3266 | /// CallConv <- KEYWORD_callconv LPAREN Expr RPAREN | 3061 | /// CallConv <- KEYWORD_callconv LPAREN Expr RPAREN |
| 3267 | fn parseCallconv(p: *Parse) !Node.Index { | 3062 | fn parseCallconv(p: *Parse) !?Node.Index { |
| 3268 | _ = p.eatToken(.keyword_callconv) orelse return null_node; | 3063 | _ = p.eatToken(.keyword_callconv) orelse return null; |
| 3269 | _ = try p.expectToken(.l_paren); | 3064 | _ = try p.expectToken(.l_paren); |
| 3270 | const expr_node = try p.expectExpr(); | 3065 | const expr_node = try p.expectExpr(); |
| 3271 | _ = try p.expectToken(.r_paren); | 3066 | _ = try p.expectToken(.r_paren); |
| ... | @@ -3273,8 +3068,8 @@ fn parseCallconv(p: *Parse) !Node.Index { | ... | @@ -3273,8 +3068,8 @@ fn parseCallconv(p: *Parse) !Node.Index { |
| 3273 | } | 3068 | } |
| 3274 | 3069 | ||
| 3275 | /// AddrSpace <- KEYWORD_addrspace LPAREN Expr RPAREN | 3070 | /// AddrSpace <- KEYWORD_addrspace LPAREN Expr RPAREN |
| 3276 | fn parseAddrSpace(p: *Parse) !Node.Index { | 3071 | fn parseAddrSpace(p: *Parse) !?Node.Index { |
| 3277 | _ = p.eatToken(.keyword_addrspace) orelse return null_node; | 3072 | _ = p.eatToken(.keyword_addrspace) orelse return null; |
| 3278 | _ = try p.expectToken(.l_paren); | 3073 | _ = try p.expectToken(.l_paren); |
| 3279 | const expr_node = try p.expectExpr(); | 3074 | const expr_node = try p.expectExpr(); |
| 3280 | _ = try p.expectToken(.r_paren); | 3075 | _ = try p.expectToken(.r_paren); |
| ... | @@ -3292,59 +3087,53 @@ fn parseAddrSpace(p: *Parse) !Node.Index { | ... | @@ -3292,59 +3087,53 @@ fn parseAddrSpace(p: *Parse) !Node.Index { |
| 3292 | /// ParamType | 3087 | /// ParamType |
| 3293 | /// <- KEYWORD_anytype | 3088 | /// <- KEYWORD_anytype |
| 3294 | /// / TypeExpr | 3089 | /// / TypeExpr |
| 3295 | fn expectParamDecl(p: *Parse) !Node.Index { | 3090 | fn expectParamDecl(p: *Parse) !?Node.Index { |
| 3296 | _ = try p.eatDocComments(); | 3091 | _ = try p.eatDocComments(); |
| 3297 | switch (p.token_tags[p.tok_i]) { | 3092 | switch (p.tokenTag(p.tok_i)) { |
| 3298 | .keyword_noalias, .keyword_comptime => p.tok_i += 1, | 3093 | .keyword_noalias, .keyword_comptime => p.tok_i += 1, |
| 3299 | .ellipsis3 => { | 3094 | .ellipsis3 => { |
| 3300 | p.tok_i += 1; | 3095 | p.tok_i += 1; |
| 3301 | return null_node; | 3096 | return null; |
| 3302 | }, | 3097 | }, |
| 3303 | else => {}, | 3098 | else => {}, |
| 3304 | } | 3099 | } |
| 3305 | if (p.token_tags[p.tok_i] == .identifier and | 3100 | _ = p.eatTokens(&.{ .identifier, .colon }); |
| 3306 | p.token_tags[p.tok_i + 1] == .colon) | 3101 | if (p.eatToken(.keyword_anytype)) |_| { |
| 3307 | { | 3102 | return null; |
| 3308 | p.tok_i += 2; | 3103 | } else { |
| 3309 | } | 3104 | return try p.expectTypeExpr(); |
| 3310 | switch (p.token_tags[p.tok_i]) { | ||
| 3311 | .keyword_anytype => { | ||
| 3312 | p.tok_i += 1; | ||
| 3313 | return null_node; | ||
| 3314 | }, | ||
| 3315 | else => return p.expectTypeExpr(), | ||
| 3316 | } | 3105 | } |
| 3317 | } | 3106 | } |
| 3318 | 3107 | ||
| 3319 | /// Payload <- PIPE IDENTIFIER PIPE | 3108 | /// Payload <- PIPE IDENTIFIER PIPE |
| 3320 | fn parsePayload(p: *Parse) !TokenIndex { | 3109 | fn parsePayload(p: *Parse) Error!OptionalTokenIndex { |
| 3321 | _ = p.eatToken(.pipe) orelse return null_node; | 3110 | _ = p.eatToken(.pipe) orelse return .none; |
| 3322 | const identifier = try p.expectToken(.identifier); | 3111 | const identifier = try p.expectToken(.identifier); |
| 3323 | _ = try p.expectToken(.pipe); | 3112 | _ = try p.expectToken(.pipe); |
| 3324 | return identifier; | 3113 | return .fromToken(identifier); |
| 3325 | } | 3114 | } |
| 3326 | 3115 | ||
| 3327 | /// PtrPayload <- PIPE ASTERISK? IDENTIFIER PIPE | 3116 | /// PtrPayload <- PIPE ASTERISK? IDENTIFIER PIPE |
| 3328 | fn parsePtrPayload(p: *Parse) !TokenIndex { | 3117 | fn parsePtrPayload(p: *Parse) Error!OptionalTokenIndex { |
| 3329 | _ = p.eatToken(.pipe) orelse return null_node; | 3118 | _ = p.eatToken(.pipe) orelse return .none; |
| 3330 | _ = p.eatToken(.asterisk); | 3119 | _ = p.eatToken(.asterisk); |
| 3331 | const identifier = try p.expectToken(.identifier); | 3120 | const identifier = try p.expectToken(.identifier); |
| 3332 | _ = try p.expectToken(.pipe); | 3121 | _ = try p.expectToken(.pipe); |
| 3333 | return identifier; | 3122 | return .fromToken(identifier); |
| 3334 | } | 3123 | } |
| 3335 | 3124 | ||
| 3336 | /// Returns the first identifier token, if any. | 3125 | /// Returns the first identifier token, if any. |
| 3337 | /// | 3126 | /// |
| 3338 | /// PtrIndexPayload <- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE | 3127 | /// PtrIndexPayload <- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE |
| 3339 | fn parsePtrIndexPayload(p: *Parse) !TokenIndex { | 3128 | fn parsePtrIndexPayload(p: *Parse) Error!OptionalTokenIndex { |
| 3340 | _ = p.eatToken(.pipe) orelse return null_node; | 3129 | _ = p.eatToken(.pipe) orelse return .none; |
| 3341 | _ = p.eatToken(.asterisk); | 3130 | _ = p.eatToken(.asterisk); |
| 3342 | const identifier = try p.expectToken(.identifier); | 3131 | const identifier = try p.expectToken(.identifier); |
| 3343 | if (p.eatToken(.comma) != null) { | 3132 | if (p.eatToken(.comma) != null) { |
| 3344 | _ = try p.expectToken(.identifier); | 3133 | _ = try p.expectToken(.identifier); |
| 3345 | } | 3134 | } |
| 3346 | _ = try p.expectToken(.pipe); | 3135 | _ = try p.expectToken(.pipe); |
| 3347 | return identifier; | 3136 | return .fromToken(identifier); |
| 3348 | } | 3137 | } |
| 3349 | 3138 | ||
| 3350 | /// SwitchProng <- KEYWORD_inline? SwitchCase EQUALRARROW PtrIndexPayload? AssignExpr | 3139 | /// SwitchProng <- KEYWORD_inline? SwitchCase EQUALRARROW PtrIndexPayload? AssignExpr |
| ... | @@ -3352,7 +3141,7 @@ fn parsePtrIndexPayload(p: *Parse) !TokenIndex { | ... | @@ -3352,7 +3141,7 @@ fn parsePtrIndexPayload(p: *Parse) !TokenIndex { |
| 3352 | /// SwitchCase | 3141 | /// SwitchCase |
| 3353 | /// <- SwitchItem (COMMA SwitchItem)* COMMA? | 3142 | /// <- SwitchItem (COMMA SwitchItem)* COMMA? |
| 3354 | /// / KEYWORD_else | 3143 | /// / KEYWORD_else |
| 3355 | fn parseSwitchProng(p: *Parse) !Node.Index { | 3144 | fn parseSwitchProng(p: *Parse) !?Node.Index { |
| 3356 | const scratch_top = p.scratch.items.len; | 3145 | const scratch_top = p.scratch.items.len; |
| 3357 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 3146 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 3358 | 3147 | ||
| ... | @@ -3360,97 +3149,92 @@ fn parseSwitchProng(p: *Parse) !Node.Index { | ... | @@ -3360,97 +3149,92 @@ fn parseSwitchProng(p: *Parse) !Node.Index { |
| 3360 | 3149 | ||
| 3361 | if (p.eatToken(.keyword_else) == null) { | 3150 | if (p.eatToken(.keyword_else) == null) { |
| 3362 | while (true) { | 3151 | while (true) { |
| 3363 | const item = try p.parseSwitchItem(); | 3152 | const item = try p.parseSwitchItem() orelse break; |
| 3364 | if (item == 0) break; | ||
| 3365 | try p.scratch.append(p.gpa, item); | 3153 | try p.scratch.append(p.gpa, item); |
| 3366 | if (p.eatToken(.comma) == null) break; | 3154 | if (p.eatToken(.comma) == null) break; |
| 3367 | } | 3155 | } |
| 3368 | if (scratch_top == p.scratch.items.len) { | 3156 | if (scratch_top == p.scratch.items.len) { |
| 3369 | if (is_inline) p.tok_i -= 1; | 3157 | if (is_inline) p.tok_i -= 1; |
| 3370 | return null_node; | 3158 | return null; |
| 3371 | } | 3159 | } |
| 3372 | } | 3160 | } |
| 3373 | const arrow_token = try p.expectToken(.equal_angle_bracket_right); | 3161 | const arrow_token = try p.expectToken(.equal_angle_bracket_right); |
| 3374 | _ = try p.parsePtrIndexPayload(); | 3162 | _ = try p.parsePtrIndexPayload(); |
| 3375 | 3163 | ||
| 3376 | const items = p.scratch.items[scratch_top..]; | 3164 | const items = p.scratch.items[scratch_top..]; |
| 3377 | switch (items.len) { | 3165 | if (items.len <= 1) { |
| 3378 | 0 => return p.addNode(.{ | 3166 | return try p.addNode(.{ |
| 3379 | .tag = if (is_inline) .switch_case_inline_one else .switch_case_one, | 3167 | .tag = if (is_inline) .switch_case_inline_one else .switch_case_one, |
| 3380 | .main_token = arrow_token, | 3168 | .main_token = arrow_token, |
| 3381 | .data = .{ | 3169 | .data = .{ .opt_node_and_node = .{ |
| 3382 | .lhs = 0, | 3170 | if (items.len >= 1) items[0].toOptional() else .none, |
| 3383 | .rhs = try p.expectSingleAssignExpr(), | 3171 | try p.expectSingleAssignExpr(), |
| 3384 | }, | 3172 | } }, |
| 3385 | }), | 3173 | }); |
| 3386 | 1 => return p.addNode(.{ | 3174 | } else { |
| 3387 | .tag = if (is_inline) .switch_case_inline_one else .switch_case_one, | 3175 | return try p.addNode(.{ |
| 3388 | .main_token = arrow_token, | ||
| 3389 | .data = .{ | ||
| 3390 | .lhs = items[0], | ||
| 3391 | .rhs = try p.expectSingleAssignExpr(), | ||
| 3392 | }, | ||
| 3393 | }), | ||
| 3394 | else => return p.addNode(.{ | ||
| 3395 | .tag = if (is_inline) .switch_case_inline else .switch_case, | 3176 | .tag = if (is_inline) .switch_case_inline else .switch_case, |
| 3396 | .main_token = arrow_token, | 3177 | .main_token = arrow_token, |
| 3397 | .data = .{ | 3178 | .data = .{ .extra_and_node = .{ |
| 3398 | .lhs = try p.addExtra(try p.listToSpan(items)), | 3179 | try p.addExtra(try p.listToSpan(items)), |
| 3399 | .rhs = try p.expectSingleAssignExpr(), | 3180 | try p.expectSingleAssignExpr(), |
| 3400 | }, | 3181 | } }, |
| 3401 | }), | 3182 | }); |
| 3402 | } | 3183 | } |
| 3403 | } | 3184 | } |
| 3404 | 3185 | ||
| 3405 | /// SwitchItem <- Expr (DOT3 Expr)? | 3186 | /// SwitchItem <- Expr (DOT3 Expr)? |
| 3406 | fn parseSwitchItem(p: *Parse) !Node.Index { | 3187 | fn parseSwitchItem(p: *Parse) !?Node.Index { |
| 3407 | const expr = try p.parseExpr(); | 3188 | const expr = try p.parseExpr() orelse return null; |
| 3408 | if (expr == 0) return null_node; | ||
| 3409 | 3189 | ||
| 3410 | if (p.eatToken(.ellipsis3)) |token| { | 3190 | if (p.eatToken(.ellipsis3)) |token| { |
| 3411 | return p.addNode(.{ | 3191 | return try p.addNode(.{ |
| 3412 | .tag = .switch_range, | 3192 | .tag = .switch_range, |
| 3413 | .main_token = token, | 3193 | .main_token = token, |
| 3414 | .data = .{ | 3194 | .data = .{ .node_and_node = .{ |
| 3415 | .lhs = expr, | 3195 | expr, |
| 3416 | .rhs = try p.expectExpr(), | 3196 | try p.expectExpr(), |
| 3417 | }, | 3197 | } }, |
| 3418 | }); | 3198 | }); |
| 3419 | } | 3199 | } |
| 3420 | return expr; | 3200 | return expr; |
| 3421 | } | 3201 | } |
| 3422 | 3202 | ||
| 3203 | /// The following invariant will hold: | ||
| 3204 | /// - `(bit_range_start == .none) == (bit_range_end == .none)` | ||
| 3205 | /// - `bit_range_start != .none` implies `align_node != .none` | ||
| 3206 | /// - `bit_range_end != .none` implies `align_node != .none` | ||
| 3423 | const PtrModifiers = struct { | 3207 | const PtrModifiers = struct { |
| 3424 | align_node: Node.Index, | 3208 | align_node: Node.OptionalIndex, |
| 3425 | addrspace_node: Node.Index, | 3209 | addrspace_node: Node.OptionalIndex, |
| 3426 | bit_range_start: Node.Index, | 3210 | bit_range_start: Node.OptionalIndex, |
| 3427 | bit_range_end: Node.Index, | 3211 | bit_range_end: Node.OptionalIndex, |
| 3428 | }; | 3212 | }; |
| 3429 | 3213 | ||
| 3430 | fn parsePtrModifiers(p: *Parse) !PtrModifiers { | 3214 | fn parsePtrModifiers(p: *Parse) !PtrModifiers { |
| 3431 | var result: PtrModifiers = .{ | 3215 | var result: PtrModifiers = .{ |
| 3432 | .align_node = 0, | 3216 | .align_node = .none, |
| 3433 | .addrspace_node = 0, | 3217 | .addrspace_node = .none, |
| 3434 | .bit_range_start = 0, | 3218 | .bit_range_start = .none, |
| 3435 | .bit_range_end = 0, | 3219 | .bit_range_end = .none, |
| 3436 | }; | 3220 | }; |
| 3437 | var saw_const = false; | 3221 | var saw_const = false; |
| 3438 | var saw_volatile = false; | 3222 | var saw_volatile = false; |
| 3439 | var saw_allowzero = false; | 3223 | var saw_allowzero = false; |
| 3440 | while (true) { | 3224 | while (true) { |
| 3441 | switch (p.token_tags[p.tok_i]) { | 3225 | switch (p.tokenTag(p.tok_i)) { |
| 3442 | .keyword_align => { | 3226 | .keyword_align => { |
| 3443 | if (result.align_node != 0) { | 3227 | if (result.align_node != .none) { |
| 3444 | try p.warn(.extra_align_qualifier); | 3228 | try p.warn(.extra_align_qualifier); |
| 3445 | } | 3229 | } |
| 3446 | p.tok_i += 1; | 3230 | p.tok_i += 1; |
| 3447 | _ = try p.expectToken(.l_paren); | 3231 | _ = try p.expectToken(.l_paren); |
| 3448 | result.align_node = try p.expectExpr(); | 3232 | result.align_node = (try p.expectExpr()).toOptional(); |
| 3449 | 3233 | ||
| 3450 | if (p.eatToken(.colon)) |_| { | 3234 | if (p.eatToken(.colon)) |_| { |
| 3451 | result.bit_range_start = try p.expectExpr(); | 3235 | result.bit_range_start = (try p.expectExpr()).toOptional(); |
| 3452 | _ = try p.expectToken(.colon); | 3236 | _ = try p.expectToken(.colon); |
| 3453 | result.bit_range_end = try p.expectExpr(); | 3237 | result.bit_range_end = (try p.expectExpr()).toOptional(); |
| 3454 | } | 3238 | } |
| 3455 | 3239 | ||
| 3456 | _ = try p.expectToken(.r_paren); | 3240 | _ = try p.expectToken(.r_paren); |
| ... | @@ -3477,10 +3261,10 @@ fn parsePtrModifiers(p: *Parse) !PtrModifiers { | ... | @@ -3477,10 +3261,10 @@ fn parsePtrModifiers(p: *Parse) !PtrModifiers { |
| 3477 | saw_allowzero = true; | 3261 | saw_allowzero = true; |
| 3478 | }, | 3262 | }, |
| 3479 | .keyword_addrspace => { | 3263 | .keyword_addrspace => { |
| 3480 | if (result.addrspace_node != 0) { | 3264 | if (result.addrspace_node != .none) { |
| 3481 | try p.warn(.extra_addrspace_qualifier); | 3265 | try p.warn(.extra_addrspace_qualifier); |
| 3482 | } | 3266 | } |
| 3483 | result.addrspace_node = try p.parseAddrSpace(); | 3267 | result.addrspace_node = .fromOptional(try p.parseAddrSpace()); |
| 3484 | }, | 3268 | }, |
| 3485 | else => return result, | 3269 | else => return result, |
| 3486 | } | 3270 | } |
| ... | @@ -3492,110 +3276,102 @@ fn parsePtrModifiers(p: *Parse) !PtrModifiers { | ... | @@ -3492,110 +3276,102 @@ fn parsePtrModifiers(p: *Parse) !PtrModifiers { |
| 3492 | /// / DOT IDENTIFIER | 3276 | /// / DOT IDENTIFIER |
| 3493 | /// / DOTASTERISK | 3277 | /// / DOTASTERISK |
| 3494 | /// / DOTQUESTIONMARK | 3278 | /// / DOTQUESTIONMARK |
| 3495 | fn parseSuffixOp(p: *Parse, lhs: Node.Index) !Node.Index { | 3279 | fn parseSuffixOp(p: *Parse, lhs: Node.Index) !?Node.Index { |
| 3496 | switch (p.token_tags[p.tok_i]) { | 3280 | switch (p.tokenTag(p.tok_i)) { |
| 3497 | .l_bracket => { | 3281 | .l_bracket => { |
| 3498 | const lbracket = p.nextToken(); | 3282 | const lbracket = p.nextToken(); |
| 3499 | const index_expr = try p.expectExpr(); | 3283 | const index_expr = try p.expectExpr(); |
| 3500 | 3284 | ||
| 3501 | if (p.eatToken(.ellipsis2)) |_| { | 3285 | if (p.eatToken(.ellipsis2)) |_| { |
| 3502 | const end_expr = try p.parseExpr(); | 3286 | const opt_end_expr = try p.parseExpr(); |
| 3503 | if (p.eatToken(.colon)) |_| { | 3287 | if (p.eatToken(.colon)) |_| { |
| 3504 | const sentinel = try p.expectExpr(); | 3288 | const sentinel = try p.expectExpr(); |
| 3505 | _ = try p.expectToken(.r_bracket); | 3289 | _ = try p.expectToken(.r_bracket); |
| 3506 | return p.addNode(.{ | 3290 | return try p.addNode(.{ |
| 3507 | .tag = .slice_sentinel, | 3291 | .tag = .slice_sentinel, |
| 3508 | .main_token = lbracket, | 3292 | .main_token = lbracket, |
| 3509 | .data = .{ | 3293 | .data = .{ .node_and_extra = .{ |
| 3510 | .lhs = lhs, | 3294 | lhs, try p.addExtra(Node.SliceSentinel{ |
| 3511 | .rhs = try p.addExtra(Node.SliceSentinel{ | ||
| 3512 | .start = index_expr, | 3295 | .start = index_expr, |
| 3513 | .end = end_expr, | 3296 | .end = .fromOptional(opt_end_expr), |
| 3514 | .sentinel = sentinel, | 3297 | .sentinel = sentinel, |
| 3515 | }), | 3298 | }), |
| 3516 | }, | 3299 | } }, |
| 3517 | }); | 3300 | }); |
| 3518 | } | 3301 | } |
| 3519 | _ = try p.expectToken(.r_bracket); | 3302 | _ = try p.expectToken(.r_bracket); |
| 3520 | if (end_expr == 0) { | 3303 | const end_expr = opt_end_expr orelse { |
| 3521 | return p.addNode(.{ | 3304 | return try p.addNode(.{ |
| 3522 | .tag = .slice_open, | 3305 | .tag = .slice_open, |
| 3523 | .main_token = lbracket, | 3306 | .main_token = lbracket, |
| 3524 | .data = .{ | 3307 | .data = .{ .node_and_node = .{ |
| 3525 | .lhs = lhs, | 3308 | lhs, |
| 3526 | .rhs = index_expr, | 3309 | index_expr, |
| 3527 | }, | 3310 | } }, |
| 3528 | }); | 3311 | }); |
| 3529 | } | 3312 | }; |
| 3530 | return p.addNode(.{ | 3313 | return try p.addNode(.{ |
| 3531 | .tag = .slice, | 3314 | .tag = .slice, |
| 3532 | .main_token = lbracket, | 3315 | .main_token = lbracket, |
| 3533 | .data = .{ | 3316 | .data = .{ .node_and_extra = .{ |
| 3534 | .lhs = lhs, | 3317 | lhs, try p.addExtra(Node.Slice{ |
| 3535 | .rhs = try p.addExtra(Node.Slice{ | ||
| 3536 | .start = index_expr, | 3318 | .start = index_expr, |
| 3537 | .end = end_expr, | 3319 | .end = end_expr, |
| 3538 | }), | 3320 | }), |
| 3539 | }, | 3321 | } }, |
| 3540 | }); | 3322 | }); |
| 3541 | } | 3323 | } |
| 3542 | _ = try p.expectToken(.r_bracket); | 3324 | _ = try p.expectToken(.r_bracket); |
| 3543 | return p.addNode(.{ | 3325 | return try p.addNode(.{ |
| 3544 | .tag = .array_access, | 3326 | .tag = .array_access, |
| 3545 | .main_token = lbracket, | 3327 | .main_token = lbracket, |
| 3546 | .data = .{ | 3328 | .data = .{ .node_and_node = .{ |
| 3547 | .lhs = lhs, | 3329 | lhs, |
| 3548 | .rhs = index_expr, | 3330 | index_expr, |
| 3549 | }, | 3331 | } }, |
| 3550 | }); | 3332 | }); |
| 3551 | }, | 3333 | }, |
| 3552 | .period_asterisk => return p.addNode(.{ | 3334 | .period_asterisk => return try p.addNode(.{ |
| 3553 | .tag = .deref, | 3335 | .tag = .deref, |
| 3554 | .main_token = p.nextToken(), | 3336 | .main_token = p.nextToken(), |
| 3555 | .data = .{ | 3337 | .data = .{ .node = lhs }, |
| 3556 | .lhs = lhs, | ||
| 3557 | .rhs = undefined, | ||
| 3558 | }, | ||
| 3559 | }), | 3338 | }), |
| 3560 | .invalid_periodasterisks => { | 3339 | .invalid_periodasterisks => { |
| 3561 | try p.warn(.asterisk_after_ptr_deref); | 3340 | try p.warn(.asterisk_after_ptr_deref); |
| 3562 | return p.addNode(.{ | 3341 | return try p.addNode(.{ |
| 3563 | .tag = .deref, | 3342 | .tag = .deref, |
| 3564 | .main_token = p.nextToken(), | 3343 | .main_token = p.nextToken(), |
| 3565 | .data = .{ | 3344 | .data = .{ .node = lhs }, |
| 3566 | .lhs = lhs, | ||
| 3567 | .rhs = undefined, | ||
| 3568 | }, | ||
| 3569 | }); | 3345 | }); |
| 3570 | }, | 3346 | }, |
| 3571 | .period => switch (p.token_tags[p.tok_i + 1]) { | 3347 | .period => switch (p.tokenTag(p.tok_i + 1)) { |
| 3572 | .identifier => return p.addNode(.{ | 3348 | .identifier => return try p.addNode(.{ |
| 3573 | .tag = .field_access, | 3349 | .tag = .field_access, |
| 3574 | .main_token = p.nextToken(), | 3350 | .main_token = p.nextToken(), |
| 3575 | .data = .{ | 3351 | .data = .{ .node_and_token = .{ |
| 3576 | .lhs = lhs, | 3352 | lhs, |
| 3577 | .rhs = p.nextToken(), | 3353 | p.nextToken(), |
| 3578 | }, | 3354 | } }, |
| 3579 | }), | 3355 | }), |
| 3580 | .question_mark => return p.addNode(.{ | 3356 | .question_mark => return try p.addNode(.{ |
| 3581 | .tag = .unwrap_optional, | 3357 | .tag = .unwrap_optional, |
| 3582 | .main_token = p.nextToken(), | 3358 | .main_token = p.nextToken(), |
| 3583 | .data = .{ | 3359 | .data = .{ .node_and_token = .{ |
| 3584 | .lhs = lhs, | 3360 | lhs, |
| 3585 | .rhs = p.nextToken(), | 3361 | p.nextToken(), |
| 3586 | }, | 3362 | } }, |
| 3587 | }), | 3363 | }), |
| 3588 | .l_brace => { | 3364 | .l_brace => { |
| 3589 | // this a misplaced `.{`, handle the error somewhere else | 3365 | // this a misplaced `.{`, handle the error somewhere else |
| 3590 | return null_node; | 3366 | return null; |
| 3591 | }, | 3367 | }, |
| 3592 | else => { | 3368 | else => { |
| 3593 | p.tok_i += 1; | 3369 | p.tok_i += 1; |
| 3594 | try p.warn(.expected_suffix_op); | 3370 | try p.warn(.expected_suffix_op); |
| 3595 | return null_node; | 3371 | return null; |
| 3596 | }, | 3372 | }, |
| 3597 | }, | 3373 | }, |
| 3598 | else => return null_node, | 3374 | else => return null, |
| 3599 | } | 3375 | } |
| 3600 | } | 3376 | } |
| 3601 | 3377 | ||
| ... | @@ -3608,17 +3384,17 @@ fn parseSuffixOp(p: *Parse, lhs: Node.Index) !Node.Index { | ... | @@ -3608,17 +3384,17 @@ fn parseSuffixOp(p: *Parse, lhs: Node.Index) !Node.Index { |
| 3608 | /// / KEYWORD_opaque | 3384 | /// / KEYWORD_opaque |
| 3609 | /// / KEYWORD_enum (LPAREN Expr RPAREN)? | 3385 | /// / KEYWORD_enum (LPAREN Expr RPAREN)? |
| 3610 | /// / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)? | 3386 | /// / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)? |
| 3611 | fn parseContainerDeclAuto(p: *Parse) !Node.Index { | 3387 | fn parseContainerDeclAuto(p: *Parse) !?Node.Index { |
| 3612 | const main_token = p.nextToken(); | 3388 | const main_token = p.nextToken(); |
| 3613 | const arg_expr = switch (p.token_tags[main_token]) { | 3389 | const arg_expr = switch (p.tokenTag(main_token)) { |
| 3614 | .keyword_opaque => null_node, | 3390 | .keyword_opaque => null, |
| 3615 | .keyword_struct, .keyword_enum => blk: { | 3391 | .keyword_struct, .keyword_enum => blk: { |
| 3616 | if (p.eatToken(.l_paren)) |_| { | 3392 | if (p.eatToken(.l_paren)) |_| { |
| 3617 | const expr = try p.expectExpr(); | 3393 | const expr = try p.expectExpr(); |
| 3618 | _ = try p.expectToken(.r_paren); | 3394 | _ = try p.expectToken(.r_paren); |
| 3619 | break :blk expr; | 3395 | break :blk expr; |
| 3620 | } else { | 3396 | } else { |
| 3621 | break :blk null_node; | 3397 | break :blk null; |
| 3622 | } | 3398 | } |
| 3623 | }, | 3399 | }, |
| 3624 | .keyword_union => blk: { | 3400 | .keyword_union => blk: { |
| ... | @@ -3633,16 +3409,16 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { | ... | @@ -3633,16 +3409,16 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { |
| 3633 | const members = try p.parseContainerMembers(); | 3409 | const members = try p.parseContainerMembers(); |
| 3634 | const members_span = try members.toSpan(p); | 3410 | const members_span = try members.toSpan(p); |
| 3635 | _ = try p.expectToken(.r_brace); | 3411 | _ = try p.expectToken(.r_brace); |
| 3636 | return p.addNode(.{ | 3412 | return try p.addNode(.{ |
| 3637 | .tag = switch (members.trailing) { | 3413 | .tag = switch (members.trailing) { |
| 3638 | true => .tagged_union_enum_tag_trailing, | 3414 | true => .tagged_union_enum_tag_trailing, |
| 3639 | false => .tagged_union_enum_tag, | 3415 | false => .tagged_union_enum_tag, |
| 3640 | }, | 3416 | }, |
| 3641 | .main_token = main_token, | 3417 | .main_token = main_token, |
| 3642 | .data = .{ | 3418 | .data = .{ .node_and_extra = .{ |
| 3643 | .lhs = enum_tag_expr, | 3419 | enum_tag_expr, |
| 3644 | .rhs = try p.addExtra(members_span), | 3420 | try p.addExtra(members_span), |
| 3645 | }, | 3421 | } }, |
| 3646 | }); | 3422 | }); |
| 3647 | } else { | 3423 | } else { |
| 3648 | _ = try p.expectToken(.r_paren); | 3424 | _ = try p.expectToken(.r_paren); |
| ... | @@ -3651,29 +3427,23 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { | ... | @@ -3651,29 +3427,23 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { |
| 3651 | const members = try p.parseContainerMembers(); | 3427 | const members = try p.parseContainerMembers(); |
| 3652 | _ = try p.expectToken(.r_brace); | 3428 | _ = try p.expectToken(.r_brace); |
| 3653 | if (members.len <= 2) { | 3429 | if (members.len <= 2) { |
| 3654 | return p.addNode(.{ | 3430 | return try p.addNode(.{ |
| 3655 | .tag = switch (members.trailing) { | 3431 | .tag = switch (members.trailing) { |
| 3656 | true => .tagged_union_two_trailing, | 3432 | true => .tagged_union_two_trailing, |
| 3657 | false => .tagged_union_two, | 3433 | false => .tagged_union_two, |
| 3658 | }, | 3434 | }, |
| 3659 | .main_token = main_token, | 3435 | .main_token = main_token, |
| 3660 | .data = .{ | 3436 | .data = members.data, |
| 3661 | .lhs = members.lhs, | ||
| 3662 | .rhs = members.rhs, | ||
| 3663 | }, | ||
| 3664 | }); | 3437 | }); |
| 3665 | } else { | 3438 | } else { |
| 3666 | const span = try members.toSpan(p); | 3439 | const span = try members.toSpan(p); |
| 3667 | return p.addNode(.{ | 3440 | return try p.addNode(.{ |
| 3668 | .tag = switch (members.trailing) { | 3441 | .tag = switch (members.trailing) { |
| 3669 | true => .tagged_union_trailing, | 3442 | true => .tagged_union_trailing, |
| 3670 | false => .tagged_union, | 3443 | false => .tagged_union, |
| 3671 | }, | 3444 | }, |
| 3672 | .main_token = main_token, | 3445 | .main_token = main_token, |
| 3673 | .data = .{ | 3446 | .data = .{ .extra_range = span }, |
| 3674 | .lhs = span.start, | ||
| 3675 | .rhs = span.end, | ||
| 3676 | }, | ||
| 3677 | }); | 3447 | }); |
| 3678 | } | 3448 | } |
| 3679 | } | 3449 | } |
| ... | @@ -3683,7 +3453,7 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { | ... | @@ -3683,7 +3453,7 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { |
| 3683 | break :blk expr; | 3453 | break :blk expr; |
| 3684 | } | 3454 | } |
| 3685 | } else { | 3455 | } else { |
| 3686 | break :blk null_node; | 3456 | break :blk null; |
| 3687 | } | 3457 | } |
| 3688 | }, | 3458 | }, |
| 3689 | else => { | 3459 | else => { |
| ... | @@ -3694,48 +3464,42 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { | ... | @@ -3694,48 +3464,42 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { |
| 3694 | _ = try p.expectToken(.l_brace); | 3464 | _ = try p.expectToken(.l_brace); |
| 3695 | const members = try p.parseContainerMembers(); | 3465 | const members = try p.parseContainerMembers(); |
| 3696 | _ = try p.expectToken(.r_brace); | 3466 | _ = try p.expectToken(.r_brace); |
| 3697 | if (arg_expr == 0) { | 3467 | if (arg_expr == null) { |
| 3698 | if (members.len <= 2) { | 3468 | if (members.len <= 2) { |
| 3699 | return p.addNode(.{ | 3469 | return try p.addNode(.{ |
| 3700 | .tag = switch (members.trailing) { | 3470 | .tag = switch (members.trailing) { |
| 3701 | true => .container_decl_two_trailing, | 3471 | true => .container_decl_two_trailing, |
| 3702 | false => .container_decl_two, | 3472 | false => .container_decl_two, |
| 3703 | }, | 3473 | }, |
| 3704 | .main_token = main_token, | 3474 | .main_token = main_token, |
| 3705 | .data = .{ | 3475 | .data = members.data, |
| 3706 | .lhs = members.lhs, | ||
| 3707 | .rhs = members.rhs, | ||
| 3708 | }, | ||
| 3709 | }); | 3476 | }); |
| 3710 | } else { | 3477 | } else { |
| 3711 | const span = try members.toSpan(p); | 3478 | const span = try members.toSpan(p); |
| 3712 | return p.addNode(.{ | 3479 | return try p.addNode(.{ |
| 3713 | .tag = switch (members.trailing) { | 3480 | .tag = switch (members.trailing) { |
| 3714 | true => .container_decl_trailing, | 3481 | true => .container_decl_trailing, |
| 3715 | false => .container_decl, | 3482 | false => .container_decl, |
| 3716 | }, | 3483 | }, |
| 3717 | .main_token = main_token, | 3484 | .main_token = main_token, |
| 3718 | .data = .{ | 3485 | .data = .{ .extra_range = span }, |
| 3719 | .lhs = span.start, | ||
| 3720 | .rhs = span.end, | ||
| 3721 | }, | ||
| 3722 | }); | 3486 | }); |
| 3723 | } | 3487 | } |
| 3724 | } else { | 3488 | } else { |
| 3725 | const span = try members.toSpan(p); | 3489 | const span = try members.toSpan(p); |
| 3726 | return p.addNode(.{ | 3490 | return try p.addNode(.{ |
| 3727 | .tag = switch (members.trailing) { | 3491 | .tag = switch (members.trailing) { |
| 3728 | true => .container_decl_arg_trailing, | 3492 | true => .container_decl_arg_trailing, |
| 3729 | false => .container_decl_arg, | 3493 | false => .container_decl_arg, |
| 3730 | }, | 3494 | }, |
| 3731 | .main_token = main_token, | 3495 | .main_token = main_token, |
| 3732 | .data = .{ | 3496 | .data = .{ .node_and_extra = .{ |
| 3733 | .lhs = arg_expr, | 3497 | arg_expr.?, |
| 3734 | .rhs = try p.addExtra(Node.SubRange{ | 3498 | try p.addExtra(Node.SubRange{ |
| 3735 | .start = span.start, | 3499 | .start = span.start, |
| 3736 | .end = span.end, | 3500 | .end = span.end, |
| 3737 | }), | 3501 | }), |
| 3738 | }, | 3502 | } }, |
| 3739 | }); | 3503 | }); |
| 3740 | } | 3504 | } |
| 3741 | } | 3505 | } |
| ... | @@ -3744,24 +3508,24 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { | ... | @@ -3744,24 +3508,24 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { |
| 3744 | /// C's 'struct Foo {};' to Zig's 'const Foo = struct {};'. | 3508 | /// C's 'struct Foo {};' to Zig's 'const Foo = struct {};'. |
| 3745 | fn parseCStyleContainer(p: *Parse) Error!bool { | 3509 | fn parseCStyleContainer(p: *Parse) Error!bool { |
| 3746 | const main_token = p.tok_i; | 3510 | const main_token = p.tok_i; |
| 3747 | switch (p.token_tags[p.tok_i]) { | 3511 | switch (p.tokenTag(p.tok_i)) { |
| 3748 | .keyword_enum, .keyword_union, .keyword_struct => {}, | 3512 | .keyword_enum, .keyword_union, .keyword_struct => {}, |
| 3749 | else => return false, | 3513 | else => return false, |
| 3750 | } | 3514 | } |
| 3751 | const identifier = p.tok_i + 1; | 3515 | const identifier = p.tok_i + 1; |
| 3752 | if (p.token_tags[identifier] != .identifier) return false; | 3516 | if (p.tokenTag(identifier) != .identifier) return false; |
| 3753 | p.tok_i += 2; | 3517 | p.tok_i += 2; |
| 3754 | 3518 | ||
| 3755 | try p.warnMsg(.{ | 3519 | try p.warnMsg(.{ |
| 3756 | .tag = .c_style_container, | 3520 | .tag = .c_style_container, |
| 3757 | .token = identifier, | 3521 | .token = identifier, |
| 3758 | .extra = .{ .expected_tag = p.token_tags[main_token] }, | 3522 | .extra = .{ .expected_tag = p.tokenTag(main_token) }, |
| 3759 | }); | 3523 | }); |
| 3760 | try p.warnMsg(.{ | 3524 | try p.warnMsg(.{ |
| 3761 | .tag = .zig_style_container, | 3525 | .tag = .zig_style_container, |
| 3762 | .is_note = true, | 3526 | .is_note = true, |
| 3763 | .token = identifier, | 3527 | .token = identifier, |
| 3764 | .extra = .{ .expected_tag = p.token_tags[main_token] }, | 3528 | .extra = .{ .expected_tag = p.tokenTag(main_token) }, |
| 3765 | }); | 3529 | }); |
| 3766 | 3530 | ||
| 3767 | _ = try p.expectToken(.l_brace); | 3531 | _ = try p.expectToken(.l_brace); |
| ... | @@ -3774,8 +3538,8 @@ fn parseCStyleContainer(p: *Parse) Error!bool { | ... | @@ -3774,8 +3538,8 @@ fn parseCStyleContainer(p: *Parse) Error!bool { |
| 3774 | /// Holds temporary data until we are ready to construct the full ContainerDecl AST node. | 3538 | /// Holds temporary data until we are ready to construct the full ContainerDecl AST node. |
| 3775 | /// | 3539 | /// |
| 3776 | /// ByteAlign <- KEYWORD_align LPAREN Expr RPAREN | 3540 | /// ByteAlign <- KEYWORD_align LPAREN Expr RPAREN |
| 3777 | fn parseByteAlign(p: *Parse) !Node.Index { | 3541 | fn parseByteAlign(p: *Parse) !?Node.Index { |
| 3778 | _ = p.eatToken(.keyword_align) orelse return null_node; | 3542 | _ = p.eatToken(.keyword_align) orelse return null; |
| 3779 | _ = try p.expectToken(.l_paren); | 3543 | _ = try p.expectToken(.l_paren); |
| 3780 | const expr = try p.expectExpr(); | 3544 | const expr = try p.expectExpr(); |
| 3781 | _ = try p.expectToken(.r_paren); | 3545 | _ = try p.expectToken(.r_paren); |
| ... | @@ -3788,12 +3552,11 @@ fn parseSwitchProngList(p: *Parse) !Node.SubRange { | ... | @@ -3788,12 +3552,11 @@ fn parseSwitchProngList(p: *Parse) !Node.SubRange { |
| 3788 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 3552 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 3789 | 3553 | ||
| 3790 | while (true) { | 3554 | while (true) { |
| 3791 | const item = try parseSwitchProng(p); | 3555 | const item = try parseSwitchProng(p) orelse break; |
| 3792 | if (item == 0) break; | ||
| 3793 | 3556 | ||
| 3794 | try p.scratch.append(p.gpa, item); | 3557 | try p.scratch.append(p.gpa, item); |
| 3795 | 3558 | ||
| 3796 | switch (p.token_tags[p.tok_i]) { | 3559 | switch (p.tokenTag(p.tok_i)) { |
| 3797 | .comma => p.tok_i += 1, | 3560 | .comma => p.tok_i += 1, |
| 3798 | // All possible delimiters. | 3561 | // All possible delimiters. |
| 3799 | .colon, .r_paren, .r_brace, .r_bracket => break, | 3562 | .colon, .r_paren, .r_brace, .r_bracket => break, |
| ... | @@ -3813,13 +3576,13 @@ fn parseParamDeclList(p: *Parse) !SmallSpan { | ... | @@ -3813,13 +3576,13 @@ fn parseParamDeclList(p: *Parse) !SmallSpan { |
| 3813 | while (true) { | 3576 | while (true) { |
| 3814 | if (p.eatToken(.r_paren)) |_| break; | 3577 | if (p.eatToken(.r_paren)) |_| break; |
| 3815 | if (varargs == .seen) varargs = .{ .nonfinal = p.tok_i }; | 3578 | if (varargs == .seen) varargs = .{ .nonfinal = p.tok_i }; |
| 3816 | const param = try p.expectParamDecl(); | 3579 | const opt_param = try p.expectParamDecl(); |
| 3817 | if (param != 0) { | 3580 | if (opt_param) |param| { |
| 3818 | try p.scratch.append(p.gpa, param); | 3581 | try p.scratch.append(p.gpa, param); |
| 3819 | } else if (p.token_tags[p.tok_i - 1] == .ellipsis3) { | 3582 | } else if (p.tokenTag(p.tok_i - 1) == .ellipsis3) { |
| 3820 | if (varargs == .none) varargs = .seen; | 3583 | if (varargs == .none) varargs = .seen; |
| 3821 | } | 3584 | } |
| 3822 | switch (p.token_tags[p.tok_i]) { | 3585 | switch (p.tokenTag(p.tok_i)) { |
| 3823 | .comma => p.tok_i += 1, | 3586 | .comma => p.tok_i += 1, |
| 3824 | .r_paren => { | 3587 | .r_paren => { |
| 3825 | p.tok_i += 1; | 3588 | p.tok_i += 1; |
| ... | @@ -3835,9 +3598,9 @@ fn parseParamDeclList(p: *Parse) !SmallSpan { | ... | @@ -3835,9 +3598,9 @@ fn parseParamDeclList(p: *Parse) !SmallSpan { |
| 3835 | } | 3598 | } |
| 3836 | const params = p.scratch.items[scratch_top..]; | 3599 | const params = p.scratch.items[scratch_top..]; |
| 3837 | return switch (params.len) { | 3600 | return switch (params.len) { |
| 3838 | 0 => SmallSpan{ .zero_or_one = 0 }, | 3601 | 0 => .{ .zero_or_one = .none }, |
| 3839 | 1 => SmallSpan{ .zero_or_one = params[0] }, | 3602 | 1 => .{ .zero_or_one = params[0].toOptional() }, |
| 3840 | else => SmallSpan{ .multi = try p.listToSpan(params) }, | 3603 | else => .{ .multi = try p.listToSpan(params) }, |
| 3841 | }; | 3604 | }; |
| 3842 | } | 3605 | } |
| 3843 | 3606 | ||
| ... | @@ -3852,10 +3615,7 @@ fn parseBuiltinCall(p: *Parse) !Node.Index { | ... | @@ -3852,10 +3615,7 @@ fn parseBuiltinCall(p: *Parse) !Node.Index { |
| 3852 | return p.addNode(.{ | 3615 | return p.addNode(.{ |
| 3853 | .tag = .identifier, | 3616 | .tag = .identifier, |
| 3854 | .main_token = builtin_token, | 3617 | .main_token = builtin_token, |
| 3855 | .data = .{ | 3618 | .data = undefined, |
| 3856 | .lhs = undefined, | ||
| 3857 | .rhs = undefined, | ||
| 3858 | }, | ||
| 3859 | }); | 3619 | }); |
| 3860 | }; | 3620 | }; |
| 3861 | const scratch_top = p.scratch.items.len; | 3621 | const scratch_top = p.scratch.items.len; |
| ... | @@ -3864,7 +3624,7 @@ fn parseBuiltinCall(p: *Parse) !Node.Index { | ... | @@ -3864,7 +3624,7 @@ fn parseBuiltinCall(p: *Parse) !Node.Index { |
| 3864 | if (p.eatToken(.r_paren)) |_| break; | 3624 | if (p.eatToken(.r_paren)) |_| break; |
| 3865 | const param = try p.expectExpr(); | 3625 | const param = try p.expectExpr(); |
| 3866 | try p.scratch.append(p.gpa, param); | 3626 | try p.scratch.append(p.gpa, param); |
| 3867 | switch (p.token_tags[p.tok_i]) { | 3627 | switch (p.tokenTag(p.tok_i)) { |
| 3868 | .comma => p.tok_i += 1, | 3628 | .comma => p.tok_i += 1, |
| 3869 | .r_paren => { | 3629 | .r_paren => { |
| 3870 | p.tok_i += 1; | 3630 | p.tok_i += 1; |
| ... | @@ -3874,88 +3634,66 @@ fn parseBuiltinCall(p: *Parse) !Node.Index { | ... | @@ -3874,88 +3634,66 @@ fn parseBuiltinCall(p: *Parse) !Node.Index { |
| 3874 | else => try p.warn(.expected_comma_after_arg), | 3634 | else => try p.warn(.expected_comma_after_arg), |
| 3875 | } | 3635 | } |
| 3876 | } | 3636 | } |
| 3877 | const comma = (p.token_tags[p.tok_i - 2] == .comma); | 3637 | const comma = (p.tokenTag(p.tok_i - 2)) == .comma; |
| 3878 | const params = p.scratch.items[scratch_top..]; | 3638 | const params = p.scratch.items[scratch_top..]; |
| 3879 | switch (params.len) { | 3639 | if (params.len <= 2) { |
| 3880 | 0 => return p.addNode(.{ | 3640 | return p.addNode(.{ |
| 3881 | .tag = .builtin_call_two, | ||
| 3882 | .main_token = builtin_token, | ||
| 3883 | .data = .{ | ||
| 3884 | .lhs = 0, | ||
| 3885 | .rhs = 0, | ||
| 3886 | }, | ||
| 3887 | }), | ||
| 3888 | 1 => return p.addNode(.{ | ||
| 3889 | .tag = if (comma) .builtin_call_two_comma else .builtin_call_two, | 3641 | .tag = if (comma) .builtin_call_two_comma else .builtin_call_two, |
| 3890 | .main_token = builtin_token, | 3642 | .main_token = builtin_token, |
| 3891 | .data = .{ | 3643 | .data = .{ .opt_node_and_opt_node = .{ |
| 3892 | .lhs = params[0], | 3644 | if (params.len >= 1) .fromOptional(params[0]) else .none, |
| 3893 | .rhs = 0, | 3645 | if (params.len >= 2) .fromOptional(params[1]) else .none, |
| 3894 | }, | 3646 | } }, |
| 3895 | }), | 3647 | }); |
| 3896 | 2 => return p.addNode(.{ | 3648 | } else { |
| 3897 | .tag = if (comma) .builtin_call_two_comma else .builtin_call_two, | 3649 | const span = try p.listToSpan(params); |
| 3650 | return p.addNode(.{ | ||
| 3651 | .tag = if (comma) .builtin_call_comma else .builtin_call, | ||
| 3898 | .main_token = builtin_token, | 3652 | .main_token = builtin_token, |
| 3899 | .data = .{ | 3653 | .data = .{ .extra_range = span }, |
| 3900 | .lhs = params[0], | 3654 | }); |
| 3901 | .rhs = params[1], | ||
| 3902 | }, | ||
| 3903 | }), | ||
| 3904 | else => { | ||
| 3905 | const span = try p.listToSpan(params); | ||
| 3906 | return p.addNode(.{ | ||
| 3907 | .tag = if (comma) .builtin_call_comma else .builtin_call, | ||
| 3908 | .main_token = builtin_token, | ||
| 3909 | .data = .{ | ||
| 3910 | .lhs = span.start, | ||
| 3911 | .rhs = span.end, | ||
| 3912 | }, | ||
| 3913 | }); | ||
| 3914 | }, | ||
| 3915 | } | 3655 | } |
| 3916 | } | 3656 | } |
| 3917 | 3657 | ||
| 3918 | /// IfPrefix <- KEYWORD_if LPAREN Expr RPAREN PtrPayload? | 3658 | /// IfPrefix <- KEYWORD_if LPAREN Expr RPAREN PtrPayload? |
| 3919 | fn parseIf(p: *Parse, comptime bodyParseFn: fn (p: *Parse) Error!Node.Index) !Node.Index { | 3659 | fn parseIf(p: *Parse, comptime bodyParseFn: fn (p: *Parse) Error!Node.Index) !?Node.Index { |
| 3920 | const if_token = p.eatToken(.keyword_if) orelse return null_node; | 3660 | const if_token = p.eatToken(.keyword_if) orelse return null; |
| 3921 | _ = try p.expectToken(.l_paren); | 3661 | _ = try p.expectToken(.l_paren); |
| 3922 | const condition = try p.expectExpr(); | 3662 | const condition = try p.expectExpr(); |
| 3923 | _ = try p.expectToken(.r_paren); | 3663 | _ = try p.expectToken(.r_paren); |
| 3924 | _ = try p.parsePtrPayload(); | 3664 | _ = try p.parsePtrPayload(); |
| 3925 | 3665 | ||
| 3926 | const then_expr = try bodyParseFn(p); | 3666 | const then_expr = try bodyParseFn(p); |
| 3927 | assert(then_expr != 0); | ||
| 3928 | 3667 | ||
| 3929 | _ = p.eatToken(.keyword_else) orelse return p.addNode(.{ | 3668 | _ = p.eatToken(.keyword_else) orelse return try p.addNode(.{ |
| 3930 | .tag = .if_simple, | 3669 | .tag = .if_simple, |
| 3931 | .main_token = if_token, | 3670 | .main_token = if_token, |
| 3932 | .data = .{ | 3671 | .data = .{ .node_and_node = .{ |
| 3933 | .lhs = condition, | 3672 | condition, |
| 3934 | .rhs = then_expr, | 3673 | then_expr, |
| 3935 | }, | 3674 | } }, |
| 3936 | }); | 3675 | }); |
| 3937 | _ = try p.parsePayload(); | 3676 | _ = try p.parsePayload(); |
| 3938 | const else_expr = try bodyParseFn(p); | 3677 | const else_expr = try bodyParseFn(p); |
| 3939 | assert(else_expr != 0); | ||
| 3940 | 3678 | ||
| 3941 | return p.addNode(.{ | 3679 | return try p.addNode(.{ |
| 3942 | .tag = .@"if", | 3680 | .tag = .@"if", |
| 3943 | .main_token = if_token, | 3681 | .main_token = if_token, |
| 3944 | .data = .{ | 3682 | .data = .{ .node_and_extra = .{ |
| 3945 | .lhs = condition, | 3683 | condition, |
| 3946 | .rhs = try p.addExtra(Node.If{ | 3684 | try p.addExtra(Node.If{ |
| 3947 | .then_expr = then_expr, | 3685 | .then_expr = then_expr, |
| 3948 | .else_expr = else_expr, | 3686 | .else_expr = else_expr, |
| 3949 | }), | 3687 | }), |
| 3950 | }, | 3688 | } }, |
| 3951 | }); | 3689 | }); |
| 3952 | } | 3690 | } |
| 3953 | 3691 | ||
| 3954 | /// ForExpr <- ForPrefix Expr (KEYWORD_else Expr)? | 3692 | /// ForExpr <- ForPrefix Expr (KEYWORD_else Expr)? |
| 3955 | /// | 3693 | /// |
| 3956 | /// ForTypeExpr <- ForPrefix TypeExpr (KEYWORD_else TypeExpr)? | 3694 | /// ForTypeExpr <- ForPrefix TypeExpr (KEYWORD_else TypeExpr)? |
| 3957 | fn parseFor(p: *Parse, comptime bodyParseFn: fn (p: *Parse) Error!Node.Index) !Node.Index { | 3695 | fn parseFor(p: *Parse, comptime bodyParseFn: fn (p: *Parse) Error!Node.Index) !?Node.Index { |
| 3958 | const for_token = p.eatToken(.keyword_for) orelse return null_node; | 3696 | const for_token = p.eatToken(.keyword_for) orelse return null; |
| 3959 | 3697 | ||
| 3960 | const scratch_top = p.scratch.items.len; | 3698 | const scratch_top = p.scratch.items.len; |
| 3961 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 3699 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| ... | @@ -3969,27 +3707,24 @@ fn parseFor(p: *Parse, comptime bodyParseFn: fn (p: *Parse) Error!Node.Index) !N | ... | @@ -3969,27 +3707,24 @@ fn parseFor(p: *Parse, comptime bodyParseFn: fn (p: *Parse) Error!Node.Index) !N |
| 3969 | try p.scratch.append(p.gpa, else_expr); | 3707 | try p.scratch.append(p.gpa, else_expr); |
| 3970 | has_else = true; | 3708 | has_else = true; |
| 3971 | } else if (inputs == 1) { | 3709 | } else if (inputs == 1) { |
| 3972 | return p.addNode(.{ | 3710 | return try p.addNode(.{ |
| 3973 | .tag = .for_simple, | 3711 | .tag = .for_simple, |
| 3974 | .main_token = for_token, | 3712 | .main_token = for_token, |
| 3975 | .data = .{ | 3713 | .data = .{ .node_and_node = .{ |
| 3976 | .lhs = p.scratch.items[scratch_top], | 3714 | p.scratch.items[scratch_top], |
| 3977 | .rhs = then_expr, | 3715 | then_expr, |
| 3978 | }, | 3716 | } }, |
| 3979 | }); | 3717 | }); |
| 3980 | } else { | 3718 | } else { |
| 3981 | try p.scratch.append(p.gpa, then_expr); | 3719 | try p.scratch.append(p.gpa, then_expr); |
| 3982 | } | 3720 | } |
| 3983 | return p.addNode(.{ | 3721 | return try p.addNode(.{ |
| 3984 | .tag = .@"for", | 3722 | .tag = .@"for", |
| 3985 | .main_token = for_token, | 3723 | .main_token = for_token, |
| 3986 | .data = .{ | 3724 | .data = .{ .@"for" = .{ |
| 3987 | .lhs = (try p.listToSpan(p.scratch.items[scratch_top..])).start, | 3725 | (try p.listToSpan(p.scratch.items[scratch_top..])).start, |
| 3988 | .rhs = @as(u32, @bitCast(Node.For{ | 3726 | .{ .inputs = @intCast(inputs), .has_else = has_else }, |
| 3989 | .inputs = @as(u31, @intCast(inputs)), | 3727 | } }, |
| 3990 | .has_else = has_else, | ||
| 3991 | })), | ||
| 3992 | }, | ||
| 3993 | }); | 3728 | }); |
| 3994 | } | 3729 | } |
| 3995 | 3730 | ||
| ... | @@ -4011,21 +3746,29 @@ fn eatDocComments(p: *Parse) Allocator.Error!?TokenIndex { | ... | @@ -4011,21 +3746,29 @@ fn eatDocComments(p: *Parse) Allocator.Error!?TokenIndex { |
| 4011 | } | 3746 | } |
| 4012 | 3747 | ||
| 4013 | fn tokensOnSameLine(p: *Parse, token1: TokenIndex, token2: TokenIndex) bool { | 3748 | fn tokensOnSameLine(p: *Parse, token1: TokenIndex, token2: TokenIndex) bool { |
| 4014 | return std.mem.indexOfScalar(u8, p.source[p.token_starts[token1]..p.token_starts[token2]], '\n') == null; | 3749 | return std.mem.indexOfScalar(u8, p.source[p.tokenStart(token1)..p.tokenStart(token2)], '\n') == null; |
| 4015 | } | 3750 | } |
| 4016 | 3751 | ||
| 4017 | fn eatToken(p: *Parse, tag: Token.Tag) ?TokenIndex { | 3752 | fn eatToken(p: *Parse, tag: Token.Tag) ?TokenIndex { |
| 4018 | return if (p.token_tags[p.tok_i] == tag) p.nextToken() else null; | 3753 | return if (p.tokenTag(p.tok_i) == tag) p.nextToken() else null; |
| 3754 | } | ||
| 3755 | |||
| 3756 | fn eatTokens(p: *Parse, tags: []const Token.Tag) ?TokenIndex { | ||
| 3757 | const available_tags = p.tokens.items(.tag)[p.tok_i..]; | ||
| 3758 | if (!std.mem.startsWith(Token.Tag, available_tags, tags)) return null; | ||
| 3759 | const result = p.tok_i; | ||
| 3760 | p.tok_i += @intCast(tags.len); | ||
| 3761 | return result; | ||
| 4019 | } | 3762 | } |
| 4020 | 3763 | ||
| 4021 | fn assertToken(p: *Parse, tag: Token.Tag) TokenIndex { | 3764 | fn assertToken(p: *Parse, tag: Token.Tag) TokenIndex { |
| 4022 | const token = p.nextToken(); | 3765 | const token = p.nextToken(); |
| 4023 | assert(p.token_tags[token] == tag); | 3766 | assert(p.tokenTag(token) == tag); |
| 4024 | return token; | 3767 | return token; |
| 4025 | } | 3768 | } |
| 4026 | 3769 | ||
| 4027 | fn expectToken(p: *Parse, tag: Token.Tag) Error!TokenIndex { | 3770 | fn expectToken(p: *Parse, tag: Token.Tag) Error!TokenIndex { |
| 4028 | if (p.token_tags[p.tok_i] != tag) { | 3771 | if (p.tokenTag(p.tok_i) != tag) { |
| 4029 | return p.failMsg(.{ | 3772 | return p.failMsg(.{ |
| 4030 | .tag = .expected_token, | 3773 | .tag = .expected_token, |
| 4031 | .token = p.tok_i, | 3774 | .token = p.tok_i, |
| ... | @@ -4036,7 +3779,7 @@ fn expectToken(p: *Parse, tag: Token.Tag) Error!TokenIndex { | ... | @@ -4036,7 +3779,7 @@ fn expectToken(p: *Parse, tag: Token.Tag) Error!TokenIndex { |
| 4036 | } | 3779 | } |
| 4037 | 3780 | ||
| 4038 | fn expectSemicolon(p: *Parse, error_tag: AstError.Tag, recoverable: bool) Error!void { | 3781 | fn expectSemicolon(p: *Parse, error_tag: AstError.Tag, recoverable: bool) Error!void { |
| 4039 | if (p.token_tags[p.tok_i] == .semicolon) { | 3782 | if (p.tokenTag(p.tok_i) == .semicolon) { |
| 4040 | _ = p.nextToken(); | 3783 | _ = p.nextToken(); |
| 4041 | return; | 3784 | return; |
| 4042 | } | 3785 | } |
| ... | @@ -4050,8 +3793,6 @@ fn nextToken(p: *Parse) TokenIndex { | ... | @@ -4050,8 +3793,6 @@ fn nextToken(p: *Parse) TokenIndex { |
| 4050 | return result; | 3793 | return result; |
| 4051 | } | 3794 | } |
| 4052 | 3795 | ||
| 4053 | const null_node: Node.Index = 0; | ||
| 4054 | |||
| 4055 | const Parse = @This(); | 3796 | const Parse = @This(); |
| 4056 | const std = @import("../std.zig"); | 3797 | const std = @import("../std.zig"); |
| 4057 | const assert = std.debug.assert; | 3798 | const assert = std.debug.assert; |
| ... | @@ -4060,6 +3801,8 @@ const Ast = std.zig.Ast; | ... | @@ -4060,6 +3801,8 @@ const Ast = std.zig.Ast; |
| 4060 | const Node = Ast.Node; | 3801 | const Node = Ast.Node; |
| 4061 | const AstError = Ast.Error; | 3802 | const AstError = Ast.Error; |
| 4062 | const TokenIndex = Ast.TokenIndex; | 3803 | const TokenIndex = Ast.TokenIndex; |
| 3804 | const OptionalTokenIndex = Ast.OptionalTokenIndex; | ||
| 3805 | const ExtraIndex = Ast.ExtraIndex; | ||
| 4063 | const Token = std.zig.Token; | 3806 | const Token = std.zig.Token; |
| 4064 | 3807 | ||
| 4065 | test { | 3808 | test { |
lib/std/zig/Zir.zig+52-45| ... | @@ -80,9 +80,18 @@ pub fn extraData(code: Zir, comptime T: type, index: usize) ExtraData(T) { | ... | @@ -80,9 +80,18 @@ pub fn extraData(code: Zir, comptime T: type, index: usize) ExtraData(T) { |
| 80 | Inst.Declaration.Name, | 80 | Inst.Declaration.Name, |
| 81 | std.zig.SimpleComptimeReason, | 81 | std.zig.SimpleComptimeReason, |
| 82 | NullTerminatedString, | 82 | NullTerminatedString, |
| 83 | // Ast.TokenIndex is missing because it is a u32. | ||
| 84 | Ast.OptionalTokenIndex, | ||
| 85 | Ast.Node.Index, | ||
| 86 | Ast.Node.OptionalIndex, | ||
| 83 | => @enumFromInt(code.extra[i]), | 87 | => @enumFromInt(code.extra[i]), |
| 84 | 88 | ||
| 85 | i32, | 89 | Ast.TokenOffset, |
| 90 | Ast.OptionalTokenOffset, | ||
| 91 | Ast.Node.Offset, | ||
| 92 | Ast.Node.OptionalOffset, | ||
| 93 | => @enumFromInt(@as(i32, @bitCast(code.extra[i]))), | ||
| 94 | |||
| 86 | Inst.Call.Flags, | 95 | Inst.Call.Flags, |
| 87 | Inst.BuiltinCall.Flags, | 96 | Inst.BuiltinCall.Flags, |
| 88 | Inst.SwitchBlock.Bits, | 97 | Inst.SwitchBlock.Bits, |
| ... | @@ -1904,22 +1913,22 @@ pub const Inst = struct { | ... | @@ -1904,22 +1913,22 @@ pub const Inst = struct { |
| 1904 | /// `small` is `fields_len: u16`. | 1913 | /// `small` is `fields_len: u16`. |
| 1905 | tuple_decl, | 1914 | tuple_decl, |
| 1906 | /// Implements the `@This` builtin. | 1915 | /// Implements the `@This` builtin. |
| 1907 | /// `operand` is `src_node: i32`. | 1916 | /// `operand` is `src_node: Ast.Node.Offset`. |
| 1908 | this, | 1917 | this, |
| 1909 | /// Implements the `@returnAddress` builtin. | 1918 | /// Implements the `@returnAddress` builtin. |
| 1910 | /// `operand` is `src_node: i32`. | 1919 | /// `operand` is `src_node: Ast.Node.Offset`. |
| 1911 | ret_addr, | 1920 | ret_addr, |
| 1912 | /// Implements the `@src` builtin. | 1921 | /// Implements the `@src` builtin. |
| 1913 | /// `operand` is payload index to `LineColumn`. | 1922 | /// `operand` is payload index to `LineColumn`. |
| 1914 | builtin_src, | 1923 | builtin_src, |
| 1915 | /// Implements the `@errorReturnTrace` builtin. | 1924 | /// Implements the `@errorReturnTrace` builtin. |
| 1916 | /// `operand` is `src_node: i32`. | 1925 | /// `operand` is `src_node: Ast.Node.Offset`. |
| 1917 | error_return_trace, | 1926 | error_return_trace, |
| 1918 | /// Implements the `@frame` builtin. | 1927 | /// Implements the `@frame` builtin. |
| 1919 | /// `operand` is `src_node: i32`. | 1928 | /// `operand` is `src_node: Ast.Node.Offset`. |
| 1920 | frame, | 1929 | frame, |
| 1921 | /// Implements the `@frameAddress` builtin. | 1930 | /// Implements the `@frameAddress` builtin. |
| 1922 | /// `operand` is `src_node: i32`. | 1931 | /// `operand` is `src_node: Ast.Node.Offset`. |
| 1923 | frame_address, | 1932 | frame_address, |
| 1924 | /// Same as `alloc` from `Tag` but may contain an alignment instruction. | 1933 | /// Same as `alloc` from `Tag` but may contain an alignment instruction. |
| 1925 | /// `operand` is payload index to `AllocExtended`. | 1934 | /// `operand` is payload index to `AllocExtended`. |
| ... | @@ -2004,9 +2013,9 @@ pub const Inst = struct { | ... | @@ -2004,9 +2013,9 @@ pub const Inst = struct { |
| 2004 | /// `operand` is payload index to `UnNode`. | 2013 | /// `operand` is payload index to `UnNode`. |
| 2005 | await_nosuspend, | 2014 | await_nosuspend, |
| 2006 | /// Implements `@breakpoint`. | 2015 | /// Implements `@breakpoint`. |
| 2007 | /// `operand` is `src_node: i32`. | 2016 | /// `operand` is `src_node: Ast.Node.Offset`. |
| 2008 | breakpoint, | 2017 | breakpoint, |
| 2009 | /// Implement builtin `@disableInstrumentation`. `operand` is `src_node: i32`. | 2018 | /// Implement builtin `@disableInstrumentation`. `operand` is `src_node: Ast.Node.Offset`. |
| 2010 | disable_instrumentation, | 2019 | disable_instrumentation, |
| 2011 | /// Implement builtin `@disableIntrinsics`. `operand` is `src_node: i32`. | 2020 | /// Implement builtin `@disableIntrinsics`. `operand` is `src_node: i32`. |
| 2012 | disable_intrinsics, | 2021 | disable_intrinsics, |
| ... | @@ -2040,7 +2049,7 @@ pub const Inst = struct { | ... | @@ -2040,7 +2049,7 @@ pub const Inst = struct { |
| 2040 | /// `operand` is payload index to `UnNode`. | 2049 | /// `operand` is payload index to `UnNode`. |
| 2041 | c_va_end, | 2050 | c_va_end, |
| 2042 | /// Implement builtin `@cVaStart`. | 2051 | /// Implement builtin `@cVaStart`. |
| 2043 | /// `operand` is `src_node: i32`. | 2052 | /// `operand` is `src_node: Ast.Node.Offset`. |
| 2044 | c_va_start, | 2053 | c_va_start, |
| 2045 | /// Implements the following builtins: | 2054 | /// Implements the following builtins: |
| 2046 | /// `@ptrCast`, `@alignCast`, `@addrSpaceCast`, `@constCast`, `@volatileCast`. | 2055 | /// `@ptrCast`, `@alignCast`, `@addrSpaceCast`, `@constCast`, `@volatileCast`. |
| ... | @@ -2067,7 +2076,7 @@ pub const Inst = struct { | ... | @@ -2067,7 +2076,7 @@ pub const Inst = struct { |
| 2067 | /// `operand` is payload index to `UnNode`. | 2076 | /// `operand` is payload index to `UnNode`. |
| 2068 | work_group_id, | 2077 | work_group_id, |
| 2069 | /// Implements the `@inComptime` builtin. | 2078 | /// Implements the `@inComptime` builtin. |
| 2070 | /// `operand` is `src_node: i32`. | 2079 | /// `operand` is `src_node: Ast.Node.Offset`. |
| 2071 | in_comptime, | 2080 | in_comptime, |
| 2072 | /// Restores the error return index to its last saved state in a given | 2081 | /// Restores the error return index to its last saved state in a given |
| 2073 | /// block. If the block is `.none`, restores to the state from the point | 2082 | /// block. If the block is `.none`, restores to the state from the point |
| ... | @@ -2077,7 +2086,7 @@ pub const Inst = struct { | ... | @@ -2077,7 +2086,7 @@ pub const Inst = struct { |
| 2077 | /// `small` is undefined. | 2086 | /// `small` is undefined. |
| 2078 | restore_err_ret_index, | 2087 | restore_err_ret_index, |
| 2079 | /// Retrieves a value from the current type declaration scope's closure. | 2088 | /// Retrieves a value from the current type declaration scope's closure. |
| 2080 | /// `operand` is `src_node: i32`. | 2089 | /// `operand` is `src_node: Ast.Node.Offset`. |
| 2081 | /// `small` is closure index. | 2090 | /// `small` is closure index. |
| 2082 | closure_get, | 2091 | closure_get, |
| 2083 | /// Used as a placeholder instruction which is just a dummy index for Sema to replace | 2092 | /// Used as a placeholder instruction which is just a dummy index for Sema to replace |
| ... | @@ -2091,7 +2100,7 @@ pub const Inst = struct { | ... | @@ -2091,7 +2100,7 @@ pub const Inst = struct { |
| 2091 | /// Uses the `pl_node` union field with payload `FieldParentPtr`. | 2100 | /// Uses the `pl_node` union field with payload `FieldParentPtr`. |
| 2092 | field_parent_ptr, | 2101 | field_parent_ptr, |
| 2093 | /// Get a type or value from `std.builtin`. | 2102 | /// Get a type or value from `std.builtin`. |
| 2094 | /// `operand` is `src_node: i32`. | 2103 | /// `operand` is `src_node: Ast.Node.Offset`. |
| 2095 | /// `small` is an `Inst.BuiltinValue`. | 2104 | /// `small` is an `Inst.BuiltinValue`. |
| 2096 | builtin_value, | 2105 | builtin_value, |
| 2097 | /// Provide a `@branchHint` for the current block. | 2106 | /// Provide a `@branchHint` for the current block. |
| ... | @@ -2286,28 +2295,28 @@ pub const Inst = struct { | ... | @@ -2286,28 +2295,28 @@ pub const Inst = struct { |
| 2286 | /// Used for unary operators, with an AST node source location. | 2295 | /// Used for unary operators, with an AST node source location. |
| 2287 | un_node: struct { | 2296 | un_node: struct { |
| 2288 | /// Offset from Decl AST node index. | 2297 | /// Offset from Decl AST node index. |
| 2289 | src_node: i32, | 2298 | src_node: Ast.Node.Offset, |
| 2290 | /// The meaning of this operand depends on the corresponding `Tag`. | 2299 | /// The meaning of this operand depends on the corresponding `Tag`. |
| 2291 | operand: Ref, | 2300 | operand: Ref, |
| 2292 | }, | 2301 | }, |
| 2293 | /// Used for unary operators, with a token source location. | 2302 | /// Used for unary operators, with a token source location. |
| 2294 | un_tok: struct { | 2303 | un_tok: struct { |
| 2295 | /// Offset from Decl AST token index. | 2304 | /// Offset from Decl AST token index. |
| 2296 | src_tok: Ast.TokenIndex, | 2305 | src_tok: Ast.TokenOffset, |
| 2297 | /// The meaning of this operand depends on the corresponding `Tag`. | 2306 | /// The meaning of this operand depends on the corresponding `Tag`. |
| 2298 | operand: Ref, | 2307 | operand: Ref, |
| 2299 | }, | 2308 | }, |
| 2300 | pl_node: struct { | 2309 | pl_node: struct { |
| 2301 | /// Offset from Decl AST node index. | 2310 | /// Offset from Decl AST node index. |
| 2302 | /// `Tag` determines which kind of AST node this points to. | 2311 | /// `Tag` determines which kind of AST node this points to. |
| 2303 | src_node: i32, | 2312 | src_node: Ast.Node.Offset, |
| 2304 | /// index into extra. | 2313 | /// index into extra. |
| 2305 | /// `Tag` determines what lives there. | 2314 | /// `Tag` determines what lives there. |
| 2306 | payload_index: u32, | 2315 | payload_index: u32, |
| 2307 | }, | 2316 | }, |
| 2308 | pl_tok: struct { | 2317 | pl_tok: struct { |
| 2309 | /// Offset from Decl AST token index. | 2318 | /// Offset from Decl AST token index. |
| 2310 | src_tok: Ast.TokenIndex, | 2319 | src_tok: Ast.TokenOffset, |
| 2311 | /// index into extra. | 2320 | /// index into extra. |
| 2312 | /// `Tag` determines what lives there. | 2321 | /// `Tag` determines what lives there. |
| 2313 | payload_index: u32, | 2322 | payload_index: u32, |
| ... | @@ -2328,16 +2337,16 @@ pub const Inst = struct { | ... | @@ -2328,16 +2337,16 @@ pub const Inst = struct { |
| 2328 | /// Offset into `string_bytes`. Null-terminated. | 2337 | /// Offset into `string_bytes`. Null-terminated. |
| 2329 | start: NullTerminatedString, | 2338 | start: NullTerminatedString, |
| 2330 | /// Offset from Decl AST token index. | 2339 | /// Offset from Decl AST token index. |
| 2331 | src_tok: u32, | 2340 | src_tok: Ast.TokenOffset, |
| 2332 | 2341 | ||
| 2333 | pub fn get(self: @This(), code: Zir) [:0]const u8 { | 2342 | pub fn get(self: @This(), code: Zir) [:0]const u8 { |
| 2334 | return code.nullTerminatedString(self.start); | 2343 | return code.nullTerminatedString(self.start); |
| 2335 | } | 2344 | } |
| 2336 | }, | 2345 | }, |
| 2337 | /// Offset from Decl AST token index. | 2346 | /// Offset from Decl AST token index. |
| 2338 | tok: Ast.TokenIndex, | 2347 | tok: Ast.TokenOffset, |
| 2339 | /// Offset from Decl AST node index. | 2348 | /// Offset from Decl AST node index. |
| 2340 | node: i32, | 2349 | node: Ast.Node.Offset, |
| 2341 | int: u64, | 2350 | int: u64, |
| 2342 | float: f64, | 2351 | float: f64, |
| 2343 | ptr_type: struct { | 2352 | ptr_type: struct { |
| ... | @@ -2358,14 +2367,14 @@ pub const Inst = struct { | ... | @@ -2358,14 +2367,14 @@ pub const Inst = struct { |
| 2358 | int_type: struct { | 2367 | int_type: struct { |
| 2359 | /// Offset from Decl AST node index. | 2368 | /// Offset from Decl AST node index. |
| 2360 | /// `Tag` determines which kind of AST node this points to. | 2369 | /// `Tag` determines which kind of AST node this points to. |
| 2361 | src_node: i32, | 2370 | src_node: Ast.Node.Offset, |
| 2362 | signedness: std.builtin.Signedness, | 2371 | signedness: std.builtin.Signedness, |
| 2363 | bit_count: u16, | 2372 | bit_count: u16, |
| 2364 | }, | 2373 | }, |
| 2365 | @"unreachable": struct { | 2374 | @"unreachable": struct { |
| 2366 | /// Offset from Decl AST node index. | 2375 | /// Offset from Decl AST node index. |
| 2367 | /// `Tag` determines which kind of AST node this points to. | 2376 | /// `Tag` determines which kind of AST node this points to. |
| 2368 | src_node: i32, | 2377 | src_node: Ast.Node.Offset, |
| 2369 | }, | 2378 | }, |
| 2370 | @"break": struct { | 2379 | @"break": struct { |
| 2371 | operand: Ref, | 2380 | operand: Ref, |
| ... | @@ -2377,7 +2386,7 @@ pub const Inst = struct { | ... | @@ -2377,7 +2386,7 @@ pub const Inst = struct { |
| 2377 | /// with an AST node source location. | 2386 | /// with an AST node source location. |
| 2378 | inst_node: struct { | 2387 | inst_node: struct { |
| 2379 | /// Offset from Decl AST node index. | 2388 | /// Offset from Decl AST node index. |
| 2380 | src_node: i32, | 2389 | src_node: Ast.Node.Offset, |
| 2381 | /// The meaning of this operand depends on the corresponding `Tag`. | 2390 | /// The meaning of this operand depends on the corresponding `Tag`. |
| 2382 | inst: Index, | 2391 | inst: Index, |
| 2383 | }, | 2392 | }, |
| ... | @@ -2456,9 +2465,7 @@ pub const Inst = struct { | ... | @@ -2456,9 +2465,7 @@ pub const Inst = struct { |
| 2456 | }; | 2465 | }; |
| 2457 | 2466 | ||
| 2458 | pub const Break = struct { | 2467 | pub const Break = struct { |
| 2459 | pub const no_src_node = std.math.maxInt(i32); | 2468 | operand_src_node: Ast.Node.OptionalOffset, |
| 2460 | |||
| 2461 | operand_src_node: i32, | ||
| 2462 | block_inst: Index, | 2469 | block_inst: Index, |
| 2463 | }; | 2470 | }; |
| 2464 | 2471 | ||
| ... | @@ -2467,7 +2474,7 @@ pub const Inst = struct { | ... | @@ -2467,7 +2474,7 @@ pub const Inst = struct { |
| 2467 | /// 1. Input for every inputs_len | 2474 | /// 1. Input for every inputs_len |
| 2468 | /// 2. clobber: NullTerminatedString // index into string_bytes (null terminated) for every clobbers_len. | 2475 | /// 2. clobber: NullTerminatedString // index into string_bytes (null terminated) for every clobbers_len. |
| 2469 | pub const Asm = struct { | 2476 | pub const Asm = struct { |
| 2470 | src_node: i32, | 2477 | src_node: Ast.Node.Offset, |
| 2471 | // null-terminated string index | 2478 | // null-terminated string index |
| 2472 | asm_source: NullTerminatedString, | 2479 | asm_source: NullTerminatedString, |
| 2473 | /// 1 bit for each outputs_len: whether it uses `-> T` or not. | 2480 | /// 1 bit for each outputs_len: whether it uses `-> T` or not. |
| ... | @@ -2582,7 +2589,7 @@ pub const Inst = struct { | ... | @@ -2582,7 +2589,7 @@ pub const Inst = struct { |
| 2582 | 2589 | ||
| 2583 | /// Trailing: operand: Ref, // for each `operands_len` (stored in `small`). | 2590 | /// Trailing: operand: Ref, // for each `operands_len` (stored in `small`). |
| 2584 | pub const NodeMultiOp = struct { | 2591 | pub const NodeMultiOp = struct { |
| 2585 | src_node: i32, | 2592 | src_node: Ast.Node.Offset, |
| 2586 | }; | 2593 | }; |
| 2587 | 2594 | ||
| 2588 | /// This data is stored inside extra, with trailing operands according to `body_len`. | 2595 | /// This data is stored inside extra, with trailing operands according to `body_len`. |
| ... | @@ -3033,7 +3040,7 @@ pub const Inst = struct { | ... | @@ -3033,7 +3040,7 @@ pub const Inst = struct { |
| 3033 | /// Trailing: | 3040 | /// Trailing: |
| 3034 | /// 0. operand: Ref // for each `operands_len` | 3041 | /// 0. operand: Ref // for each `operands_len` |
| 3035 | pub const TypeOfPeer = struct { | 3042 | pub const TypeOfPeer = struct { |
| 3036 | src_node: i32, | 3043 | src_node: Ast.Node.Offset, |
| 3037 | body_len: u32, | 3044 | body_len: u32, |
| 3038 | body_index: u32, | 3045 | body_index: u32, |
| 3039 | }; | 3046 | }; |
| ... | @@ -3084,7 +3091,7 @@ pub const Inst = struct { | ... | @@ -3084,7 +3091,7 @@ pub const Inst = struct { |
| 3084 | /// 4. host_size: Ref // if `has_bit_range` flag is set | 3091 | /// 4. host_size: Ref // if `has_bit_range` flag is set |
| 3085 | pub const PtrType = struct { | 3092 | pub const PtrType = struct { |
| 3086 | elem_type: Ref, | 3093 | elem_type: Ref, |
| 3087 | src_node: i32, | 3094 | src_node: Ast.Node.Offset, |
| 3088 | }; | 3095 | }; |
| 3089 | 3096 | ||
| 3090 | pub const ArrayTypeSentinel = struct { | 3097 | pub const ArrayTypeSentinel = struct { |
| ... | @@ -3116,7 +3123,7 @@ pub const Inst = struct { | ... | @@ -3116,7 +3123,7 @@ pub const Inst = struct { |
| 3116 | start: Ref, | 3123 | start: Ref, |
| 3117 | len: Ref, | 3124 | len: Ref, |
| 3118 | sentinel: Ref, | 3125 | sentinel: Ref, |
| 3119 | start_src_node_offset: i32, | 3126 | start_src_node_offset: Ast.Node.Offset, |
| 3120 | }; | 3127 | }; |
| 3121 | 3128 | ||
| 3122 | /// The meaning of these operands depends on the corresponding `Tag`. | 3129 | /// The meaning of these operands depends on the corresponding `Tag`. |
| ... | @@ -3126,13 +3133,13 @@ pub const Inst = struct { | ... | @@ -3126,13 +3133,13 @@ pub const Inst = struct { |
| 3126 | }; | 3133 | }; |
| 3127 | 3134 | ||
| 3128 | pub const BinNode = struct { | 3135 | pub const BinNode = struct { |
| 3129 | node: i32, | 3136 | node: Ast.Node.Offset, |
| 3130 | lhs: Ref, | 3137 | lhs: Ref, |
| 3131 | rhs: Ref, | 3138 | rhs: Ref, |
| 3132 | }; | 3139 | }; |
| 3133 | 3140 | ||
| 3134 | pub const UnNode = struct { | 3141 | pub const UnNode = struct { |
| 3135 | node: i32, | 3142 | node: Ast.Node.Offset, |
| 3136 | operand: Ref, | 3143 | operand: Ref, |
| 3137 | }; | 3144 | }; |
| 3138 | 3145 | ||
| ... | @@ -3186,7 +3193,7 @@ pub const Inst = struct { | ... | @@ -3186,7 +3193,7 @@ pub const Inst = struct { |
| 3186 | pub const SwitchBlockErrUnion = struct { | 3193 | pub const SwitchBlockErrUnion = struct { |
| 3187 | operand: Ref, | 3194 | operand: Ref, |
| 3188 | bits: Bits, | 3195 | bits: Bits, |
| 3189 | main_src_node_offset: i32, | 3196 | main_src_node_offset: Ast.Node.Offset, |
| 3190 | 3197 | ||
| 3191 | pub const Bits = packed struct(u32) { | 3198 | pub const Bits = packed struct(u32) { |
| 3192 | /// If true, one or more prongs have multiple items. | 3199 | /// If true, one or more prongs have multiple items. |
| ... | @@ -3592,7 +3599,7 @@ pub const Inst = struct { | ... | @@ -3592,7 +3599,7 @@ pub const Inst = struct { |
| 3592 | /// init: Inst.Ref, // `.none` for non-`comptime` fields | 3599 | /// init: Inst.Ref, // `.none` for non-`comptime` fields |
| 3593 | /// } | 3600 | /// } |
| 3594 | pub const TupleDecl = struct { | 3601 | pub const TupleDecl = struct { |
| 3595 | src_node: i32, // relative | 3602 | src_node: Ast.Node.Offset, |
| 3596 | }; | 3603 | }; |
| 3597 | 3604 | ||
| 3598 | /// Trailing: | 3605 | /// Trailing: |
| ... | @@ -3666,7 +3673,7 @@ pub const Inst = struct { | ... | @@ -3666,7 +3673,7 @@ pub const Inst = struct { |
| 3666 | }; | 3673 | }; |
| 3667 | 3674 | ||
| 3668 | pub const Cmpxchg = struct { | 3675 | pub const Cmpxchg = struct { |
| 3669 | node: i32, | 3676 | node: Ast.Node.Offset, |
| 3670 | ptr: Ref, | 3677 | ptr: Ref, |
| 3671 | expected_value: Ref, | 3678 | expected_value: Ref, |
| 3672 | new_value: Ref, | 3679 | new_value: Ref, |
| ... | @@ -3706,7 +3713,7 @@ pub const Inst = struct { | ... | @@ -3706,7 +3713,7 @@ pub const Inst = struct { |
| 3706 | }; | 3713 | }; |
| 3707 | 3714 | ||
| 3708 | pub const FieldParentPtr = struct { | 3715 | pub const FieldParentPtr = struct { |
| 3709 | src_node: i32, | 3716 | src_node: Ast.Node.Offset, |
| 3710 | parent_ptr_type: Ref, | 3717 | parent_ptr_type: Ref, |
| 3711 | field_name: Ref, | 3718 | field_name: Ref, |
| 3712 | field_ptr: Ref, | 3719 | field_ptr: Ref, |
| ... | @@ -3720,7 +3727,7 @@ pub const Inst = struct { | ... | @@ -3720,7 +3727,7 @@ pub const Inst = struct { |
| 3720 | }; | 3727 | }; |
| 3721 | 3728 | ||
| 3722 | pub const Select = struct { | 3729 | pub const Select = struct { |
| 3723 | node: i32, | 3730 | node: Ast.Node.Offset, |
| 3724 | elem_type: Ref, | 3731 | elem_type: Ref, |
| 3725 | pred: Ref, | 3732 | pred: Ref, |
| 3726 | a: Ref, | 3733 | a: Ref, |
| ... | @@ -3728,7 +3735,7 @@ pub const Inst = struct { | ... | @@ -3728,7 +3735,7 @@ pub const Inst = struct { |
| 3728 | }; | 3735 | }; |
| 3729 | 3736 | ||
| 3730 | pub const AsyncCall = struct { | 3737 | pub const AsyncCall = struct { |
| 3731 | node: i32, | 3738 | node: Ast.Node.Offset, |
| 3732 | frame_buffer: Ref, | 3739 | frame_buffer: Ref, |
| 3733 | result_ptr: Ref, | 3740 | result_ptr: Ref, |
| 3734 | fn_ptr: Ref, | 3741 | fn_ptr: Ref, |
| ... | @@ -3753,7 +3760,7 @@ pub const Inst = struct { | ... | @@ -3753,7 +3760,7 @@ pub const Inst = struct { |
| 3753 | /// 0. type_inst: Ref, // if small 0b000X is set | 3760 | /// 0. type_inst: Ref, // if small 0b000X is set |
| 3754 | /// 1. align_inst: Ref, // if small 0b00X0 is set | 3761 | /// 1. align_inst: Ref, // if small 0b00X0 is set |
| 3755 | pub const AllocExtended = struct { | 3762 | pub const AllocExtended = struct { |
| 3756 | src_node: i32, | 3763 | src_node: Ast.Node.Offset, |
| 3757 | 3764 | ||
| 3758 | pub const Small = packed struct { | 3765 | pub const Small = packed struct { |
| 3759 | has_type: bool, | 3766 | has_type: bool, |
| ... | @@ -3778,9 +3785,9 @@ pub const Inst = struct { | ... | @@ -3778,9 +3785,9 @@ pub const Inst = struct { |
| 3778 | pub const Item = struct { | 3785 | pub const Item = struct { |
| 3779 | /// null terminated string index | 3786 | /// null terminated string index |
| 3780 | msg: NullTerminatedString, | 3787 | msg: NullTerminatedString, |
| 3781 | node: Ast.Node.Index, | 3788 | node: Ast.Node.OptionalIndex, |
| 3782 | /// If node is 0 then this will be populated. | 3789 | /// If node is .none then this will be populated. |
| 3783 | token: Ast.TokenIndex, | 3790 | token: Ast.OptionalTokenIndex, |
| 3784 | /// Can be used in combination with `token`. | 3791 | /// Can be used in combination with `token`. |
| 3785 | byte_offset: u32, | 3792 | byte_offset: u32, |
| 3786 | /// 0 or a payload index of a `Block`, each is a payload | 3793 | /// 0 or a payload index of a `Block`, each is a payload |
| ... | @@ -3818,7 +3825,7 @@ pub const Inst = struct { | ... | @@ -3818,7 +3825,7 @@ pub const Inst = struct { |
| 3818 | }; | 3825 | }; |
| 3819 | 3826 | ||
| 3820 | pub const Src = struct { | 3827 | pub const Src = struct { |
| 3821 | node: i32, | 3828 | node: Ast.Node.Offset, |
| 3822 | line: u32, | 3829 | line: u32, |
| 3823 | column: u32, | 3830 | column: u32, |
| 3824 | }; | 3831 | }; |
| ... | @@ -3833,7 +3840,7 @@ pub const Inst = struct { | ... | @@ -3833,7 +3840,7 @@ pub const Inst = struct { |
| 3833 | /// The value being destructured. | 3840 | /// The value being destructured. |
| 3834 | operand: Ref, | 3841 | operand: Ref, |
| 3835 | /// The `destructure_assign` node. | 3842 | /// The `destructure_assign` node. |
| 3836 | destructure_node: i32, | 3843 | destructure_node: Ast.Node.Offset, |
| 3837 | /// The expected field count. | 3844 | /// The expected field count. |
| 3838 | expect_len: u32, | 3845 | expect_len: u32, |
| 3839 | }; | 3846 | }; |
| ... | @@ -3848,7 +3855,7 @@ pub const Inst = struct { | ... | @@ -3848,7 +3855,7 @@ pub const Inst = struct { |
| 3848 | }; | 3855 | }; |
| 3849 | 3856 | ||
| 3850 | pub const RestoreErrRetIndex = struct { | 3857 | pub const RestoreErrRetIndex = struct { |
| 3851 | src_node: i32, | 3858 | src_node: Ast.Node.Offset, |
| 3852 | /// If `.none`, restore the trace to its state upon function entry. | 3859 | /// If `.none`, restore the trace to its state upon function entry. |
| 3853 | block: Ref, | 3860 | block: Ref, |
| 3854 | /// If `.none`, restore unconditionally. | 3861 | /// If `.none`, restore unconditionally. |
lib/std/zig/Zoir.zig+4-6| ... | @@ -228,8 +228,8 @@ pub const NullTerminatedString = enum(u32) { | ... | @@ -228,8 +228,8 @@ pub const NullTerminatedString = enum(u32) { |
| 228 | 228 | ||
| 229 | pub const CompileError = extern struct { | 229 | pub const CompileError = extern struct { |
| 230 | msg: NullTerminatedString, | 230 | msg: NullTerminatedString, |
| 231 | token: Ast.TokenIndex, | 231 | token: Ast.OptionalTokenIndex, |
| 232 | /// If `token == invalid_token`, this is an `Ast.Node.Index`. | 232 | /// If `token == .none`, this is an `Ast.Node.Index`. |
| 233 | /// Otherwise, this is a byte offset into `token`. | 233 | /// Otherwise, this is a byte offset into `token`. |
| 234 | node_or_offset: u32, | 234 | node_or_offset: u32, |
| 235 | 235 | ||
| ... | @@ -243,14 +243,12 @@ pub const CompileError = extern struct { | ... | @@ -243,14 +243,12 @@ pub const CompileError = extern struct { |
| 243 | 243 | ||
| 244 | pub const Note = extern struct { | 244 | pub const Note = extern struct { |
| 245 | msg: NullTerminatedString, | 245 | msg: NullTerminatedString, |
| 246 | token: Ast.TokenIndex, | 246 | token: Ast.OptionalTokenIndex, |
| 247 | /// If `token == invalid_token`, this is an `Ast.Node.Index`. | 247 | /// If `token == .none`, this is an `Ast.Node.Index`. |
| 248 | /// Otherwise, this is a byte offset into `token`. | 248 | /// Otherwise, this is a byte offset into `token`. |
| 249 | node_or_offset: u32, | 249 | node_or_offset: u32, |
| 250 | }; | 250 | }; |
| 251 | 251 | ||
| 252 | pub const invalid_token: Ast.TokenIndex = std.math.maxInt(Ast.TokenIndex); | ||
| 253 | |||
| 254 | comptime { | 252 | comptime { |
| 255 | assert(std.meta.hasUniqueRepresentation(CompileError)); | 253 | assert(std.meta.hasUniqueRepresentation(CompileError)); |
| 256 | assert(std.meta.hasUniqueRepresentation(Note)); | 254 | assert(std.meta.hasUniqueRepresentation(Note)); |
lib/std/zig/ZonGen.zig+43-55| ... | @@ -48,7 +48,7 @@ pub fn generate(gpa: Allocator, tree: Ast, options: Options) Allocator.Error!Zoi | ... | @@ -48,7 +48,7 @@ pub fn generate(gpa: Allocator, tree: Ast, options: Options) Allocator.Error!Zoi |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | if (tree.errors.len == 0) { | 50 | if (tree.errors.len == 0) { |
| 51 | const root_ast_node = tree.nodes.items(.data)[0].lhs; | 51 | const root_ast_node = tree.rootDecls()[0]; |
| 52 | try zg.nodes.append(gpa, undefined); // index 0; root node | 52 | try zg.nodes.append(gpa, undefined); // index 0; root node |
| 53 | try zg.expr(root_ast_node, .root); | 53 | try zg.expr(root_ast_node, .root); |
| 54 | } else { | 54 | } else { |
| ... | @@ -97,11 +97,8 @@ pub fn generate(gpa: Allocator, tree: Ast, options: Options) Allocator.Error!Zoi | ... | @@ -97,11 +97,8 @@ pub fn generate(gpa: Allocator, tree: Ast, options: Options) Allocator.Error!Zoi |
| 97 | fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator.Error!void { | 97 | fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator.Error!void { |
| 98 | const gpa = zg.gpa; | 98 | const gpa = zg.gpa; |
| 99 | const tree = zg.tree; | 99 | const tree = zg.tree; |
| 100 | const node_tags = tree.nodes.items(.tag); | ||
| 101 | const node_datas = tree.nodes.items(.data); | ||
| 102 | const main_tokens = tree.nodes.items(.main_token); | ||
| 103 | 100 | ||
| 104 | switch (node_tags[node]) { | 101 | switch (tree.nodeTag(node)) { |
| 105 | .root => unreachable, | 102 | .root => unreachable, |
| 106 | .@"usingnamespace" => unreachable, | 103 | .@"usingnamespace" => unreachable, |
| 107 | .test_decl => unreachable, | 104 | .test_decl => unreachable, |
| ... | @@ -173,7 +170,7 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator | ... | @@ -173,7 +170,7 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator |
| 173 | .bool_not, | 170 | .bool_not, |
| 174 | .bit_not, | 171 | .bit_not, |
| 175 | .negation_wrap, | 172 | .negation_wrap, |
| 176 | => try zg.addErrorTok(main_tokens[node], "operator '{s}' is not allowed in ZON", .{tree.tokenSlice(main_tokens[node])}), | 173 | => try zg.addErrorTok(tree.nodeMainToken(node), "operator '{s}' is not allowed in ZON", .{tree.tokenSlice(tree.nodeMainToken(node))}), |
| 177 | 174 | ||
| 178 | .error_union, | 175 | .error_union, |
| 179 | .merge_error_sets, | 176 | .merge_error_sets, |
| ... | @@ -251,8 +248,8 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator | ... | @@ -251,8 +248,8 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator |
| 251 | .slice_sentinel, | 248 | .slice_sentinel, |
| 252 | => try zg.addErrorNode(node, "slice operator is not allowed in ZON", .{}), | 249 | => try zg.addErrorNode(node, "slice operator is not allowed in ZON", .{}), |
| 253 | 250 | ||
| 254 | .deref, .address_of => try zg.addErrorTok(main_tokens[node], "pointers are not available in ZON", .{}), | 251 | .deref, .address_of => try zg.addErrorTok(tree.nodeMainToken(node), "pointers are not available in ZON", .{}), |
| 255 | .unwrap_optional => try zg.addErrorTok(main_tokens[node], "optionals are not available in ZON", .{}), | 252 | .unwrap_optional => try zg.addErrorTok(tree.nodeMainToken(node), "optionals are not available in ZON", .{}), |
| 256 | .error_value => try zg.addErrorNode(node, "errors are not available in ZON", .{}), | 253 | .error_value => try zg.addErrorNode(node, "errors are not available in ZON", .{}), |
| 257 | 254 | ||
| 258 | .array_access => try zg.addErrorNode(node, "array indexing is not allowed in ZON", .{}), | 255 | .array_access => try zg.addErrorNode(node, "array indexing is not allowed in ZON", .{}), |
| ... | @@ -262,12 +259,9 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator | ... | @@ -262,12 +259,9 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator |
| 262 | .block, | 259 | .block, |
| 263 | .block_semicolon, | 260 | .block_semicolon, |
| 264 | => { | 261 | => { |
| 265 | const size = switch (node_tags[node]) { | 262 | var buffer: [2]Ast.Node.Index = undefined; |
| 266 | .block_two, .block_two_semicolon => @intFromBool(node_datas[node].lhs != 0) + @intFromBool(node_datas[node].rhs != 0), | 263 | const statements = tree.blockStatements(&buffer, node).?; |
| 267 | .block, .block_semicolon => node_datas[node].rhs - node_datas[node].lhs, | 264 | if (statements.len == 0) { |
| 268 | else => unreachable, | ||
| 269 | }; | ||
| 270 | if (size == 0) { | ||
| 271 | try zg.addErrorNodeNotes(node, "void literals are not available in ZON", .{}, &.{ | 265 | try zg.addErrorNodeNotes(node, "void literals are not available in ZON", .{}, &.{ |
| 272 | try zg.errNoteNode(node, "void union payloads can be represented by enum literals", .{}), | 266 | try zg.errNoteNode(node, "void union payloads can be represented by enum literals", .{}), |
| 273 | }); | 267 | }); |
| ... | @@ -288,9 +282,9 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator | ... | @@ -288,9 +282,9 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator |
| 288 | var buf: [2]Ast.Node.Index = undefined; | 282 | var buf: [2]Ast.Node.Index = undefined; |
| 289 | 283 | ||
| 290 | const type_node = if (tree.fullArrayInit(&buf, node)) |full| | 284 | const type_node = if (tree.fullArrayInit(&buf, node)) |full| |
| 291 | full.ast.type_expr | 285 | full.ast.type_expr.unwrap().? |
| 292 | else if (tree.fullStructInit(&buf, node)) |full| | 286 | else if (tree.fullStructInit(&buf, node)) |full| |
| 293 | full.ast.type_expr | 287 | full.ast.type_expr.unwrap().? |
| 294 | else | 288 | else |
| 295 | unreachable; | 289 | unreachable; |
| 296 | 290 | ||
| ... | @@ -300,18 +294,18 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator | ... | @@ -300,18 +294,18 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator |
| 300 | }, | 294 | }, |
| 301 | 295 | ||
| 302 | .grouped_expression => { | 296 | .grouped_expression => { |
| 303 | try zg.addErrorTokNotes(main_tokens[node], "expression grouping is not allowed in ZON", .{}, &.{ | 297 | try zg.addErrorTokNotes(tree.nodeMainToken(node), "expression grouping is not allowed in ZON", .{}, &.{ |
| 304 | try zg.errNoteTok(main_tokens[node], "these parentheses are always redundant", .{}), | 298 | try zg.errNoteTok(tree.nodeMainToken(node), "these parentheses are always redundant", .{}), |
| 305 | }); | 299 | }); |
| 306 | return zg.expr(node_datas[node].lhs, dest_node); | 300 | return zg.expr(tree.nodeData(node).node_and_token[0], dest_node); |
| 307 | }, | 301 | }, |
| 308 | 302 | ||
| 309 | .negation => { | 303 | .negation => { |
| 310 | const child_node = node_datas[node].lhs; | 304 | const child_node = tree.nodeData(node).node; |
| 311 | switch (node_tags[child_node]) { | 305 | switch (tree.nodeTag(child_node)) { |
| 312 | .number_literal => return zg.numberLiteral(child_node, node, dest_node, .negative), | 306 | .number_literal => return zg.numberLiteral(child_node, node, dest_node, .negative), |
| 313 | .identifier => { | 307 | .identifier => { |
| 314 | const child_ident = tree.tokenSlice(main_tokens[child_node]); | 308 | const child_ident = tree.tokenSlice(tree.nodeMainToken(child_node)); |
| 315 | if (mem.eql(u8, child_ident, "inf")) { | 309 | if (mem.eql(u8, child_ident, "inf")) { |
| 316 | zg.setNode(dest_node, .{ | 310 | zg.setNode(dest_node, .{ |
| 317 | .tag = .neg_inf, | 311 | .tag = .neg_inf, |
| ... | @@ -323,7 +317,7 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator | ... | @@ -323,7 +317,7 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator |
| 323 | }, | 317 | }, |
| 324 | else => {}, | 318 | else => {}, |
| 325 | } | 319 | } |
| 326 | try zg.addErrorTok(main_tokens[node], "expected number or 'inf' after '-'", .{}); | 320 | try zg.addErrorTok(tree.nodeMainToken(node), "expected number or 'inf' after '-'", .{}); |
| 327 | }, | 321 | }, |
| 328 | .number_literal => try zg.numberLiteral(node, node, dest_node, .positive), | 322 | .number_literal => try zg.numberLiteral(node, node, dest_node, .positive), |
| 329 | .char_literal => try zg.charLiteral(node, dest_node), | 323 | .char_literal => try zg.charLiteral(node, dest_node), |
| ... | @@ -331,7 +325,7 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator | ... | @@ -331,7 +325,7 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator |
| 331 | .identifier => try zg.identifier(node, dest_node), | 325 | .identifier => try zg.identifier(node, dest_node), |
| 332 | 326 | ||
| 333 | .enum_literal => { | 327 | .enum_literal => { |
| 334 | const str_index = zg.identAsString(main_tokens[node]) catch |err| switch (err) { | 328 | const str_index = zg.identAsString(tree.nodeMainToken(node)) catch |err| switch (err) { |
| 335 | error.BadString => undefined, // doesn't matter, there's an error | 329 | error.BadString => undefined, // doesn't matter, there's an error |
| 336 | error.OutOfMemory => |e| return e, | 330 | error.OutOfMemory => |e| return e, |
| 337 | }; | 331 | }; |
| ... | @@ -369,7 +363,7 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator | ... | @@ -369,7 +363,7 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator |
| 369 | var buf: [2]Ast.Node.Index = undefined; | 363 | var buf: [2]Ast.Node.Index = undefined; |
| 370 | const full = tree.fullArrayInit(&buf, node).?; | 364 | const full = tree.fullArrayInit(&buf, node).?; |
| 371 | assert(full.ast.elements.len != 0); // Otherwise it would be a struct init | 365 | assert(full.ast.elements.len != 0); // Otherwise it would be a struct init |
| 372 | assert(full.ast.type_expr == 0); // The tag was `array_init_dot_*` | 366 | assert(full.ast.type_expr == .none); // The tag was `array_init_dot_*` |
| 373 | 367 | ||
| 374 | const first_elem: u32 = @intCast(zg.nodes.len); | 368 | const first_elem: u32 = @intCast(zg.nodes.len); |
| 375 | try zg.nodes.resize(gpa, zg.nodes.len + full.ast.elements.len); | 369 | try zg.nodes.resize(gpa, zg.nodes.len + full.ast.elements.len); |
| ... | @@ -398,7 +392,7 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator | ... | @@ -398,7 +392,7 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator |
| 398 | => { | 392 | => { |
| 399 | var buf: [2]Ast.Node.Index = undefined; | 393 | var buf: [2]Ast.Node.Index = undefined; |
| 400 | const full = tree.fullStructInit(&buf, node).?; | 394 | const full = tree.fullStructInit(&buf, node).?; |
| 401 | assert(full.ast.type_expr == 0); // The tag was `struct_init_dot_*` | 395 | assert(full.ast.type_expr == .none); // The tag was `struct_init_dot_*` |
| 402 | 396 | ||
| 403 | if (full.ast.fields.len == 0) { | 397 | if (full.ast.fields.len == 0) { |
| 404 | zg.setNode(dest_node, .{ | 398 | zg.setNode(dest_node, .{ |
| ... | @@ -460,7 +454,7 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator | ... | @@ -460,7 +454,7 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator |
| 460 | 454 | ||
| 461 | fn appendIdentStr(zg: *ZonGen, ident_token: Ast.TokenIndex) !u32 { | 455 | fn appendIdentStr(zg: *ZonGen, ident_token: Ast.TokenIndex) !u32 { |
| 462 | const tree = zg.tree; | 456 | const tree = zg.tree; |
| 463 | assert(tree.tokens.items(.tag)[ident_token] == .identifier); | 457 | assert(tree.tokenTag(ident_token) == .identifier); |
| 464 | const ident_name = tree.tokenSlice(ident_token); | 458 | const ident_name = tree.tokenSlice(ident_token); |
| 465 | if (!mem.startsWith(u8, ident_name, "@")) { | 459 | if (!mem.startsWith(u8, ident_name, "@")) { |
| 466 | const start = zg.string_bytes.items.len; | 460 | const start = zg.string_bytes.items.len; |
| ... | @@ -493,19 +487,16 @@ fn appendIdentStr(zg: *ZonGen, ident_token: Ast.TokenIndex) !u32 { | ... | @@ -493,19 +487,16 @@ fn appendIdentStr(zg: *ZonGen, ident_token: Ast.TokenIndex) !u32 { |
| 493 | 487 | ||
| 494 | /// Estimates the size of a string node without parsing it. | 488 | /// Estimates the size of a string node without parsing it. |
| 495 | pub fn strLitSizeHint(tree: Ast, node: Ast.Node.Index) usize { | 489 | pub fn strLitSizeHint(tree: Ast, node: Ast.Node.Index) usize { |
| 496 | switch (tree.nodes.items(.tag)[node]) { | 490 | switch (tree.nodeTag(node)) { |
| 497 | // Parsed string literals are typically around the size of the raw strings. | 491 | // Parsed string literals are typically around the size of the raw strings. |
| 498 | .string_literal => { | 492 | .string_literal => { |
| 499 | const token = tree.nodes.items(.main_token)[node]; | 493 | const token = tree.nodeMainToken(node); |
| 500 | const raw_string = tree.tokenSlice(token); | 494 | const raw_string = tree.tokenSlice(token); |
| 501 | return raw_string.len; | 495 | return raw_string.len; |
| 502 | }, | 496 | }, |
| 503 | // Multiline string literal lengths can be computed exactly. | 497 | // Multiline string literal lengths can be computed exactly. |
| 504 | .multiline_string_literal => { | 498 | .multiline_string_literal => { |
| 505 | const first_tok, const last_tok = bounds: { | 499 | const first_tok, const last_tok = tree.nodeData(node).token_and_token; |
| 506 | const node_data = tree.nodes.items(.data)[node]; | ||
| 507 | break :bounds .{ node_data.lhs, node_data.rhs }; | ||
| 508 | }; | ||
| 509 | 500 | ||
| 510 | var size = tree.tokenSlice(first_tok)[2..].len; | 501 | var size = tree.tokenSlice(first_tok)[2..].len; |
| 511 | for (first_tok + 1..last_tok + 1) |tok_idx| { | 502 | for (first_tok + 1..last_tok + 1) |tok_idx| { |
| ... | @@ -524,17 +515,14 @@ pub fn parseStrLit( | ... | @@ -524,17 +515,14 @@ pub fn parseStrLit( |
| 524 | node: Ast.Node.Index, | 515 | node: Ast.Node.Index, |
| 525 | writer: anytype, | 516 | writer: anytype, |
| 526 | ) error{OutOfMemory}!std.zig.string_literal.Result { | 517 | ) error{OutOfMemory}!std.zig.string_literal.Result { |
| 527 | switch (tree.nodes.items(.tag)[node]) { | 518 | switch (tree.nodeTag(node)) { |
| 528 | .string_literal => { | 519 | .string_literal => { |
| 529 | const token = tree.nodes.items(.main_token)[node]; | 520 | const token = tree.nodeMainToken(node); |
| 530 | const raw_string = tree.tokenSlice(token); | 521 | const raw_string = tree.tokenSlice(token); |
| 531 | return std.zig.string_literal.parseWrite(writer, raw_string); | 522 | return std.zig.string_literal.parseWrite(writer, raw_string); |
| 532 | }, | 523 | }, |
| 533 | .multiline_string_literal => { | 524 | .multiline_string_literal => { |
| 534 | const first_tok, const last_tok = bounds: { | 525 | const first_tok, const last_tok = tree.nodeData(node).token_and_token; |
| 535 | const node_data = tree.nodes.items(.data)[node]; | ||
| 536 | break :bounds .{ node_data.lhs, node_data.rhs }; | ||
| 537 | }; | ||
| 538 | 526 | ||
| 539 | // First line: do not append a newline. | 527 | // First line: do not append a newline. |
| 540 | { | 528 | { |
| ... | @@ -572,7 +560,7 @@ fn strLitAsString(zg: *ZonGen, str_node: Ast.Node.Index) !StringLiteralResult { | ... | @@ -572,7 +560,7 @@ fn strLitAsString(zg: *ZonGen, str_node: Ast.Node.Index) !StringLiteralResult { |
| 572 | switch (try parseStrLit(zg.tree, str_node, zg.string_bytes.writer(zg.gpa))) { | 560 | switch (try parseStrLit(zg.tree, str_node, zg.string_bytes.writer(zg.gpa))) { |
| 573 | .success => {}, | 561 | .success => {}, |
| 574 | .failure => |err| { | 562 | .failure => |err| { |
| 575 | const token = zg.tree.nodes.items(.main_token)[str_node]; | 563 | const token = zg.tree.nodeMainToken(str_node); |
| 576 | const raw_string = zg.tree.tokenSlice(token); | 564 | const raw_string = zg.tree.tokenSlice(token); |
| 577 | try zg.lowerStrLitError(err, token, raw_string, 0); | 565 | try zg.lowerStrLitError(err, token, raw_string, 0); |
| 578 | return error.BadString; | 566 | return error.BadString; |
| ... | @@ -620,7 +608,7 @@ fn identAsString(zg: *ZonGen, ident_token: Ast.TokenIndex) !Zoir.NullTerminatedS | ... | @@ -620,7 +608,7 @@ fn identAsString(zg: *ZonGen, ident_token: Ast.TokenIndex) !Zoir.NullTerminatedS |
| 620 | 608 | ||
| 621 | fn numberLiteral(zg: *ZonGen, num_node: Ast.Node.Index, src_node: Ast.Node.Index, dest_node: Zoir.Node.Index, sign: enum { negative, positive }) !void { | 609 | fn numberLiteral(zg: *ZonGen, num_node: Ast.Node.Index, src_node: Ast.Node.Index, dest_node: Zoir.Node.Index, sign: enum { negative, positive }) !void { |
| 622 | const tree = zg.tree; | 610 | const tree = zg.tree; |
| 623 | const num_token = tree.nodes.items(.main_token)[num_node]; | 611 | const num_token = tree.nodeMainToken(num_node); |
| 624 | const num_bytes = tree.tokenSlice(num_token); | 612 | const num_bytes = tree.tokenSlice(num_token); |
| 625 | 613 | ||
| 626 | switch (std.zig.parseNumberLiteral(num_bytes)) { | 614 | switch (std.zig.parseNumberLiteral(num_bytes)) { |
| ... | @@ -724,8 +712,8 @@ fn setBigIntLiteralNode(zg: *ZonGen, dest_node: Zoir.Node.Index, src_node: Ast.N | ... | @@ -724,8 +712,8 @@ fn setBigIntLiteralNode(zg: *ZonGen, dest_node: Zoir.Node.Index, src_node: Ast.N |
| 724 | 712 | ||
| 725 | fn charLiteral(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) !void { | 713 | fn charLiteral(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) !void { |
| 726 | const tree = zg.tree; | 714 | const tree = zg.tree; |
| 727 | assert(tree.nodes.items(.tag)[node] == .char_literal); | 715 | assert(tree.nodeTag(node) == .char_literal); |
| 728 | const main_token = tree.nodes.items(.main_token)[node]; | 716 | const main_token = tree.nodeMainToken(node); |
| 729 | const slice = tree.tokenSlice(main_token); | 717 | const slice = tree.tokenSlice(main_token); |
| 730 | switch (std.zig.parseCharLiteral(slice)) { | 718 | switch (std.zig.parseCharLiteral(slice)) { |
| 731 | .success => |codepoint| zg.setNode(dest_node, .{ | 719 | .success => |codepoint| zg.setNode(dest_node, .{ |
| ... | @@ -739,8 +727,8 @@ fn charLiteral(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) !v | ... | @@ -739,8 +727,8 @@ fn charLiteral(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) !v |
| 739 | 727 | ||
| 740 | fn identifier(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) !void { | 728 | fn identifier(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) !void { |
| 741 | const tree = zg.tree; | 729 | const tree = zg.tree; |
| 742 | assert(tree.nodes.items(.tag)[node] == .identifier); | 730 | assert(tree.nodeTag(node) == .identifier); |
| 743 | const main_token = tree.nodes.items(.main_token)[node]; | 731 | const main_token = tree.nodeMainToken(node); |
| 744 | const ident = tree.tokenSlice(main_token); | 732 | const ident = tree.tokenSlice(main_token); |
| 745 | 733 | ||
| 746 | const tag: Zoir.Node.Repr.Tag = t: { | 734 | const tag: Zoir.Node.Repr.Tag = t: { |
| ... | @@ -823,8 +811,8 @@ fn errNoteNode(zg: *ZonGen, node: Ast.Node.Index, comptime format: []const u8, a | ... | @@ -823,8 +811,8 @@ fn errNoteNode(zg: *ZonGen, node: Ast.Node.Index, comptime format: []const u8, a |
| 823 | 811 | ||
| 824 | return .{ | 812 | return .{ |
| 825 | .msg = @enumFromInt(message_idx), | 813 | .msg = @enumFromInt(message_idx), |
| 826 | .token = Zoir.CompileError.invalid_token, | 814 | .token = .none, |
| 827 | .node_or_offset = node, | 815 | .node_or_offset = @intFromEnum(node), |
| 828 | }; | 816 | }; |
| 829 | } | 817 | } |
| 830 | 818 | ||
| ... | @@ -836,33 +824,33 @@ fn errNoteTok(zg: *ZonGen, tok: Ast.TokenIndex, comptime format: []const u8, arg | ... | @@ -836,33 +824,33 @@ fn errNoteTok(zg: *ZonGen, tok: Ast.TokenIndex, comptime format: []const u8, arg |
| 836 | 824 | ||
| 837 | return .{ | 825 | return .{ |
| 838 | .msg = @enumFromInt(message_idx), | 826 | .msg = @enumFromInt(message_idx), |
| 839 | .token = tok, | 827 | .token = .fromToken(tok), |
| 840 | .node_or_offset = 0, | 828 | .node_or_offset = 0, |
| 841 | }; | 829 | }; |
| 842 | } | 830 | } |
| 843 | 831 | ||
| 844 | fn addErrorNode(zg: *ZonGen, node: Ast.Node.Index, comptime format: []const u8, args: anytype) Allocator.Error!void { | 832 | fn addErrorNode(zg: *ZonGen, node: Ast.Node.Index, comptime format: []const u8, args: anytype) Allocator.Error!void { |
| 845 | return zg.addErrorInner(Zoir.CompileError.invalid_token, node, format, args, &.{}); | 833 | return zg.addErrorInner(.none, @intFromEnum(node), format, args, &.{}); |
| 846 | } | 834 | } |
| 847 | fn addErrorTok(zg: *ZonGen, tok: Ast.TokenIndex, comptime format: []const u8, args: anytype) Allocator.Error!void { | 835 | fn addErrorTok(zg: *ZonGen, tok: Ast.TokenIndex, comptime format: []const u8, args: anytype) Allocator.Error!void { |
| 848 | return zg.addErrorInner(tok, 0, format, args, &.{}); | 836 | return zg.addErrorInner(.fromToken(tok), 0, format, args, &.{}); |
| 849 | } | 837 | } |
| 850 | fn addErrorNodeNotes(zg: *ZonGen, node: Ast.Node.Index, comptime format: []const u8, args: anytype, notes: []const Zoir.CompileError.Note) Allocator.Error!void { | 838 | fn addErrorNodeNotes(zg: *ZonGen, node: Ast.Node.Index, comptime format: []const u8, args: anytype, notes: []const Zoir.CompileError.Note) Allocator.Error!void { |
| 851 | return zg.addErrorInner(Zoir.CompileError.invalid_token, node, format, args, notes); | 839 | return zg.addErrorInner(.none, @intFromEnum(node), format, args, notes); |
| 852 | } | 840 | } |
| 853 | fn addErrorTokNotes(zg: *ZonGen, tok: Ast.TokenIndex, comptime format: []const u8, args: anytype, notes: []const Zoir.CompileError.Note) Allocator.Error!void { | 841 | fn addErrorTokNotes(zg: *ZonGen, tok: Ast.TokenIndex, comptime format: []const u8, args: anytype, notes: []const Zoir.CompileError.Note) Allocator.Error!void { |
| 854 | return zg.addErrorInner(tok, 0, format, args, notes); | 842 | return zg.addErrorInner(.fromToken(tok), 0, format, args, notes); |
| 855 | } | 843 | } |
| 856 | fn addErrorTokOff(zg: *ZonGen, tok: Ast.TokenIndex, offset: u32, comptime format: []const u8, args: anytype) Allocator.Error!void { | 844 | fn addErrorTokOff(zg: *ZonGen, tok: Ast.TokenIndex, offset: u32, comptime format: []const u8, args: anytype) Allocator.Error!void { |
| 857 | return zg.addErrorInner(tok, offset, format, args, &.{}); | 845 | return zg.addErrorInner(.fromToken(tok), offset, format, args, &.{}); |
| 858 | } | 846 | } |
| 859 | fn addErrorTokNotesOff(zg: *ZonGen, tok: Ast.TokenIndex, offset: u32, comptime format: []const u8, args: anytype, notes: []const Zoir.CompileError.Note) Allocator.Error!void { | 847 | fn addErrorTokNotesOff(zg: *ZonGen, tok: Ast.TokenIndex, offset: u32, comptime format: []const u8, args: anytype, notes: []const Zoir.CompileError.Note) Allocator.Error!void { |
| 860 | return zg.addErrorInner(tok, offset, format, args, notes); | 848 | return zg.addErrorInner(.fromToken(tok), offset, format, args, notes); |
| 861 | } | 849 | } |
| 862 | 850 | ||
| 863 | fn addErrorInner( | 851 | fn addErrorInner( |
| 864 | zg: *ZonGen, | 852 | zg: *ZonGen, |
| 865 | token: Ast.TokenIndex, | 853 | token: Ast.OptionalTokenIndex, |
| 866 | node_or_offset: u32, | 854 | node_or_offset: u32, |
| 867 | comptime format: []const u8, | 855 | comptime format: []const u8, |
| 868 | args: anytype, | 856 | args: anytype, |
lib/std/zig/render.zig+459-487| ... | @@ -91,21 +91,22 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: Ast, fixups: Fixups) Error!v | ... | @@ -91,21 +91,22 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: Ast, fixups: Fixups) Error!v |
| 91 | }; | 91 | }; |
| 92 | 92 | ||
| 93 | // Render all the line comments at the beginning of the file. | 93 | // Render all the line comments at the beginning of the file. |
| 94 | const comment_end_loc = tree.tokens.items(.start)[0]; | 94 | const comment_end_loc = tree.tokenStart(0); |
| 95 | _ = try renderComments(&r, 0, comment_end_loc); | 95 | _ = try renderComments(&r, 0, comment_end_loc); |
| 96 | 96 | ||
| 97 | if (tree.tokens.items(.tag)[0] == .container_doc_comment) { | 97 | if (tree.tokenTag(0) == .container_doc_comment) { |
| 98 | try renderContainerDocComments(&r, 0); | 98 | try renderContainerDocComments(&r, 0); |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | if (tree.mode == .zon) { | 101 | switch (tree.mode) { |
| 102 | try renderExpression( | 102 | .zig => try renderMembers(&r, tree.rootDecls()), |
| 103 | &r, | 103 | .zon => { |
| 104 | tree.nodes.items(.data)[0].lhs, | 104 | try renderExpression( |
| 105 | .newline, | 105 | &r, |
| 106 | ); | 106 | tree.rootDecls()[0], |
| 107 | } else { | 107 | .newline, |
| 108 | try renderMembers(&r, tree.rootDecls()); | 108 | ); |
| 109 | }, | ||
| 109 | } | 110 | } |
| 110 | 111 | ||
| 111 | if (auto_indenting_stream.disabled_offset) |disabled_offset| { | 112 | if (auto_indenting_stream.disabled_offset) |disabled_offset| { |
| ... | @@ -141,23 +142,20 @@ fn renderMember( | ... | @@ -141,23 +142,20 @@ fn renderMember( |
| 141 | ) Error!void { | 142 | ) Error!void { |
| 142 | const tree = r.tree; | 143 | const tree = r.tree; |
| 143 | const ais = r.ais; | 144 | const ais = r.ais; |
| 144 | const token_tags = tree.tokens.items(.tag); | ||
| 145 | const main_tokens = tree.nodes.items(.main_token); | ||
| 146 | const datas = tree.nodes.items(.data); | ||
| 147 | if (r.fixups.omit_nodes.contains(decl)) return; | 145 | if (r.fixups.omit_nodes.contains(decl)) return; |
| 148 | try renderDocComments(r, tree.firstToken(decl)); | 146 | try renderDocComments(r, tree.firstToken(decl)); |
| 149 | switch (tree.nodes.items(.tag)[decl]) { | 147 | switch (tree.nodeTag(decl)) { |
| 150 | .fn_decl => { | 148 | .fn_decl => { |
| 151 | // Some examples: | 149 | // Some examples: |
| 152 | // pub extern "foo" fn ... | 150 | // pub extern "foo" fn ... |
| 153 | // export fn ... | 151 | // export fn ... |
| 154 | const fn_proto = datas[decl].lhs; | 152 | const fn_proto, const body_node = tree.nodeData(decl).node_and_node; |
| 155 | const fn_token = main_tokens[fn_proto]; | 153 | const fn_token = tree.nodeMainToken(fn_proto); |
| 156 | // Go back to the first token we should render here. | 154 | // Go back to the first token we should render here. |
| 157 | var i = fn_token; | 155 | var i = fn_token; |
| 158 | while (i > 0) { | 156 | while (i > 0) { |
| 159 | i -= 1; | 157 | i -= 1; |
| 160 | switch (token_tags[i]) { | 158 | switch (tree.tokenTag(i)) { |
| 161 | .keyword_extern, | 159 | .keyword_extern, |
| 162 | .keyword_export, | 160 | .keyword_export, |
| 163 | .keyword_pub, | 161 | .keyword_pub, |
| ... | @@ -172,31 +170,34 @@ fn renderMember( | ... | @@ -172,31 +170,34 @@ fn renderMember( |
| 172 | }, | 170 | }, |
| 173 | } | 171 | } |
| 174 | } | 172 | } |
| 173 | |||
| 175 | while (i < fn_token) : (i += 1) { | 174 | while (i < fn_token) : (i += 1) { |
| 176 | try renderToken(r, i, .space); | 175 | try renderToken(r, i, .space); |
| 177 | } | 176 | } |
| 178 | switch (tree.nodes.items(.tag)[fn_proto]) { | 177 | switch (tree.nodeTag(fn_proto)) { |
| 179 | .fn_proto_one, .fn_proto => { | 178 | .fn_proto_one, .fn_proto => { |
| 180 | const callconv_expr = if (tree.nodes.items(.tag)[fn_proto] == .fn_proto_one) | 179 | var buf: [1]Ast.Node.Index = undefined; |
| 181 | tree.extraData(datas[fn_proto].lhs, Ast.Node.FnProtoOne).callconv_expr | 180 | const opt_callconv_expr = if (tree.nodeTag(fn_proto) == .fn_proto_one) |
| 181 | tree.fnProtoOne(&buf, fn_proto).ast.callconv_expr | ||
| 182 | else | 182 | else |
| 183 | tree.extraData(datas[fn_proto].lhs, Ast.Node.FnProto).callconv_expr; | 183 | tree.fnProto(fn_proto).ast.callconv_expr; |
| 184 | |||
| 184 | // Keep in sync with logic in `renderFnProto`. Search this file for the marker PROMOTE_CALLCONV_INLINE | 185 | // Keep in sync with logic in `renderFnProto`. Search this file for the marker PROMOTE_CALLCONV_INLINE |
| 185 | if (callconv_expr != 0 and tree.nodes.items(.tag)[callconv_expr] == .enum_literal) { | 186 | if (opt_callconv_expr.unwrap()) |callconv_expr| { |
| 186 | if (mem.eql(u8, "@\"inline\"", tree.tokenSlice(main_tokens[callconv_expr]))) { | 187 | if (tree.nodeTag(callconv_expr) == .enum_literal) { |
| 187 | try ais.writer().writeAll("inline "); | 188 | if (mem.eql(u8, "@\"inline\"", tree.tokenSlice(tree.nodeMainToken(callconv_expr)))) { |
| 189 | try ais.writer().writeAll("inline "); | ||
| 190 | } | ||
| 188 | } | 191 | } |
| 189 | } | 192 | } |
| 190 | }, | 193 | }, |
| 191 | .fn_proto_simple, .fn_proto_multi => {}, | 194 | .fn_proto_simple, .fn_proto_multi => {}, |
| 192 | else => unreachable, | 195 | else => unreachable, |
| 193 | } | 196 | } |
| 194 | assert(datas[decl].rhs != 0); | ||
| 195 | try renderExpression(r, fn_proto, .space); | 197 | try renderExpression(r, fn_proto, .space); |
| 196 | const body_node = datas[decl].rhs; | ||
| 197 | if (r.fixups.gut_functions.contains(decl)) { | 198 | if (r.fixups.gut_functions.contains(decl)) { |
| 198 | try ais.pushIndent(.normal); | 199 | try ais.pushIndent(.normal); |
| 199 | const lbrace = tree.nodes.items(.main_token)[body_node]; | 200 | const lbrace = tree.nodeMainToken(body_node); |
| 200 | try renderToken(r, lbrace, .newline); | 201 | try renderToken(r, lbrace, .newline); |
| 201 | try discardAllParams(r, fn_proto); | 202 | try discardAllParams(r, fn_proto); |
| 202 | try ais.writer().writeAll("@trap();"); | 203 | try ais.writer().writeAll("@trap();"); |
| ... | @@ -205,7 +206,7 @@ fn renderMember( | ... | @@ -205,7 +206,7 @@ fn renderMember( |
| 205 | try renderToken(r, tree.lastToken(body_node), space); // rbrace | 206 | try renderToken(r, tree.lastToken(body_node), space); // rbrace |
| 206 | } else if (r.fixups.unused_var_decls.count() != 0) { | 207 | } else if (r.fixups.unused_var_decls.count() != 0) { |
| 207 | try ais.pushIndent(.normal); | 208 | try ais.pushIndent(.normal); |
| 208 | const lbrace = tree.nodes.items(.main_token)[body_node]; | 209 | const lbrace = tree.nodeMainToken(body_node); |
| 209 | try renderToken(r, lbrace, .newline); | 210 | try renderToken(r, lbrace, .newline); |
| 210 | 211 | ||
| 211 | var fn_proto_buf: [1]Ast.Node.Index = undefined; | 212 | var fn_proto_buf: [1]Ast.Node.Index = undefined; |
| ... | @@ -213,7 +214,7 @@ fn renderMember( | ... | @@ -213,7 +214,7 @@ fn renderMember( |
| 213 | var it = full_fn_proto.iterate(&tree); | 214 | var it = full_fn_proto.iterate(&tree); |
| 214 | while (it.next()) |param| { | 215 | while (it.next()) |param| { |
| 215 | const name_ident = param.name_token.?; | 216 | const name_ident = param.name_token.?; |
| 216 | assert(token_tags[name_ident] == .identifier); | 217 | assert(tree.tokenTag(name_ident) == .identifier); |
| 217 | if (r.fixups.unused_var_decls.contains(name_ident)) { | 218 | if (r.fixups.unused_var_decls.contains(name_ident)) { |
| 218 | const w = ais.writer(); | 219 | const w = ais.writer(); |
| 219 | try w.writeAll("_ = "); | 220 | try w.writeAll("_ = "); |
| ... | @@ -235,11 +236,11 @@ fn renderMember( | ... | @@ -235,11 +236,11 @@ fn renderMember( |
| 235 | => { | 236 | => { |
| 236 | // Extern function prototypes are parsed as these tags. | 237 | // Extern function prototypes are parsed as these tags. |
| 237 | // Go back to the first token we should render here. | 238 | // Go back to the first token we should render here. |
| 238 | const fn_token = main_tokens[decl]; | 239 | const fn_token = tree.nodeMainToken(decl); |
| 239 | var i = fn_token; | 240 | var i = fn_token; |
| 240 | while (i > 0) { | 241 | while (i > 0) { |
| 241 | i -= 1; | 242 | i -= 1; |
| 242 | switch (token_tags[i]) { | 243 | switch (tree.tokenTag(i)) { |
| 243 | .keyword_extern, | 244 | .keyword_extern, |
| 244 | .keyword_export, | 245 | .keyword_export, |
| 245 | .keyword_pub, | 246 | .keyword_pub, |
| ... | @@ -262,9 +263,9 @@ fn renderMember( | ... | @@ -262,9 +263,9 @@ fn renderMember( |
| 262 | }, | 263 | }, |
| 263 | 264 | ||
| 264 | .@"usingnamespace" => { | 265 | .@"usingnamespace" => { |
| 265 | const main_token = main_tokens[decl]; | 266 | const main_token = tree.nodeMainToken(decl); |
| 266 | const expr = datas[decl].lhs; | 267 | const expr = tree.nodeData(decl).node; |
| 267 | if (main_token > 0 and token_tags[main_token - 1] == .keyword_pub) { | 268 | if (tree.isTokenPrecededByTags(main_token, &.{.keyword_pub})) { |
| 268 | try renderToken(r, main_token - 1, .space); // pub | 269 | try renderToken(r, main_token - 1, .space); // pub |
| 269 | } | 270 | } |
| 270 | try renderToken(r, main_token, .space); // usingnamespace | 271 | try renderToken(r, main_token, .space); // usingnamespace |
| ... | @@ -283,15 +284,17 @@ fn renderMember( | ... | @@ -283,15 +284,17 @@ fn renderMember( |
| 283 | }, | 284 | }, |
| 284 | 285 | ||
| 285 | .test_decl => { | 286 | .test_decl => { |
| 286 | const test_token = main_tokens[decl]; | 287 | const test_token = tree.nodeMainToken(decl); |
| 288 | const opt_name_token, const block_node = tree.nodeData(decl).opt_token_and_node; | ||
| 287 | try renderToken(r, test_token, .space); | 289 | try renderToken(r, test_token, .space); |
| 288 | const test_name_tag = token_tags[test_token + 1]; | 290 | if (opt_name_token.unwrap()) |name_token| { |
| 289 | switch (test_name_tag) { | 291 | switch (tree.tokenTag(name_token)) { |
| 290 | .string_literal => try renderToken(r, test_token + 1, .space), | 292 | .string_literal => try renderToken(r, name_token, .space), |
| 291 | .identifier => try renderIdentifier(r, test_token + 1, .space, .preserve_when_shadowing), | 293 | .identifier => try renderIdentifier(r, name_token, .space, .preserve_when_shadowing), |
| 292 | else => {}, | 294 | else => unreachable, |
| 295 | } | ||
| 293 | } | 296 | } |
| 294 | try renderExpression(r, datas[decl].rhs, space); | 297 | try renderExpression(r, block_node, space); |
| 295 | }, | 298 | }, |
| 296 | 299 | ||
| 297 | .container_field_init, | 300 | .container_field_init, |
| ... | @@ -319,10 +322,6 @@ fn renderExpressions(r: *Render, expressions: []const Ast.Node.Index, space: Spa | ... | @@ -319,10 +322,6 @@ fn renderExpressions(r: *Render, expressions: []const Ast.Node.Index, space: Spa |
| 319 | fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | 322 | fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 320 | const tree = r.tree; | 323 | const tree = r.tree; |
| 321 | const ais = r.ais; | 324 | const ais = r.ais; |
| 322 | const token_tags = tree.tokens.items(.tag); | ||
| 323 | const main_tokens = tree.nodes.items(.main_token); | ||
| 324 | const node_tags = tree.nodes.items(.tag); | ||
| 325 | const datas = tree.nodes.items(.data); | ||
| 326 | if (r.fixups.replace_nodes_with_string.get(node)) |replacement| { | 325 | if (r.fixups.replace_nodes_with_string.get(node)) |replacement| { |
| 327 | try ais.writer().writeAll(replacement); | 326 | try ais.writer().writeAll(replacement); |
| 328 | try renderOnlySpace(r, space); | 327 | try renderOnlySpace(r, space); |
| ... | @@ -330,9 +329,9 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -330,9 +329,9 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 330 | } else if (r.fixups.replace_nodes_with_node.get(node)) |replacement| { | 329 | } else if (r.fixups.replace_nodes_with_node.get(node)) |replacement| { |
| 331 | return renderExpression(r, replacement, space); | 330 | return renderExpression(r, replacement, space); |
| 332 | } | 331 | } |
| 333 | switch (node_tags[node]) { | 332 | switch (tree.nodeTag(node)) { |
| 334 | .identifier => { | 333 | .identifier => { |
| 335 | const token_index = main_tokens[node]; | 334 | const token_index = tree.nodeMainToken(node); |
| 336 | return renderIdentifier(r, token_index, space, .preserve_when_shadowing); | 335 | return renderIdentifier(r, token_index, space, .preserve_when_shadowing); |
| 337 | }, | 336 | }, |
| 338 | 337 | ||
| ... | @@ -341,18 +340,23 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -341,18 +340,23 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 341 | .unreachable_literal, | 340 | .unreachable_literal, |
| 342 | .anyframe_literal, | 341 | .anyframe_literal, |
| 343 | .string_literal, | 342 | .string_literal, |
| 344 | => return renderToken(r, main_tokens[node], space), | 343 | => return renderToken(r, tree.nodeMainToken(node), space), |
| 345 | 344 | ||
| 346 | .multiline_string_literal => { | 345 | .multiline_string_literal => { |
| 347 | try ais.maybeInsertNewline(); | 346 | try ais.maybeInsertNewline(); |
| 348 | 347 | ||
| 349 | var i = datas[node].lhs; | 348 | const first_tok, const last_tok = tree.nodeData(node).token_and_token; |
| 350 | while (i <= datas[node].rhs) : (i += 1) try renderToken(r, i, .newline); | 349 | for (first_tok..last_tok + 1) |i| { |
| 350 | try renderToken(r, @intCast(i), .newline); | ||
| 351 | } | ||
| 352 | |||
| 353 | const next_token = last_tok + 1; | ||
| 354 | const next_token_tag = tree.tokenTag(next_token); | ||
| 351 | 355 | ||
| 352 | // dedent the next thing that comes after a multiline string literal | 356 | // dedent the next thing that comes after a multiline string literal |
| 353 | if (!ais.indentStackEmpty() and | 357 | if (!ais.indentStackEmpty() and |
| 354 | token_tags[i] != .colon and | 358 | next_token_tag != .colon and |
| 355 | ((token_tags[i] != .semicolon and token_tags[i] != .comma) or | 359 | ((next_token_tag != .semicolon and next_token_tag != .comma) or |
| 356 | ais.lastSpaceModeIndent() < ais.currentIndent())) | 360 | ais.lastSpaceModeIndent() < ais.currentIndent())) |
| 357 | { | 361 | { |
| 358 | ais.popIndent(); | 362 | ais.popIndent(); |
| ... | @@ -361,16 +365,17 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -361,16 +365,17 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 361 | 365 | ||
| 362 | switch (space) { | 366 | switch (space) { |
| 363 | .none, .space, .newline, .skip => {}, | 367 | .none, .space, .newline, .skip => {}, |
| 364 | .semicolon => if (token_tags[i] == .semicolon) try renderTokenOverrideSpaceMode(r, i, .newline, .semicolon), | 368 | .semicolon => if (next_token_tag == .semicolon) try renderTokenOverrideSpaceMode(r, next_token, .newline, .semicolon), |
| 365 | .comma => if (token_tags[i] == .comma) try renderTokenOverrideSpaceMode(r, i, .newline, .comma), | 369 | .comma => if (next_token_tag == .comma) try renderTokenOverrideSpaceMode(r, next_token, .newline, .comma), |
| 366 | .comma_space => if (token_tags[i] == .comma) try renderToken(r, i, .space), | 370 | .comma_space => if (next_token_tag == .comma) try renderToken(r, next_token, .space), |
| 367 | } | 371 | } |
| 368 | }, | 372 | }, |
| 369 | 373 | ||
| 370 | .error_value => { | 374 | .error_value => { |
| 371 | try renderToken(r, main_tokens[node], .none); | 375 | const main_token = tree.nodeMainToken(node); |
| 372 | try renderToken(r, main_tokens[node] + 1, .none); | 376 | try renderToken(r, main_token, .none); |
| 373 | return renderIdentifier(r, main_tokens[node] + 2, space, .eagerly_unquote); | 377 | try renderToken(r, main_token + 1, .none); |
| 378 | return renderIdentifier(r, main_token + 2, space, .eagerly_unquote); | ||
| 374 | }, | 379 | }, |
| 375 | 380 | ||
| 376 | .block_two, | 381 | .block_two, |
| ... | @@ -384,12 +389,11 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -384,12 +389,11 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 384 | }, | 389 | }, |
| 385 | 390 | ||
| 386 | .@"errdefer" => { | 391 | .@"errdefer" => { |
| 387 | const defer_token = main_tokens[node]; | 392 | const defer_token = tree.nodeMainToken(node); |
| 388 | const payload_token = datas[node].lhs; | 393 | const maybe_payload_token, const expr = tree.nodeData(node).opt_token_and_node; |
| 389 | const expr = datas[node].rhs; | ||
| 390 | 394 | ||
| 391 | try renderToken(r, defer_token, .space); | 395 | try renderToken(r, defer_token, .space); |
| 392 | if (payload_token != 0) { | 396 | if (maybe_payload_token.unwrap()) |payload_token| { |
| 393 | try renderToken(r, payload_token - 1, .none); // | | 397 | try renderToken(r, payload_token - 1, .none); // | |
| 394 | try renderIdentifier(r, payload_token, .none, .preserve_when_shadowing); // identifier | 398 | try renderIdentifier(r, payload_token, .none, .preserve_when_shadowing); // identifier |
| 395 | try renderToken(r, payload_token + 1, .space); // | | 399 | try renderToken(r, payload_token + 1, .space); // | |
| ... | @@ -397,84 +401,76 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -397,84 +401,76 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 397 | return renderExpression(r, expr, space); | 401 | return renderExpression(r, expr, space); |
| 398 | }, | 402 | }, |
| 399 | 403 | ||
| 400 | .@"defer" => { | 404 | .@"defer", |
| 401 | const defer_token = main_tokens[node]; | 405 | .@"comptime", |
| 402 | const expr = datas[node].rhs; | 406 | .@"nosuspend", |
| 403 | try renderToken(r, defer_token, .space); | 407 | .@"suspend", |
| 404 | return renderExpression(r, expr, space); | 408 | => { |
| 405 | }, | 409 | const main_token = tree.nodeMainToken(node); |
| 406 | .@"comptime", .@"nosuspend" => { | 410 | const item = tree.nodeData(node).node; |
| 407 | const comptime_token = main_tokens[node]; | 411 | try renderToken(r, main_token, .space); |
| 408 | const block = datas[node].lhs; | 412 | return renderExpression(r, item, space); |
| 409 | try renderToken(r, comptime_token, .space); | ||
| 410 | return renderExpression(r, block, space); | ||
| 411 | }, | ||
| 412 | |||
| 413 | .@"suspend" => { | ||
| 414 | const suspend_token = main_tokens[node]; | ||
| 415 | const body = datas[node].lhs; | ||
| 416 | try renderToken(r, suspend_token, .space); | ||
| 417 | return renderExpression(r, body, space); | ||
| 418 | }, | 413 | }, |
| 419 | 414 | ||
| 420 | .@"catch" => { | 415 | .@"catch" => { |
| 421 | const main_token = main_tokens[node]; | 416 | const main_token = tree.nodeMainToken(node); |
| 422 | const fallback_first = tree.firstToken(datas[node].rhs); | 417 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 418 | const fallback_first = tree.firstToken(rhs); | ||
| 423 | 419 | ||
| 424 | const same_line = tree.tokensOnSameLine(main_token, fallback_first); | 420 | const same_line = tree.tokensOnSameLine(main_token, fallback_first); |
| 425 | const after_op_space = if (same_line) Space.space else Space.newline; | 421 | const after_op_space = if (same_line) Space.space else Space.newline; |
| 426 | 422 | ||
| 427 | try renderExpression(r, datas[node].lhs, .space); // target | 423 | try renderExpression(r, lhs, .space); // target |
| 428 | 424 | ||
| 429 | try ais.pushIndent(.normal); | 425 | try ais.pushIndent(.normal); |
| 430 | if (token_tags[fallback_first - 1] == .pipe) { | 426 | if (tree.tokenTag(fallback_first - 1) == .pipe) { |
| 431 | try renderToken(r, main_token, .space); // catch keyword | 427 | try renderToken(r, main_token, .space); // catch keyword |
| 432 | try renderToken(r, main_token + 1, .none); // pipe | 428 | try renderToken(r, main_token + 1, .none); // pipe |
| 433 | try renderIdentifier(r, main_token + 2, .none, .preserve_when_shadowing); // payload identifier | 429 | try renderIdentifier(r, main_token + 2, .none, .preserve_when_shadowing); // payload identifier |
| 434 | try renderToken(r, main_token + 3, after_op_space); // pipe | 430 | try renderToken(r, main_token + 3, after_op_space); // pipe |
| 435 | } else { | 431 | } else { |
| 436 | assert(token_tags[fallback_first - 1] == .keyword_catch); | 432 | assert(tree.tokenTag(fallback_first - 1) == .keyword_catch); |
| 437 | try renderToken(r, main_token, after_op_space); // catch keyword | 433 | try renderToken(r, main_token, after_op_space); // catch keyword |
| 438 | } | 434 | } |
| 439 | try renderExpression(r, datas[node].rhs, space); // fallback | 435 | try renderExpression(r, rhs, space); // fallback |
| 440 | ais.popIndent(); | 436 | ais.popIndent(); |
| 441 | }, | 437 | }, |
| 442 | 438 | ||
| 443 | .field_access => { | 439 | .field_access => { |
| 444 | const main_token = main_tokens[node]; | 440 | const lhs, const name_token = tree.nodeData(node).node_and_token; |
| 445 | const field_access = datas[node]; | 441 | const dot_token = name_token - 1; |
| 446 | 442 | ||
| 447 | try ais.pushIndent(.field_access); | 443 | try ais.pushIndent(.field_access); |
| 448 | try renderExpression(r, field_access.lhs, .none); | 444 | try renderExpression(r, lhs, .none); |
| 449 | 445 | ||
| 450 | // Allow a line break between the lhs and the dot if the lhs and rhs | 446 | // Allow a line break between the lhs and the dot if the lhs and rhs |
| 451 | // are on different lines. | 447 | // are on different lines. |
| 452 | const lhs_last_token = tree.lastToken(field_access.lhs); | 448 | const lhs_last_token = tree.lastToken(lhs); |
| 453 | const same_line = tree.tokensOnSameLine(lhs_last_token, main_token + 1); | 449 | const same_line = tree.tokensOnSameLine(lhs_last_token, name_token); |
| 454 | if (!same_line and !hasComment(tree, lhs_last_token, main_token)) try ais.insertNewline(); | 450 | if (!same_line and !hasComment(tree, lhs_last_token, dot_token)) try ais.insertNewline(); |
| 455 | 451 | ||
| 456 | try renderToken(r, main_token, .none); // . | 452 | try renderToken(r, dot_token, .none); |
| 457 | 453 | ||
| 458 | try renderIdentifier(r, field_access.rhs, space, .eagerly_unquote); // field | 454 | try renderIdentifier(r, name_token, space, .eagerly_unquote); // field |
| 459 | ais.popIndent(); | 455 | ais.popIndent(); |
| 460 | }, | 456 | }, |
| 461 | 457 | ||
| 462 | .error_union, | 458 | .error_union, |
| 463 | .switch_range, | 459 | .switch_range, |
| 464 | => { | 460 | => { |
| 465 | const infix = datas[node]; | 461 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 466 | try renderExpression(r, infix.lhs, .none); | 462 | try renderExpression(r, lhs, .none); |
| 467 | try renderToken(r, main_tokens[node], .none); | 463 | try renderToken(r, tree.nodeMainToken(node), .none); |
| 468 | return renderExpression(r, infix.rhs, space); | 464 | return renderExpression(r, rhs, space); |
| 469 | }, | 465 | }, |
| 470 | .for_range => { | 466 | .for_range => { |
| 471 | const infix = datas[node]; | 467 | const start, const opt_end = tree.nodeData(node).node_and_opt_node; |
| 472 | try renderExpression(r, infix.lhs, .none); | 468 | try renderExpression(r, start, .none); |
| 473 | if (infix.rhs != 0) { | 469 | if (opt_end.unwrap()) |end| { |
| 474 | try renderToken(r, main_tokens[node], .none); | 470 | try renderToken(r, tree.nodeMainToken(node), .none); |
| 475 | return renderExpression(r, infix.rhs, space); | 471 | return renderExpression(r, end, space); |
| 476 | } else { | 472 | } else { |
| 477 | return renderToken(r, main_tokens[node], space); | 473 | return renderToken(r, tree.nodeMainToken(node), space); |
| 478 | } | 474 | } |
| 479 | }, | 475 | }, |
| 480 | 476 | ||
| ... | @@ -497,16 +493,16 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -497,16 +493,16 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 497 | .assign_mul_wrap, | 493 | .assign_mul_wrap, |
| 498 | .assign_mul_sat, | 494 | .assign_mul_sat, |
| 499 | => { | 495 | => { |
| 500 | const infix = datas[node]; | 496 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 501 | try renderExpression(r, infix.lhs, .space); | 497 | try renderExpression(r, lhs, .space); |
| 502 | const op_token = main_tokens[node]; | 498 | const op_token = tree.nodeMainToken(node); |
| 503 | try ais.pushIndent(.after_equals); | 499 | try ais.pushIndent(.after_equals); |
| 504 | if (tree.tokensOnSameLine(op_token, op_token + 1)) { | 500 | if (tree.tokensOnSameLine(op_token, op_token + 1)) { |
| 505 | try renderToken(r, op_token, .space); | 501 | try renderToken(r, op_token, .space); |
| 506 | } else { | 502 | } else { |
| 507 | try renderToken(r, op_token, .newline); | 503 | try renderToken(r, op_token, .newline); |
| 508 | } | 504 | } |
| 509 | try renderExpression(r, infix.rhs, space); | 505 | try renderExpression(r, rhs, space); |
| 510 | ais.popIndent(); | 506 | ais.popIndent(); |
| 511 | }, | 507 | }, |
| 512 | 508 | ||
| ... | @@ -540,16 +536,16 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -540,16 +536,16 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 540 | .sub_sat, | 536 | .sub_sat, |
| 541 | .@"orelse", | 537 | .@"orelse", |
| 542 | => { | 538 | => { |
| 543 | const infix = datas[node]; | 539 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 544 | try renderExpression(r, infix.lhs, .space); | 540 | try renderExpression(r, lhs, .space); |
| 545 | const op_token = main_tokens[node]; | 541 | const op_token = tree.nodeMainToken(node); |
| 546 | try ais.pushIndent(.binop); | 542 | try ais.pushIndent(.binop); |
| 547 | if (tree.tokensOnSameLine(op_token, op_token + 1)) { | 543 | if (tree.tokensOnSameLine(op_token, op_token + 1)) { |
| 548 | try renderToken(r, op_token, .space); | 544 | try renderToken(r, op_token, .space); |
| 549 | } else { | 545 | } else { |
| 550 | try renderToken(r, op_token, .newline); | 546 | try renderToken(r, op_token, .newline); |
| 551 | } | 547 | } |
| 552 | try renderExpression(r, infix.rhs, space); | 548 | try renderExpression(r, rhs, space); |
| 553 | ais.popIndent(); | 549 | ais.popIndent(); |
| 554 | }, | 550 | }, |
| 555 | 551 | ||
| ... | @@ -561,7 +557,7 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -561,7 +557,7 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 561 | 557 | ||
| 562 | for (full.ast.variables, 0..) |variable_node, i| { | 558 | for (full.ast.variables, 0..) |variable_node, i| { |
| 563 | const variable_space: Space = if (i == full.ast.variables.len - 1) .space else .comma_space; | 559 | const variable_space: Space = if (i == full.ast.variables.len - 1) .space else .comma_space; |
| 564 | switch (node_tags[variable_node]) { | 560 | switch (tree.nodeTag(variable_node)) { |
| 565 | .global_var_decl, | 561 | .global_var_decl, |
| 566 | .local_var_decl, | 562 | .local_var_decl, |
| 567 | .simple_var_decl, | 563 | .simple_var_decl, |
| ... | @@ -589,16 +585,16 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -589,16 +585,16 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 589 | .optional_type, | 585 | .optional_type, |
| 590 | .address_of, | 586 | .address_of, |
| 591 | => { | 587 | => { |
| 592 | try renderToken(r, main_tokens[node], .none); | 588 | try renderToken(r, tree.nodeMainToken(node), .none); |
| 593 | return renderExpression(r, datas[node].lhs, space); | 589 | return renderExpression(r, tree.nodeData(node).node, space); |
| 594 | }, | 590 | }, |
| 595 | 591 | ||
| 596 | .@"try", | 592 | .@"try", |
| 597 | .@"resume", | 593 | .@"resume", |
| 598 | .@"await", | 594 | .@"await", |
| 599 | => { | 595 | => { |
| 600 | try renderToken(r, main_tokens[node], .space); | 596 | try renderToken(r, tree.nodeMainToken(node), .space); |
| 601 | return renderExpression(r, datas[node].lhs, space); | 597 | return renderExpression(r, tree.nodeData(node).node, space); |
| 602 | }, | 598 | }, |
| 603 | 599 | ||
| 604 | .array_type, | 600 | .array_type, |
| ... | @@ -651,68 +647,77 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -651,68 +647,77 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 651 | }, | 647 | }, |
| 652 | 648 | ||
| 653 | .array_access => { | 649 | .array_access => { |
| 654 | const suffix = datas[node]; | 650 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 655 | const lbracket = tree.firstToken(suffix.rhs) - 1; | 651 | const lbracket = tree.firstToken(rhs) - 1; |
| 656 | const rbracket = tree.lastToken(suffix.rhs) + 1; | 652 | const rbracket = tree.lastToken(rhs) + 1; |
| 657 | const one_line = tree.tokensOnSameLine(lbracket, rbracket); | 653 | const one_line = tree.tokensOnSameLine(lbracket, rbracket); |
| 658 | const inner_space = if (one_line) Space.none else Space.newline; | 654 | const inner_space = if (one_line) Space.none else Space.newline; |
| 659 | try renderExpression(r, suffix.lhs, .none); | 655 | try renderExpression(r, lhs, .none); |
| 660 | try ais.pushIndent(.normal); | 656 | try ais.pushIndent(.normal); |
| 661 | try renderToken(r, lbracket, inner_space); // [ | 657 | try renderToken(r, lbracket, inner_space); // [ |
| 662 | try renderExpression(r, suffix.rhs, inner_space); | 658 | try renderExpression(r, rhs, inner_space); |
| 663 | ais.popIndent(); | 659 | ais.popIndent(); |
| 664 | return renderToken(r, rbracket, space); // ] | 660 | return renderToken(r, rbracket, space); // ] |
| 665 | }, | 661 | }, |
| 666 | 662 | ||
| 667 | .slice_open, .slice, .slice_sentinel => return renderSlice(r, node, tree.fullSlice(node).?, space), | 663 | .slice_open, |
| 664 | .slice, | ||
| 665 | .slice_sentinel, | ||
| 666 | => return renderSlice(r, node, tree.fullSlice(node).?, space), | ||
| 668 | 667 | ||
| 669 | .deref => { | 668 | .deref => { |
| 670 | try renderExpression(r, datas[node].lhs, .none); | 669 | try renderExpression(r, tree.nodeData(node).node, .none); |
| 671 | return renderToken(r, main_tokens[node], space); | 670 | return renderToken(r, tree.nodeMainToken(node), space); |
| 672 | }, | 671 | }, |
| 673 | 672 | ||
| 674 | .unwrap_optional => { | 673 | .unwrap_optional => { |
| 675 | try renderExpression(r, datas[node].lhs, .none); | 674 | const lhs, const question_mark = tree.nodeData(node).node_and_token; |
| 676 | try renderToken(r, main_tokens[node], .none); | 675 | const dot_token = question_mark - 1; |
| 677 | return renderToken(r, datas[node].rhs, space); | 676 | try renderExpression(r, lhs, .none); |
| 677 | try renderToken(r, dot_token, .none); | ||
| 678 | return renderToken(r, question_mark, space); | ||
| 678 | }, | 679 | }, |
| 679 | 680 | ||
| 680 | .@"break", .@"continue" => { | 681 | .@"break", .@"continue" => { |
| 681 | const main_token = main_tokens[node]; | 682 | const main_token = tree.nodeMainToken(node); |
| 682 | const label_token = datas[node].lhs; | 683 | const opt_label_token, const opt_target = tree.nodeData(node).opt_token_and_opt_node; |
| 683 | const target = datas[node].rhs; | 684 | if (opt_label_token == .none and opt_target == .none) { |
| 684 | if (label_token == 0 and target == 0) { | ||
| 685 | try renderToken(r, main_token, space); // break/continue | 685 | try renderToken(r, main_token, space); // break/continue |
| 686 | } else if (label_token == 0 and target != 0) { | 686 | } else if (opt_label_token == .none and opt_target != .none) { |
| 687 | const target = opt_target.unwrap().?; | ||
| 687 | try renderToken(r, main_token, .space); // break/continue | 688 | try renderToken(r, main_token, .space); // break/continue |
| 688 | try renderExpression(r, target, space); | 689 | try renderExpression(r, target, space); |
| 689 | } else if (label_token != 0 and target == 0) { | 690 | } else if (opt_label_token != .none and opt_target == .none) { |
| 691 | const label_token = opt_label_token.unwrap().?; | ||
| 690 | try renderToken(r, main_token, .space); // break/continue | 692 | try renderToken(r, main_token, .space); // break/continue |
| 691 | try renderToken(r, label_token - 1, .none); // : | 693 | try renderToken(r, label_token - 1, .none); // : |
| 692 | try renderIdentifier(r, label_token, space, .eagerly_unquote); // identifier | 694 | try renderIdentifier(r, label_token, space, .eagerly_unquote); // identifier |
| 693 | } else if (label_token != 0 and target != 0) { | 695 | } else if (opt_label_token != .none and opt_target != .none) { |
| 696 | const label_token = opt_label_token.unwrap().?; | ||
| 697 | const target = opt_target.unwrap().?; | ||
| 694 | try renderToken(r, main_token, .space); // break/continue | 698 | try renderToken(r, main_token, .space); // break/continue |
| 695 | try renderToken(r, label_token - 1, .none); // : | 699 | try renderToken(r, label_token - 1, .none); // : |
| 696 | try renderIdentifier(r, label_token, .space, .eagerly_unquote); // identifier | 700 | try renderIdentifier(r, label_token, .space, .eagerly_unquote); // identifier |
| 697 | try renderExpression(r, target, space); | 701 | try renderExpression(r, target, space); |
| 698 | } | 702 | } else unreachable; |
| 699 | }, | 703 | }, |
| 700 | 704 | ||
| 701 | .@"return" => { | 705 | .@"return" => { |
| 702 | if (datas[node].lhs != 0) { | 706 | if (tree.nodeData(node).opt_node.unwrap()) |expr| { |
| 703 | try renderToken(r, main_tokens[node], .space); | 707 | try renderToken(r, tree.nodeMainToken(node), .space); |
| 704 | try renderExpression(r, datas[node].lhs, space); | 708 | try renderExpression(r, expr, space); |
| 705 | } else { | 709 | } else { |
| 706 | try renderToken(r, main_tokens[node], space); | 710 | try renderToken(r, tree.nodeMainToken(node), space); |
| 707 | } | 711 | } |
| 708 | }, | 712 | }, |
| 709 | 713 | ||
| 710 | .grouped_expression => { | 714 | .grouped_expression => { |
| 715 | const expr, const rparen = tree.nodeData(node).node_and_token; | ||
| 711 | try ais.pushIndent(.normal); | 716 | try ais.pushIndent(.normal); |
| 712 | try renderToken(r, main_tokens[node], .none); // lparen | 717 | try renderToken(r, tree.nodeMainToken(node), .none); // lparen |
| 713 | try renderExpression(r, datas[node].lhs, .none); | 718 | try renderExpression(r, expr, .none); |
| 714 | ais.popIndent(); | 719 | ais.popIndent(); |
| 715 | return renderToken(r, datas[node].rhs, space); // rparen | 720 | return renderToken(r, rparen, space); |
| 716 | }, | 721 | }, |
| 717 | 722 | ||
| 718 | .container_decl, | 723 | .container_decl, |
| ... | @@ -733,9 +738,9 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -733,9 +738,9 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 733 | }, | 738 | }, |
| 734 | 739 | ||
| 735 | .error_set_decl => { | 740 | .error_set_decl => { |
| 736 | const error_token = main_tokens[node]; | 741 | const error_token = tree.nodeMainToken(node); |
| 737 | const lbrace = error_token + 1; | 742 | const lbrace = error_token + 1; |
| 738 | const rbrace = datas[node].rhs; | 743 | const rbrace = tree.nodeData(node).token; |
| 739 | 744 | ||
| 740 | try renderToken(r, error_token, .none); | 745 | try renderToken(r, error_token, .none); |
| 741 | 746 | ||
| ... | @@ -743,20 +748,20 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -743,20 +748,20 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 743 | // There is nothing between the braces so render condensed: `error{}` | 748 | // There is nothing between the braces so render condensed: `error{}` |
| 744 | try renderToken(r, lbrace, .none); | 749 | try renderToken(r, lbrace, .none); |
| 745 | return renderToken(r, rbrace, space); | 750 | return renderToken(r, rbrace, space); |
| 746 | } else if (lbrace + 2 == rbrace and token_tags[lbrace + 1] == .identifier) { | 751 | } else if (lbrace + 2 == rbrace and tree.tokenTag(lbrace + 1) == .identifier) { |
| 747 | // There is exactly one member and no trailing comma or | 752 | // There is exactly one member and no trailing comma or |
| 748 | // comments, so render without surrounding spaces: `error{Foo}` | 753 | // comments, so render without surrounding spaces: `error{Foo}` |
| 749 | try renderToken(r, lbrace, .none); | 754 | try renderToken(r, lbrace, .none); |
| 750 | try renderIdentifier(r, lbrace + 1, .none, .eagerly_unquote); // identifier | 755 | try renderIdentifier(r, lbrace + 1, .none, .eagerly_unquote); // identifier |
| 751 | return renderToken(r, rbrace, space); | 756 | return renderToken(r, rbrace, space); |
| 752 | } else if (token_tags[rbrace - 1] == .comma) { | 757 | } else if (tree.tokenTag(rbrace - 1) == .comma) { |
| 753 | // There is a trailing comma so render each member on a new line. | 758 | // There is a trailing comma so render each member on a new line. |
| 754 | try ais.pushIndent(.normal); | 759 | try ais.pushIndent(.normal); |
| 755 | try renderToken(r, lbrace, .newline); | 760 | try renderToken(r, lbrace, .newline); |
| 756 | var i = lbrace + 1; | 761 | var i = lbrace + 1; |
| 757 | while (i < rbrace) : (i += 1) { | 762 | while (i < rbrace) : (i += 1) { |
| 758 | if (i > lbrace + 1) try renderExtraNewlineToken(r, i); | 763 | if (i > lbrace + 1) try renderExtraNewlineToken(r, i); |
| 759 | switch (token_tags[i]) { | 764 | switch (tree.tokenTag(i)) { |
| 760 | .doc_comment => try renderToken(r, i, .newline), | 765 | .doc_comment => try renderToken(r, i, .newline), |
| 761 | .identifier => { | 766 | .identifier => { |
| 762 | try ais.pushSpace(.comma); | 767 | try ais.pushSpace(.comma); |
| ... | @@ -774,7 +779,7 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -774,7 +779,7 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 774 | try renderToken(r, lbrace, .space); | 779 | try renderToken(r, lbrace, .space); |
| 775 | var i = lbrace + 1; | 780 | var i = lbrace + 1; |
| 776 | while (i < rbrace) : (i += 1) { | 781 | while (i < rbrace) : (i += 1) { |
| 777 | switch (token_tags[i]) { | 782 | switch (tree.tokenTag(i)) { |
| 778 | .doc_comment => unreachable, // TODO | 783 | .doc_comment => unreachable, // TODO |
| 779 | .identifier => try renderIdentifier(r, i, .comma_space, .eagerly_unquote), | 784 | .identifier => try renderIdentifier(r, i, .comma_space, .eagerly_unquote), |
| 780 | .comma => {}, | 785 | .comma => {}, |
| ... | @@ -792,7 +797,7 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -792,7 +797,7 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 792 | => { | 797 | => { |
| 793 | var buf: [2]Ast.Node.Index = undefined; | 798 | var buf: [2]Ast.Node.Index = undefined; |
| 794 | const params = tree.builtinCallParams(&buf, node).?; | 799 | const params = tree.builtinCallParams(&buf, node).?; |
| 795 | return renderBuiltinCall(r, main_tokens[node], params, space); | 800 | return renderBuiltinCall(r, tree.nodeMainToken(node), params, space); |
| 796 | }, | 801 | }, |
| 797 | 802 | ||
| 798 | .fn_proto_simple, | 803 | .fn_proto_simple, |
| ... | @@ -805,14 +810,10 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -805,14 +810,10 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 805 | }, | 810 | }, |
| 806 | 811 | ||
| 807 | .anyframe_type => { | 812 | .anyframe_type => { |
| 808 | const main_token = main_tokens[node]; | 813 | const main_token = tree.nodeMainToken(node); |
| 809 | if (datas[node].rhs != 0) { | 814 | try renderToken(r, main_token, .none); // anyframe |
| 810 | try renderToken(r, main_token, .none); // anyframe | 815 | try renderToken(r, main_token + 1, .none); // -> |
| 811 | try renderToken(r, main_token + 1, .none); // -> | 816 | return renderExpression(r, tree.nodeData(node).token_and_node[1], space); |
| 812 | return renderExpression(r, datas[node].rhs, space); | ||
| 813 | } else { | ||
| 814 | return renderToken(r, main_token, space); // anyframe | ||
| 815 | } | ||
| 816 | }, | 817 | }, |
| 817 | 818 | ||
| 818 | .@"switch", | 819 | .@"switch", |
| ... | @@ -869,8 +870,8 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -869,8 +870,8 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 869 | => return renderAsm(r, tree.fullAsm(node).?, space), | 870 | => return renderAsm(r, tree.fullAsm(node).?, space), |
| 870 | 871 | ||
| 871 | .enum_literal => { | 872 | .enum_literal => { |
| 872 | try renderToken(r, main_tokens[node] - 1, .none); // . | 873 | try renderToken(r, tree.nodeMainToken(node) - 1, .none); // . |
| 873 | return renderIdentifier(r, main_tokens[node], space, .eagerly_unquote); // name | 874 | return renderIdentifier(r, tree.nodeMainToken(node), space, .eagerly_unquote); // name |
| 874 | }, | 875 | }, |
| 875 | 876 | ||
| 876 | .fn_decl => unreachable, | 877 | .fn_decl => unreachable, |
| ... | @@ -912,9 +913,9 @@ fn renderArrayType( | ... | @@ -912,9 +913,9 @@ fn renderArrayType( |
| 912 | try ais.pushIndent(.normal); | 913 | try ais.pushIndent(.normal); |
| 913 | try renderToken(r, array_type.ast.lbracket, inner_space); // lbracket | 914 | try renderToken(r, array_type.ast.lbracket, inner_space); // lbracket |
| 914 | try renderExpression(r, array_type.ast.elem_count, inner_space); | 915 | try renderExpression(r, array_type.ast.elem_count, inner_space); |
| 915 | if (array_type.ast.sentinel != 0) { | 916 | if (array_type.ast.sentinel.unwrap()) |sentinel| { |
| 916 | try renderToken(r, tree.firstToken(array_type.ast.sentinel) - 1, inner_space); // colon | 917 | try renderToken(r, tree.firstToken(sentinel) - 1, inner_space); // colon |
| 917 | try renderExpression(r, array_type.ast.sentinel, inner_space); | 918 | try renderExpression(r, sentinel, inner_space); |
| 918 | } | 919 | } |
| 919 | ais.popIndent(); | 920 | ais.popIndent(); |
| 920 | try renderToken(r, rbracket, .none); // rbracket | 921 | try renderToken(r, rbracket, .none); // rbracket |
| ... | @@ -923,6 +924,7 @@ fn renderArrayType( | ... | @@ -923,6 +924,7 @@ fn renderArrayType( |
| 923 | 924 | ||
| 924 | fn renderPtrType(r: *Render, ptr_type: Ast.full.PtrType, space: Space) Error!void { | 925 | fn renderPtrType(r: *Render, ptr_type: Ast.full.PtrType, space: Space) Error!void { |
| 925 | const tree = r.tree; | 926 | const tree = r.tree; |
| 927 | const main_token = ptr_type.ast.main_token; | ||
| 926 | switch (ptr_type.size) { | 928 | switch (ptr_type.size) { |
| 927 | .one => { | 929 | .one => { |
| 928 | // Since ** tokens exist and the same token is shared by two | 930 | // Since ** tokens exist and the same token is shared by two |
| ... | @@ -930,41 +932,41 @@ fn renderPtrType(r: *Render, ptr_type: Ast.full.PtrType, space: Space) Error!voi | ... | @@ -930,41 +932,41 @@ fn renderPtrType(r: *Render, ptr_type: Ast.full.PtrType, space: Space) Error!voi |
| 930 | // in such a relationship. If so, skip rendering anything for | 932 | // in such a relationship. If so, skip rendering anything for |
| 931 | // this pointer type and rely on the child to render our asterisk | 933 | // this pointer type and rely on the child to render our asterisk |
| 932 | // as well when it renders the ** token. | 934 | // as well when it renders the ** token. |
| 933 | if (tree.tokens.items(.tag)[ptr_type.ast.main_token] == .asterisk_asterisk and | 935 | if (tree.tokenTag(main_token) == .asterisk_asterisk and |
| 934 | ptr_type.ast.main_token == tree.nodes.items(.main_token)[ptr_type.ast.child_type]) | 936 | main_token == tree.nodeMainToken(ptr_type.ast.child_type)) |
| 935 | { | 937 | { |
| 936 | return renderExpression(r, ptr_type.ast.child_type, space); | 938 | return renderExpression(r, ptr_type.ast.child_type, space); |
| 937 | } | 939 | } |
| 938 | try renderToken(r, ptr_type.ast.main_token, .none); // asterisk | 940 | try renderToken(r, main_token, .none); // asterisk |
| 939 | }, | 941 | }, |
| 940 | .many => { | 942 | .many => { |
| 941 | if (ptr_type.ast.sentinel == 0) { | 943 | if (ptr_type.ast.sentinel.unwrap()) |sentinel| { |
| 942 | try renderToken(r, ptr_type.ast.main_token, .none); // lbracket | 944 | try renderToken(r, main_token, .none); // lbracket |
| 943 | try renderToken(r, ptr_type.ast.main_token + 1, .none); // asterisk | 945 | try renderToken(r, main_token + 1, .none); // asterisk |
| 944 | try renderToken(r, ptr_type.ast.main_token + 2, .none); // rbracket | 946 | try renderToken(r, main_token + 2, .none); // colon |
| 947 | try renderExpression(r, sentinel, .none); | ||
| 948 | try renderToken(r, tree.lastToken(sentinel) + 1, .none); // rbracket | ||
| 945 | } else { | 949 | } else { |
| 946 | try renderToken(r, ptr_type.ast.main_token, .none); // lbracket | 950 | try renderToken(r, main_token, .none); // lbracket |
| 947 | try renderToken(r, ptr_type.ast.main_token + 1, .none); // asterisk | 951 | try renderToken(r, main_token + 1, .none); // asterisk |
| 948 | try renderToken(r, ptr_type.ast.main_token + 2, .none); // colon | 952 | try renderToken(r, main_token + 2, .none); // rbracket |
| 949 | try renderExpression(r, ptr_type.ast.sentinel, .none); | ||
| 950 | try renderToken(r, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket | ||
| 951 | } | 953 | } |
| 952 | }, | 954 | }, |
| 953 | .c => { | 955 | .c => { |
| 954 | try renderToken(r, ptr_type.ast.main_token, .none); // lbracket | 956 | try renderToken(r, main_token, .none); // lbracket |
| 955 | try renderToken(r, ptr_type.ast.main_token + 1, .none); // asterisk | 957 | try renderToken(r, main_token + 1, .none); // asterisk |
| 956 | try renderToken(r, ptr_type.ast.main_token + 2, .none); // c | 958 | try renderToken(r, main_token + 2, .none); // c |
| 957 | try renderToken(r, ptr_type.ast.main_token + 3, .none); // rbracket | 959 | try renderToken(r, main_token + 3, .none); // rbracket |
| 958 | }, | 960 | }, |
| 959 | .slice => { | 961 | .slice => { |
| 960 | if (ptr_type.ast.sentinel == 0) { | 962 | if (ptr_type.ast.sentinel.unwrap()) |sentinel| { |
| 961 | try renderToken(r, ptr_type.ast.main_token, .none); // lbracket | 963 | try renderToken(r, main_token, .none); // lbracket |
| 962 | try renderToken(r, ptr_type.ast.main_token + 1, .none); // rbracket | 964 | try renderToken(r, main_token + 1, .none); // colon |
| 965 | try renderExpression(r, sentinel, .none); | ||
| 966 | try renderToken(r, tree.lastToken(sentinel) + 1, .none); // rbracket | ||
| 963 | } else { | 967 | } else { |
| 964 | try renderToken(r, ptr_type.ast.main_token, .none); // lbracket | 968 | try renderToken(r, main_token, .none); // lbracket |
| 965 | try renderToken(r, ptr_type.ast.main_token + 1, .none); // colon | 969 | try renderToken(r, main_token + 1, .none); // rbracket |
| 966 | try renderExpression(r, ptr_type.ast.sentinel, .none); | ||
| 967 | try renderToken(r, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket | ||
| 968 | } | 970 | } |
| 969 | }, | 971 | }, |
| 970 | } | 972 | } |
| ... | @@ -973,29 +975,29 @@ fn renderPtrType(r: *Render, ptr_type: Ast.full.PtrType, space: Space) Error!voi | ... | @@ -973,29 +975,29 @@ fn renderPtrType(r: *Render, ptr_type: Ast.full.PtrType, space: Space) Error!voi |
| 973 | try renderToken(r, allowzero_token, .space); | 975 | try renderToken(r, allowzero_token, .space); |
| 974 | } | 976 | } |
| 975 | 977 | ||
| 976 | if (ptr_type.ast.align_node != 0) { | 978 | if (ptr_type.ast.align_node.unwrap()) |align_node| { |
| 977 | const align_first = tree.firstToken(ptr_type.ast.align_node); | 979 | const align_first = tree.firstToken(align_node); |
| 978 | try renderToken(r, align_first - 2, .none); // align | 980 | try renderToken(r, align_first - 2, .none); // align |
| 979 | try renderToken(r, align_first - 1, .none); // lparen | 981 | try renderToken(r, align_first - 1, .none); // lparen |
| 980 | try renderExpression(r, ptr_type.ast.align_node, .none); | 982 | try renderExpression(r, align_node, .none); |
| 981 | if (ptr_type.ast.bit_range_start != 0) { | 983 | if (ptr_type.ast.bit_range_start.unwrap()) |bit_range_start| { |
| 982 | assert(ptr_type.ast.bit_range_end != 0); | 984 | const bit_range_end = ptr_type.ast.bit_range_end.unwrap().?; |
| 983 | try renderToken(r, tree.firstToken(ptr_type.ast.bit_range_start) - 1, .none); // colon | 985 | try renderToken(r, tree.firstToken(bit_range_start) - 1, .none); // colon |
| 984 | try renderExpression(r, ptr_type.ast.bit_range_start, .none); | 986 | try renderExpression(r, bit_range_start, .none); |
| 985 | try renderToken(r, tree.firstToken(ptr_type.ast.bit_range_end) - 1, .none); // colon | 987 | try renderToken(r, tree.firstToken(bit_range_end) - 1, .none); // colon |
| 986 | try renderExpression(r, ptr_type.ast.bit_range_end, .none); | 988 | try renderExpression(r, bit_range_end, .none); |
| 987 | try renderToken(r, tree.lastToken(ptr_type.ast.bit_range_end) + 1, .space); // rparen | 989 | try renderToken(r, tree.lastToken(bit_range_end) + 1, .space); // rparen |
| 988 | } else { | 990 | } else { |
| 989 | try renderToken(r, tree.lastToken(ptr_type.ast.align_node) + 1, .space); // rparen | 991 | try renderToken(r, tree.lastToken(align_node) + 1, .space); // rparen |
| 990 | } | 992 | } |
| 991 | } | 993 | } |
| 992 | 994 | ||
| 993 | if (ptr_type.ast.addrspace_node != 0) { | 995 | if (ptr_type.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 994 | const addrspace_first = tree.firstToken(ptr_type.ast.addrspace_node); | 996 | const addrspace_first = tree.firstToken(addrspace_node); |
| 995 | try renderToken(r, addrspace_first - 2, .none); // addrspace | 997 | try renderToken(r, addrspace_first - 2, .none); // addrspace |
| 996 | try renderToken(r, addrspace_first - 1, .none); // lparen | 998 | try renderToken(r, addrspace_first - 1, .none); // lparen |
| 997 | try renderExpression(r, ptr_type.ast.addrspace_node, .none); | 999 | try renderExpression(r, addrspace_node, .none); |
| 998 | try renderToken(r, tree.lastToken(ptr_type.ast.addrspace_node) + 1, .space); // rparen | 1000 | try renderToken(r, tree.lastToken(addrspace_node) + 1, .space); // rparen |
| 999 | } | 1001 | } |
| 1000 | 1002 | ||
| 1001 | if (ptr_type.const_token) |const_token| { | 1003 | if (ptr_type.const_token) |const_token| { |
| ... | @@ -1016,13 +1018,12 @@ fn renderSlice( | ... | @@ -1016,13 +1018,12 @@ fn renderSlice( |
| 1016 | space: Space, | 1018 | space: Space, |
| 1017 | ) Error!void { | 1019 | ) Error!void { |
| 1018 | const tree = r.tree; | 1020 | const tree = r.tree; |
| 1019 | const node_tags = tree.nodes.items(.tag); | 1021 | const after_start_space_bool = nodeCausesSliceOpSpace(tree.nodeTag(slice.ast.start)) or |
| 1020 | const after_start_space_bool = nodeCausesSliceOpSpace(node_tags[slice.ast.start]) or | 1022 | if (slice.ast.end.unwrap()) |end| nodeCausesSliceOpSpace(tree.nodeTag(end)) else false; |
| 1021 | if (slice.ast.end != 0) nodeCausesSliceOpSpace(node_tags[slice.ast.end]) else false; | ||
| 1022 | const after_start_space = if (after_start_space_bool) Space.space else Space.none; | 1023 | const after_start_space = if (after_start_space_bool) Space.space else Space.none; |
| 1023 | const after_dots_space = if (slice.ast.end != 0) | 1024 | const after_dots_space = if (slice.ast.end != .none) |
| 1024 | after_start_space | 1025 | after_start_space |
| 1025 | else if (slice.ast.sentinel != 0) Space.space else Space.none; | 1026 | else if (slice.ast.sentinel != .none) Space.space else Space.none; |
| 1026 | 1027 | ||
| 1027 | try renderExpression(r, slice.ast.sliced, .none); | 1028 | try renderExpression(r, slice.ast.sliced, .none); |
| 1028 | try renderToken(r, slice.ast.lbracket, .none); // lbracket | 1029 | try renderToken(r, slice.ast.lbracket, .none); // lbracket |
| ... | @@ -1031,14 +1032,14 @@ fn renderSlice( | ... | @@ -1031,14 +1032,14 @@ fn renderSlice( |
| 1031 | try renderExpression(r, slice.ast.start, after_start_space); | 1032 | try renderExpression(r, slice.ast.start, after_start_space); |
| 1032 | try renderToken(r, start_last + 1, after_dots_space); // ellipsis2 ("..") | 1033 | try renderToken(r, start_last + 1, after_dots_space); // ellipsis2 ("..") |
| 1033 | 1034 | ||
| 1034 | if (slice.ast.end != 0) { | 1035 | if (slice.ast.end.unwrap()) |end| { |
| 1035 | const after_end_space = if (slice.ast.sentinel != 0) Space.space else Space.none; | 1036 | const after_end_space = if (slice.ast.sentinel != .none) Space.space else Space.none; |
| 1036 | try renderExpression(r, slice.ast.end, after_end_space); | 1037 | try renderExpression(r, end, after_end_space); |
| 1037 | } | 1038 | } |
| 1038 | 1039 | ||
| 1039 | if (slice.ast.sentinel != 0) { | 1040 | if (slice.ast.sentinel.unwrap()) |sentinel| { |
| 1040 | try renderToken(r, tree.firstToken(slice.ast.sentinel) - 1, .none); // colon | 1041 | try renderToken(r, tree.firstToken(sentinel) - 1, .none); // colon |
| 1041 | try renderExpression(r, slice.ast.sentinel, .none); | 1042 | try renderExpression(r, sentinel, .none); |
| 1042 | } | 1043 | } |
| 1043 | 1044 | ||
| 1044 | try renderToken(r, tree.lastToken(slice_node), space); // rbracket | 1045 | try renderToken(r, tree.lastToken(slice_node), space); // rbracket |
| ... | @@ -1050,12 +1051,8 @@ fn renderAsmOutput( | ... | @@ -1050,12 +1051,8 @@ fn renderAsmOutput( |
| 1050 | space: Space, | 1051 | space: Space, |
| 1051 | ) Error!void { | 1052 | ) Error!void { |
| 1052 | const tree = r.tree; | 1053 | const tree = r.tree; |
| 1053 | const token_tags = tree.tokens.items(.tag); | 1054 | assert(tree.nodeTag(asm_output) == .asm_output); |
| 1054 | const node_tags = tree.nodes.items(.tag); | 1055 | const symbolic_name = tree.nodeMainToken(asm_output); |
| 1055 | const main_tokens = tree.nodes.items(.main_token); | ||
| 1056 | const datas = tree.nodes.items(.data); | ||
| 1057 | assert(node_tags[asm_output] == .asm_output); | ||
| 1058 | const symbolic_name = main_tokens[asm_output]; | ||
| 1059 | 1056 | ||
| 1060 | try renderToken(r, symbolic_name - 1, .none); // lbracket | 1057 | try renderToken(r, symbolic_name - 1, .none); // lbracket |
| 1061 | try renderIdentifier(r, symbolic_name, .none, .eagerly_unquote); // ident | 1058 | try renderIdentifier(r, symbolic_name, .none, .eagerly_unquote); // ident |
| ... | @@ -1063,10 +1060,11 @@ fn renderAsmOutput( | ... | @@ -1063,10 +1060,11 @@ fn renderAsmOutput( |
| 1063 | try renderToken(r, symbolic_name + 2, .space); // "constraint" | 1060 | try renderToken(r, symbolic_name + 2, .space); // "constraint" |
| 1064 | try renderToken(r, symbolic_name + 3, .none); // lparen | 1061 | try renderToken(r, symbolic_name + 3, .none); // lparen |
| 1065 | 1062 | ||
| 1066 | if (token_tags[symbolic_name + 4] == .arrow) { | 1063 | if (tree.tokenTag(symbolic_name + 4) == .arrow) { |
| 1064 | const type_expr, const rparen = tree.nodeData(asm_output).opt_node_and_token; | ||
| 1067 | try renderToken(r, symbolic_name + 4, .space); // -> | 1065 | try renderToken(r, symbolic_name + 4, .space); // -> |
| 1068 | try renderExpression(r, datas[asm_output].lhs, Space.none); | 1066 | try renderExpression(r, type_expr.unwrap().?, Space.none); |
| 1069 | return renderToken(r, datas[asm_output].rhs, space); // rparen | 1067 | return renderToken(r, rparen, space); |
| 1070 | } else { | 1068 | } else { |
| 1071 | try renderIdentifier(r, symbolic_name + 4, .none, .eagerly_unquote); // ident | 1069 | try renderIdentifier(r, symbolic_name + 4, .none, .eagerly_unquote); // ident |
| 1072 | return renderToken(r, symbolic_name + 5, space); // rparen | 1070 | return renderToken(r, symbolic_name + 5, space); // rparen |
| ... | @@ -1079,19 +1077,17 @@ fn renderAsmInput( | ... | @@ -1079,19 +1077,17 @@ fn renderAsmInput( |
| 1079 | space: Space, | 1077 | space: Space, |
| 1080 | ) Error!void { | 1078 | ) Error!void { |
| 1081 | const tree = r.tree; | 1079 | const tree = r.tree; |
| 1082 | const node_tags = tree.nodes.items(.tag); | 1080 | assert(tree.nodeTag(asm_input) == .asm_input); |
| 1083 | const main_tokens = tree.nodes.items(.main_token); | 1081 | const symbolic_name = tree.nodeMainToken(asm_input); |
| 1084 | const datas = tree.nodes.items(.data); | 1082 | const expr, const rparen = tree.nodeData(asm_input).node_and_token; |
| 1085 | assert(node_tags[asm_input] == .asm_input); | ||
| 1086 | const symbolic_name = main_tokens[asm_input]; | ||
| 1087 | 1083 | ||
| 1088 | try renderToken(r, symbolic_name - 1, .none); // lbracket | 1084 | try renderToken(r, symbolic_name - 1, .none); // lbracket |
| 1089 | try renderIdentifier(r, symbolic_name, .none, .eagerly_unquote); // ident | 1085 | try renderIdentifier(r, symbolic_name, .none, .eagerly_unquote); // ident |
| 1090 | try renderToken(r, symbolic_name + 1, .space); // rbracket | 1086 | try renderToken(r, symbolic_name + 1, .space); // rbracket |
| 1091 | try renderToken(r, symbolic_name + 2, .space); // "constraint" | 1087 | try renderToken(r, symbolic_name + 2, .space); // "constraint" |
| 1092 | try renderToken(r, symbolic_name + 3, .none); // lparen | 1088 | try renderToken(r, symbolic_name + 3, .none); // lparen |
| 1093 | try renderExpression(r, datas[asm_input].lhs, Space.none); | 1089 | try renderExpression(r, expr, Space.none); |
| 1094 | return renderToken(r, datas[asm_input].rhs, space); // rparen | 1090 | return renderToken(r, rparen, space); |
| 1095 | } | 1091 | } |
| 1096 | 1092 | ||
| 1097 | fn renderVarDecl( | 1093 | fn renderVarDecl( |
| ... | @@ -1147,15 +1143,15 @@ fn renderVarDeclWithoutFixups( | ... | @@ -1147,15 +1143,15 @@ fn renderVarDeclWithoutFixups( |
| 1147 | 1143 | ||
| 1148 | try renderToken(r, var_decl.ast.mut_token, .space); // var | 1144 | try renderToken(r, var_decl.ast.mut_token, .space); // var |
| 1149 | 1145 | ||
| 1150 | if (var_decl.ast.type_node != 0 or var_decl.ast.align_node != 0 or | 1146 | if (var_decl.ast.type_node != .none or var_decl.ast.align_node != .none or |
| 1151 | var_decl.ast.addrspace_node != 0 or var_decl.ast.section_node != 0 or | 1147 | var_decl.ast.addrspace_node != .none or var_decl.ast.section_node != .none or |
| 1152 | var_decl.ast.init_node != 0) | 1148 | var_decl.ast.init_node != .none) |
| 1153 | { | 1149 | { |
| 1154 | const name_space = if (var_decl.ast.type_node == 0 and | 1150 | const name_space = if (var_decl.ast.type_node == .none and |
| 1155 | (var_decl.ast.align_node != 0 or | 1151 | (var_decl.ast.align_node != .none or |
| 1156 | var_decl.ast.addrspace_node != 0 or | 1152 | var_decl.ast.addrspace_node != .none or |
| 1157 | var_decl.ast.section_node != 0 or | 1153 | var_decl.ast.section_node != .none or |
| 1158 | var_decl.ast.init_node != 0)) | 1154 | var_decl.ast.init_node != .none)) |
| 1159 | Space.space | 1155 | Space.space |
| 1160 | else | 1156 | else |
| 1161 | Space.none; | 1157 | Space.none; |
| ... | @@ -1165,26 +1161,26 @@ fn renderVarDeclWithoutFixups( | ... | @@ -1165,26 +1161,26 @@ fn renderVarDeclWithoutFixups( |
| 1165 | return renderIdentifier(r, var_decl.ast.mut_token + 1, space, .preserve_when_shadowing); // name | 1161 | return renderIdentifier(r, var_decl.ast.mut_token + 1, space, .preserve_when_shadowing); // name |
| 1166 | } | 1162 | } |
| 1167 | 1163 | ||
| 1168 | if (var_decl.ast.type_node != 0) { | 1164 | if (var_decl.ast.type_node.unwrap()) |type_node| { |
| 1169 | try renderToken(r, var_decl.ast.mut_token + 2, Space.space); // : | 1165 | try renderToken(r, var_decl.ast.mut_token + 2, Space.space); // : |
| 1170 | if (var_decl.ast.align_node != 0 or var_decl.ast.addrspace_node != 0 or | 1166 | if (var_decl.ast.align_node != .none or var_decl.ast.addrspace_node != .none or |
| 1171 | var_decl.ast.section_node != 0 or var_decl.ast.init_node != 0) | 1167 | var_decl.ast.section_node != .none or var_decl.ast.init_node != .none) |
| 1172 | { | 1168 | { |
| 1173 | try renderExpression(r, var_decl.ast.type_node, .space); | 1169 | try renderExpression(r, type_node, .space); |
| 1174 | } else { | 1170 | } else { |
| 1175 | return renderExpression(r, var_decl.ast.type_node, space); | 1171 | return renderExpression(r, type_node, space); |
| 1176 | } | 1172 | } |
| 1177 | } | 1173 | } |
| 1178 | 1174 | ||
| 1179 | if (var_decl.ast.align_node != 0) { | 1175 | if (var_decl.ast.align_node.unwrap()) |align_node| { |
| 1180 | const lparen = tree.firstToken(var_decl.ast.align_node) - 1; | 1176 | const lparen = tree.firstToken(align_node) - 1; |
| 1181 | const align_kw = lparen - 1; | 1177 | const align_kw = lparen - 1; |
| 1182 | const rparen = tree.lastToken(var_decl.ast.align_node) + 1; | 1178 | const rparen = tree.lastToken(align_node) + 1; |
| 1183 | try renderToken(r, align_kw, Space.none); // align | 1179 | try renderToken(r, align_kw, Space.none); // align |
| 1184 | try renderToken(r, lparen, Space.none); // ( | 1180 | try renderToken(r, lparen, Space.none); // ( |
| 1185 | try renderExpression(r, var_decl.ast.align_node, Space.none); | 1181 | try renderExpression(r, align_node, Space.none); |
| 1186 | if (var_decl.ast.addrspace_node != 0 or var_decl.ast.section_node != 0 or | 1182 | if (var_decl.ast.addrspace_node != .none or var_decl.ast.section_node != .none or |
| 1187 | var_decl.ast.init_node != 0) | 1183 | var_decl.ast.init_node != .none) |
| 1188 | { | 1184 | { |
| 1189 | try renderToken(r, rparen, .space); // ) | 1185 | try renderToken(r, rparen, .space); // ) |
| 1190 | } else { | 1186 | } else { |
| ... | @@ -1192,14 +1188,14 @@ fn renderVarDeclWithoutFixups( | ... | @@ -1192,14 +1188,14 @@ fn renderVarDeclWithoutFixups( |
| 1192 | } | 1188 | } |
| 1193 | } | 1189 | } |
| 1194 | 1190 | ||
| 1195 | if (var_decl.ast.addrspace_node != 0) { | 1191 | if (var_decl.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 1196 | const lparen = tree.firstToken(var_decl.ast.addrspace_node) - 1; | 1192 | const lparen = tree.firstToken(addrspace_node) - 1; |
| 1197 | const addrspace_kw = lparen - 1; | 1193 | const addrspace_kw = lparen - 1; |
| 1198 | const rparen = tree.lastToken(var_decl.ast.addrspace_node) + 1; | 1194 | const rparen = tree.lastToken(addrspace_node) + 1; |
| 1199 | try renderToken(r, addrspace_kw, Space.none); // addrspace | 1195 | try renderToken(r, addrspace_kw, Space.none); // addrspace |
| 1200 | try renderToken(r, lparen, Space.none); // ( | 1196 | try renderToken(r, lparen, Space.none); // ( |
| 1201 | try renderExpression(r, var_decl.ast.addrspace_node, Space.none); | 1197 | try renderExpression(r, addrspace_node, Space.none); |
| 1202 | if (var_decl.ast.section_node != 0 or var_decl.ast.init_node != 0) { | 1198 | if (var_decl.ast.section_node != .none or var_decl.ast.init_node != .none) { |
| 1203 | try renderToken(r, rparen, .space); // ) | 1199 | try renderToken(r, rparen, .space); // ) |
| 1204 | } else { | 1200 | } else { |
| 1205 | try renderToken(r, rparen, .none); // ) | 1201 | try renderToken(r, rparen, .none); // ) |
| ... | @@ -1207,27 +1203,27 @@ fn renderVarDeclWithoutFixups( | ... | @@ -1207,27 +1203,27 @@ fn renderVarDeclWithoutFixups( |
| 1207 | } | 1203 | } |
| 1208 | } | 1204 | } |
| 1209 | 1205 | ||
| 1210 | if (var_decl.ast.section_node != 0) { | 1206 | if (var_decl.ast.section_node.unwrap()) |section_node| { |
| 1211 | const lparen = tree.firstToken(var_decl.ast.section_node) - 1; | 1207 | const lparen = tree.firstToken(section_node) - 1; |
| 1212 | const section_kw = lparen - 1; | 1208 | const section_kw = lparen - 1; |
| 1213 | const rparen = tree.lastToken(var_decl.ast.section_node) + 1; | 1209 | const rparen = tree.lastToken(section_node) + 1; |
| 1214 | try renderToken(r, section_kw, Space.none); // linksection | 1210 | try renderToken(r, section_kw, Space.none); // linksection |
| 1215 | try renderToken(r, lparen, Space.none); // ( | 1211 | try renderToken(r, lparen, Space.none); // ( |
| 1216 | try renderExpression(r, var_decl.ast.section_node, Space.none); | 1212 | try renderExpression(r, section_node, Space.none); |
| 1217 | if (var_decl.ast.init_node != 0) { | 1213 | if (var_decl.ast.init_node != .none) { |
| 1218 | try renderToken(r, rparen, .space); // ) | 1214 | try renderToken(r, rparen, .space); // ) |
| 1219 | } else { | 1215 | } else { |
| 1220 | return renderToken(r, rparen, space); // ) | 1216 | return renderToken(r, rparen, space); // ) |
| 1221 | } | 1217 | } |
| 1222 | } | 1218 | } |
| 1223 | 1219 | ||
| 1224 | assert(var_decl.ast.init_node != 0); | 1220 | const init_node = var_decl.ast.init_node.unwrap().?; |
| 1225 | 1221 | ||
| 1226 | const eq_token = tree.firstToken(var_decl.ast.init_node) - 1; | 1222 | const eq_token = tree.firstToken(init_node) - 1; |
| 1227 | const eq_space: Space = if (tree.tokensOnSameLine(eq_token, eq_token + 1)) .space else .newline; | 1223 | const eq_space: Space = if (tree.tokensOnSameLine(eq_token, eq_token + 1)) .space else .newline; |
| 1228 | try ais.pushIndent(.after_equals); | 1224 | try ais.pushIndent(.after_equals); |
| 1229 | try renderToken(r, eq_token, eq_space); // = | 1225 | try renderToken(r, eq_token, eq_space); // = |
| 1230 | try renderExpression(r, var_decl.ast.init_node, space); // ; | 1226 | try renderExpression(r, init_node, space); // ; |
| 1231 | ais.popIndent(); | 1227 | ais.popIndent(); |
| 1232 | } | 1228 | } |
| 1233 | 1229 | ||
| ... | @@ -1236,7 +1232,7 @@ fn renderIf(r: *Render, if_node: Ast.full.If, space: Space) Error!void { | ... | @@ -1236,7 +1232,7 @@ fn renderIf(r: *Render, if_node: Ast.full.If, space: Space) Error!void { |
| 1236 | .ast = .{ | 1232 | .ast = .{ |
| 1237 | .while_token = if_node.ast.if_token, | 1233 | .while_token = if_node.ast.if_token, |
| 1238 | .cond_expr = if_node.ast.cond_expr, | 1234 | .cond_expr = if_node.ast.cond_expr, |
| 1239 | .cont_expr = 0, | 1235 | .cont_expr = .none, |
| 1240 | .then_expr = if_node.ast.then_expr, | 1236 | .then_expr = if_node.ast.then_expr, |
| 1241 | .else_expr = if_node.ast.else_expr, | 1237 | .else_expr = if_node.ast.else_expr, |
| 1242 | }, | 1238 | }, |
| ... | @@ -1252,7 +1248,6 @@ fn renderIf(r: *Render, if_node: Ast.full.If, space: Space) Error!void { | ... | @@ -1252,7 +1248,6 @@ fn renderIf(r: *Render, if_node: Ast.full.If, space: Space) Error!void { |
| 1252 | /// respective values set to null. | 1248 | /// respective values set to null. |
| 1253 | fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void { | 1249 | fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void { |
| 1254 | const tree = r.tree; | 1250 | const tree = r.tree; |
| 1255 | const token_tags = tree.tokens.items(.tag); | ||
| 1256 | 1251 | ||
| 1257 | if (while_node.label_token) |label| { | 1252 | if (while_node.label_token) |label| { |
| 1258 | try renderIdentifier(r, label, .none, .eagerly_unquote); // label | 1253 | try renderIdentifier(r, label, .none, .eagerly_unquote); // label |
| ... | @@ -1273,7 +1268,7 @@ fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void | ... | @@ -1273,7 +1268,7 @@ fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void |
| 1273 | try renderToken(r, last_prefix_token, .space); | 1268 | try renderToken(r, last_prefix_token, .space); |
| 1274 | try renderToken(r, payload_token - 1, .none); // | | 1269 | try renderToken(r, payload_token - 1, .none); // | |
| 1275 | const ident = blk: { | 1270 | const ident = blk: { |
| 1276 | if (token_tags[payload_token] == .asterisk) { | 1271 | if (tree.tokenTag(payload_token) == .asterisk) { |
| 1277 | try renderToken(r, payload_token, .none); // * | 1272 | try renderToken(r, payload_token, .none); // * |
| 1278 | break :blk payload_token + 1; | 1273 | break :blk payload_token + 1; |
| 1279 | } else { | 1274 | } else { |
| ... | @@ -1282,7 +1277,7 @@ fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void | ... | @@ -1282,7 +1277,7 @@ fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void |
| 1282 | }; | 1277 | }; |
| 1283 | try renderIdentifier(r, ident, .none, .preserve_when_shadowing); // identifier | 1278 | try renderIdentifier(r, ident, .none, .preserve_when_shadowing); // identifier |
| 1284 | const pipe = blk: { | 1279 | const pipe = blk: { |
| 1285 | if (token_tags[ident + 1] == .comma) { | 1280 | if (tree.tokenTag(ident + 1) == .comma) { |
| 1286 | try renderToken(r, ident + 1, .space); // , | 1281 | try renderToken(r, ident + 1, .space); // , |
| 1287 | try renderIdentifier(r, ident + 2, .none, .preserve_when_shadowing); // index | 1282 | try renderIdentifier(r, ident + 2, .none, .preserve_when_shadowing); // index |
| 1288 | break :blk ident + 3; | 1283 | break :blk ident + 3; |
| ... | @@ -1293,13 +1288,13 @@ fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void | ... | @@ -1293,13 +1288,13 @@ fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void |
| 1293 | last_prefix_token = pipe; | 1288 | last_prefix_token = pipe; |
| 1294 | } | 1289 | } |
| 1295 | 1290 | ||
| 1296 | if (while_node.ast.cont_expr != 0) { | 1291 | if (while_node.ast.cont_expr.unwrap()) |cont_expr| { |
| 1297 | try renderToken(r, last_prefix_token, .space); | 1292 | try renderToken(r, last_prefix_token, .space); |
| 1298 | const lparen = tree.firstToken(while_node.ast.cont_expr) - 1; | 1293 | const lparen = tree.firstToken(cont_expr) - 1; |
| 1299 | try renderToken(r, lparen - 1, .space); // : | 1294 | try renderToken(r, lparen - 1, .space); // : |
| 1300 | try renderToken(r, lparen, .none); // lparen | 1295 | try renderToken(r, lparen, .none); // lparen |
| 1301 | try renderExpression(r, while_node.ast.cont_expr, .none); | 1296 | try renderExpression(r, cont_expr, .none); |
| 1302 | last_prefix_token = tree.lastToken(while_node.ast.cont_expr) + 1; // rparen | 1297 | last_prefix_token = tree.lastToken(cont_expr) + 1; // rparen |
| 1303 | } | 1298 | } |
| 1304 | 1299 | ||
| 1305 | try renderThenElse( | 1300 | try renderThenElse( |
| ... | @@ -1317,15 +1312,14 @@ fn renderThenElse( | ... | @@ -1317,15 +1312,14 @@ fn renderThenElse( |
| 1317 | r: *Render, | 1312 | r: *Render, |
| 1318 | last_prefix_token: Ast.TokenIndex, | 1313 | last_prefix_token: Ast.TokenIndex, |
| 1319 | then_expr: Ast.Node.Index, | 1314 | then_expr: Ast.Node.Index, |
| 1320 | else_token: Ast.TokenIndex, | 1315 | else_token: ?Ast.TokenIndex, |
| 1321 | maybe_error_token: ?Ast.TokenIndex, | 1316 | maybe_error_token: ?Ast.TokenIndex, |
| 1322 | else_expr: Ast.Node.Index, | 1317 | opt_else_expr: Ast.Node.OptionalIndex, |
| 1323 | space: Space, | 1318 | space: Space, |
| 1324 | ) Error!void { | 1319 | ) Error!void { |
| 1325 | const tree = r.tree; | 1320 | const tree = r.tree; |
| 1326 | const ais = r.ais; | 1321 | const ais = r.ais; |
| 1327 | const node_tags = tree.nodes.items(.tag); | 1322 | const then_expr_is_block = nodeIsBlock(tree.nodeTag(then_expr)); |
| 1328 | const then_expr_is_block = nodeIsBlock(node_tags[then_expr]); | ||
| 1329 | const indent_then_expr = !then_expr_is_block and | 1323 | const indent_then_expr = !then_expr_is_block and |
| 1330 | !tree.tokensOnSameLine(last_prefix_token, tree.firstToken(then_expr)); | 1324 | !tree.tokensOnSameLine(last_prefix_token, tree.firstToken(then_expr)); |
| 1331 | 1325 | ||
| ... | @@ -1341,7 +1335,7 @@ fn renderThenElse( | ... | @@ -1341,7 +1335,7 @@ fn renderThenElse( |
| 1341 | try renderToken(r, last_prefix_token, .space); | 1335 | try renderToken(r, last_prefix_token, .space); |
| 1342 | } | 1336 | } |
| 1343 | 1337 | ||
| 1344 | if (else_expr != 0) { | 1338 | if (opt_else_expr.unwrap()) |else_expr| { |
| 1345 | if (indent_then_expr) { | 1339 | if (indent_then_expr) { |
| 1346 | try renderExpression(r, then_expr, .newline); | 1340 | try renderExpression(r, then_expr, .newline); |
| 1347 | } else { | 1341 | } else { |
| ... | @@ -1350,18 +1344,18 @@ fn renderThenElse( | ... | @@ -1350,18 +1344,18 @@ fn renderThenElse( |
| 1350 | 1344 | ||
| 1351 | if (indent_then_expr) ais.popIndent(); | 1345 | if (indent_then_expr) ais.popIndent(); |
| 1352 | 1346 | ||
| 1353 | var last_else_token = else_token; | 1347 | var last_else_token = else_token.?; |
| 1354 | 1348 | ||
| 1355 | if (maybe_error_token) |error_token| { | 1349 | if (maybe_error_token) |error_token| { |
| 1356 | try renderToken(r, else_token, .space); // else | 1350 | try renderToken(r, last_else_token, .space); // else |
| 1357 | try renderToken(r, error_token - 1, .none); // | | 1351 | try renderToken(r, error_token - 1, .none); // | |
| 1358 | try renderIdentifier(r, error_token, .none, .preserve_when_shadowing); // identifier | 1352 | try renderIdentifier(r, error_token, .none, .preserve_when_shadowing); // identifier |
| 1359 | last_else_token = error_token + 1; // | | 1353 | last_else_token = error_token + 1; // | |
| 1360 | } | 1354 | } |
| 1361 | 1355 | ||
| 1362 | const indent_else_expr = indent_then_expr and | 1356 | const indent_else_expr = indent_then_expr and |
| 1363 | !nodeIsBlock(node_tags[else_expr]) and | 1357 | !nodeIsBlock(tree.nodeTag(else_expr)) and |
| 1364 | !nodeIsIfForWhileSwitch(node_tags[else_expr]); | 1358 | !nodeIsIfForWhileSwitch(tree.nodeTag(else_expr)); |
| 1365 | if (indent_else_expr) { | 1359 | if (indent_else_expr) { |
| 1366 | try ais.pushIndent(.normal); | 1360 | try ais.pushIndent(.normal); |
| 1367 | try renderToken(r, last_else_token, .newline); | 1361 | try renderToken(r, last_else_token, .newline); |
| ... | @@ -1398,21 +1392,21 @@ fn renderFor(r: *Render, for_node: Ast.full.For, space: Space) Error!void { | ... | @@ -1398,21 +1392,21 @@ fn renderFor(r: *Render, for_node: Ast.full.For, space: Space) Error!void { |
| 1398 | 1392 | ||
| 1399 | var cur = for_node.payload_token; | 1393 | var cur = for_node.payload_token; |
| 1400 | const pipe = std.mem.indexOfScalarPos(std.zig.Token.Tag, token_tags, cur, .pipe).?; | 1394 | const pipe = std.mem.indexOfScalarPos(std.zig.Token.Tag, token_tags, cur, .pipe).?; |
| 1401 | if (token_tags[pipe - 1] == .comma) { | 1395 | if (tree.tokenTag(@intCast(pipe - 1)) == .comma) { |
| 1402 | try ais.pushIndent(.normal); | 1396 | try ais.pushIndent(.normal); |
| 1403 | try renderToken(r, cur - 1, .newline); // | | 1397 | try renderToken(r, cur - 1, .newline); // | |
| 1404 | while (true) { | 1398 | while (true) { |
| 1405 | if (token_tags[cur] == .asterisk) { | 1399 | if (tree.tokenTag(cur) == .asterisk) { |
| 1406 | try renderToken(r, cur, .none); // * | 1400 | try renderToken(r, cur, .none); // * |
| 1407 | cur += 1; | 1401 | cur += 1; |
| 1408 | } | 1402 | } |
| 1409 | try renderIdentifier(r, cur, .none, .preserve_when_shadowing); // identifier | 1403 | try renderIdentifier(r, cur, .none, .preserve_when_shadowing); // identifier |
| 1410 | cur += 1; | 1404 | cur += 1; |
| 1411 | if (token_tags[cur] == .comma) { | 1405 | if (tree.tokenTag(cur) == .comma) { |
| 1412 | try renderToken(r, cur, .newline); // , | 1406 | try renderToken(r, cur, .newline); // , |
| 1413 | cur += 1; | 1407 | cur += 1; |
| 1414 | } | 1408 | } |
| 1415 | if (token_tags[cur] == .pipe) { | 1409 | if (tree.tokenTag(cur) == .pipe) { |
| 1416 | break; | 1410 | break; |
| 1417 | } | 1411 | } |
| 1418 | } | 1412 | } |
| ... | @@ -1420,17 +1414,17 @@ fn renderFor(r: *Render, for_node: Ast.full.For, space: Space) Error!void { | ... | @@ -1420,17 +1414,17 @@ fn renderFor(r: *Render, for_node: Ast.full.For, space: Space) Error!void { |
| 1420 | } else { | 1414 | } else { |
| 1421 | try renderToken(r, cur - 1, .none); // | | 1415 | try renderToken(r, cur - 1, .none); // | |
| 1422 | while (true) { | 1416 | while (true) { |
| 1423 | if (token_tags[cur] == .asterisk) { | 1417 | if (tree.tokenTag(cur) == .asterisk) { |
| 1424 | try renderToken(r, cur, .none); // * | 1418 | try renderToken(r, cur, .none); // * |
| 1425 | cur += 1; | 1419 | cur += 1; |
| 1426 | } | 1420 | } |
| 1427 | try renderIdentifier(r, cur, .none, .preserve_when_shadowing); // identifier | 1421 | try renderIdentifier(r, cur, .none, .preserve_when_shadowing); // identifier |
| 1428 | cur += 1; | 1422 | cur += 1; |
| 1429 | if (token_tags[cur] == .comma) { | 1423 | if (tree.tokenTag(cur) == .comma) { |
| 1430 | try renderToken(r, cur, .space); // , | 1424 | try renderToken(r, cur, .space); // , |
| 1431 | cur += 1; | 1425 | cur += 1; |
| 1432 | } | 1426 | } |
| 1433 | if (token_tags[cur] == .pipe) { | 1427 | if (tree.tokenTag(cur) == .pipe) { |
| 1434 | break; | 1428 | break; |
| 1435 | } | 1429 | } |
| 1436 | } | 1430 | } |
| ... | @@ -1456,7 +1450,7 @@ fn renderContainerField( | ... | @@ -1456,7 +1450,7 @@ fn renderContainerField( |
| 1456 | const tree = r.tree; | 1450 | const tree = r.tree; |
| 1457 | const ais = r.ais; | 1451 | const ais = r.ais; |
| 1458 | var field = field_param; | 1452 | var field = field_param; |
| 1459 | if (container != .tuple) field.convertToNonTupleLike(tree.nodes); | 1453 | if (container != .tuple) field.convertToNonTupleLike(&tree); |
| 1460 | const quote: QuoteBehavior = switch (container) { | 1454 | const quote: QuoteBehavior = switch (container) { |
| 1461 | .@"enum" => .eagerly_unquote_except_underscore, | 1455 | .@"enum" => .eagerly_unquote_except_underscore, |
| 1462 | .tuple, .other => .eagerly_unquote, | 1456 | .tuple, .other => .eagerly_unquote, |
| ... | @@ -1465,67 +1459,74 @@ fn renderContainerField( | ... | @@ -1465,67 +1459,74 @@ fn renderContainerField( |
| 1465 | if (field.comptime_token) |t| { | 1459 | if (field.comptime_token) |t| { |
| 1466 | try renderToken(r, t, .space); // comptime | 1460 | try renderToken(r, t, .space); // comptime |
| 1467 | } | 1461 | } |
| 1468 | if (field.ast.type_expr == 0 and field.ast.value_expr == 0) { | 1462 | if (field.ast.type_expr == .none and field.ast.value_expr == .none) { |
| 1469 | if (field.ast.align_expr != 0) { | 1463 | if (field.ast.align_expr.unwrap()) |align_expr| { |
| 1470 | try renderIdentifier(r, field.ast.main_token, .space, quote); // name | 1464 | try renderIdentifier(r, field.ast.main_token, .space, quote); // name |
| 1471 | const lparen_token = tree.firstToken(field.ast.align_expr) - 1; | 1465 | const lparen_token = tree.firstToken(align_expr) - 1; |
| 1472 | const align_kw = lparen_token - 1; | 1466 | const align_kw = lparen_token - 1; |
| 1473 | const rparen_token = tree.lastToken(field.ast.align_expr) + 1; | 1467 | const rparen_token = tree.lastToken(align_expr) + 1; |
| 1474 | try renderToken(r, align_kw, .none); // align | 1468 | try renderToken(r, align_kw, .none); // align |
| 1475 | try renderToken(r, lparen_token, .none); // ( | 1469 | try renderToken(r, lparen_token, .none); // ( |
| 1476 | try renderExpression(r, field.ast.align_expr, .none); // alignment | 1470 | try renderExpression(r, align_expr, .none); // alignment |
| 1477 | return renderToken(r, rparen_token, .space); // ) | 1471 | return renderToken(r, rparen_token, .space); // ) |
| 1478 | } | 1472 | } |
| 1479 | return renderIdentifierComma(r, field.ast.main_token, space, quote); // name | 1473 | return renderIdentifierComma(r, field.ast.main_token, space, quote); // name |
| 1480 | } | 1474 | } |
| 1481 | if (field.ast.type_expr != 0 and field.ast.value_expr == 0) { | 1475 | if (field.ast.type_expr != .none and field.ast.value_expr == .none) { |
| 1476 | const type_expr = field.ast.type_expr.unwrap().?; | ||
| 1482 | if (!field.ast.tuple_like) { | 1477 | if (!field.ast.tuple_like) { |
| 1483 | try renderIdentifier(r, field.ast.main_token, .none, quote); // name | 1478 | try renderIdentifier(r, field.ast.main_token, .none, quote); // name |
| 1484 | try renderToken(r, field.ast.main_token + 1, .space); // : | 1479 | try renderToken(r, field.ast.main_token + 1, .space); // : |
| 1485 | } | 1480 | } |
| 1486 | 1481 | ||
| 1487 | if (field.ast.align_expr != 0) { | 1482 | if (field.ast.align_expr.unwrap()) |align_expr| { |
| 1488 | try renderExpression(r, field.ast.type_expr, .space); // type | 1483 | try renderExpression(r, type_expr, .space); // type |
| 1489 | const align_token = tree.firstToken(field.ast.align_expr) - 2; | 1484 | const align_token = tree.firstToken(align_expr) - 2; |
| 1490 | try renderToken(r, align_token, .none); // align | 1485 | try renderToken(r, align_token, .none); // align |
| 1491 | try renderToken(r, align_token + 1, .none); // ( | 1486 | try renderToken(r, align_token + 1, .none); // ( |
| 1492 | try renderExpression(r, field.ast.align_expr, .none); // alignment | 1487 | try renderExpression(r, align_expr, .none); // alignment |
| 1493 | const rparen = tree.lastToken(field.ast.align_expr) + 1; | 1488 | const rparen = tree.lastToken(align_expr) + 1; |
| 1494 | return renderTokenComma(r, rparen, space); // ) | 1489 | return renderTokenComma(r, rparen, space); // ) |
| 1495 | } else { | 1490 | } else { |
| 1496 | return renderExpressionComma(r, field.ast.type_expr, space); // type | 1491 | return renderExpressionComma(r, type_expr, space); // type |
| 1497 | } | 1492 | } |
| 1498 | } | 1493 | } |
| 1499 | if (field.ast.type_expr == 0 and field.ast.value_expr != 0) { | 1494 | if (field.ast.type_expr == .none and field.ast.value_expr != .none) { |
| 1495 | const value_expr = field.ast.value_expr.unwrap().?; | ||
| 1496 | |||
| 1500 | try renderIdentifier(r, field.ast.main_token, .space, quote); // name | 1497 | try renderIdentifier(r, field.ast.main_token, .space, quote); // name |
| 1501 | if (field.ast.align_expr != 0) { | 1498 | if (field.ast.align_expr.unwrap()) |align_expr| { |
| 1502 | const lparen_token = tree.firstToken(field.ast.align_expr) - 1; | 1499 | const lparen_token = tree.firstToken(align_expr) - 1; |
| 1503 | const align_kw = lparen_token - 1; | 1500 | const align_kw = lparen_token - 1; |
| 1504 | const rparen_token = tree.lastToken(field.ast.align_expr) + 1; | 1501 | const rparen_token = tree.lastToken(align_expr) + 1; |
| 1505 | try renderToken(r, align_kw, .none); // align | 1502 | try renderToken(r, align_kw, .none); // align |
| 1506 | try renderToken(r, lparen_token, .none); // ( | 1503 | try renderToken(r, lparen_token, .none); // ( |
| 1507 | try renderExpression(r, field.ast.align_expr, .none); // alignment | 1504 | try renderExpression(r, align_expr, .none); // alignment |
| 1508 | try renderToken(r, rparen_token, .space); // ) | 1505 | try renderToken(r, rparen_token, .space); // ) |
| 1509 | } | 1506 | } |
| 1510 | try renderToken(r, field.ast.main_token + 1, .space); // = | 1507 | try renderToken(r, field.ast.main_token + 1, .space); // = |
| 1511 | return renderExpressionComma(r, field.ast.value_expr, space); // value | 1508 | return renderExpressionComma(r, value_expr, space); // value |
| 1512 | } | 1509 | } |
| 1513 | if (!field.ast.tuple_like) { | 1510 | if (!field.ast.tuple_like) { |
| 1514 | try renderIdentifier(r, field.ast.main_token, .none, quote); // name | 1511 | try renderIdentifier(r, field.ast.main_token, .none, quote); // name |
| 1515 | try renderToken(r, field.ast.main_token + 1, .space); // : | 1512 | try renderToken(r, field.ast.main_token + 1, .space); // : |
| 1516 | } | 1513 | } |
| 1517 | try renderExpression(r, field.ast.type_expr, .space); // type | ||
| 1518 | 1514 | ||
| 1519 | if (field.ast.align_expr != 0) { | 1515 | const type_expr = field.ast.type_expr.unwrap().?; |
| 1520 | const lparen_token = tree.firstToken(field.ast.align_expr) - 1; | 1516 | const value_expr = field.ast.value_expr.unwrap().?; |
| 1517 | |||
| 1518 | try renderExpression(r, type_expr, .space); // type | ||
| 1519 | |||
| 1520 | if (field.ast.align_expr.unwrap()) |align_expr| { | ||
| 1521 | const lparen_token = tree.firstToken(align_expr) - 1; | ||
| 1521 | const align_kw = lparen_token - 1; | 1522 | const align_kw = lparen_token - 1; |
| 1522 | const rparen_token = tree.lastToken(field.ast.align_expr) + 1; | 1523 | const rparen_token = tree.lastToken(align_expr) + 1; |
| 1523 | try renderToken(r, align_kw, .none); // align | 1524 | try renderToken(r, align_kw, .none); // align |
| 1524 | try renderToken(r, lparen_token, .none); // ( | 1525 | try renderToken(r, lparen_token, .none); // ( |
| 1525 | try renderExpression(r, field.ast.align_expr, .none); // alignment | 1526 | try renderExpression(r, align_expr, .none); // alignment |
| 1526 | try renderToken(r, rparen_token, .space); // ) | 1527 | try renderToken(r, rparen_token, .space); // ) |
| 1527 | } | 1528 | } |
| 1528 | const eq_token = tree.firstToken(field.ast.value_expr) - 1; | 1529 | const eq_token = tree.firstToken(value_expr) - 1; |
| 1529 | const eq_space: Space = if (tree.tokensOnSameLine(eq_token, eq_token + 1)) .space else .newline; | 1530 | const eq_space: Space = if (tree.tokensOnSameLine(eq_token, eq_token + 1)) .space else .newline; |
| 1530 | 1531 | ||
| 1531 | try ais.pushIndent(.after_equals); | 1532 | try ais.pushIndent(.after_equals); |
| ... | @@ -1533,19 +1534,18 @@ fn renderContainerField( | ... | @@ -1533,19 +1534,18 @@ fn renderContainerField( |
| 1533 | 1534 | ||
| 1534 | if (eq_space == .space) { | 1535 | if (eq_space == .space) { |
| 1535 | ais.popIndent(); | 1536 | ais.popIndent(); |
| 1536 | try renderExpressionComma(r, field.ast.value_expr, space); // value | 1537 | try renderExpressionComma(r, value_expr, space); // value |
| 1537 | return; | 1538 | return; |
| 1538 | } | 1539 | } |
| 1539 | 1540 | ||
| 1540 | const token_tags = tree.tokens.items(.tag); | 1541 | const maybe_comma = tree.lastToken(value_expr) + 1; |
| 1541 | const maybe_comma = tree.lastToken(field.ast.value_expr) + 1; | ||
| 1542 | 1542 | ||
| 1543 | if (token_tags[maybe_comma] == .comma) { | 1543 | if (tree.tokenTag(maybe_comma) == .comma) { |
| 1544 | try renderExpression(r, field.ast.value_expr, .none); // value | 1544 | try renderExpression(r, value_expr, .none); // value |
| 1545 | ais.popIndent(); | 1545 | ais.popIndent(); |
| 1546 | try renderToken(r, maybe_comma, .newline); | 1546 | try renderToken(r, maybe_comma, .newline); |
| 1547 | } else { | 1547 | } else { |
| 1548 | try renderExpression(r, field.ast.value_expr, space); // value | 1548 | try renderExpression(r, value_expr, space); // value |
| 1549 | ais.popIndent(); | 1549 | ais.popIndent(); |
| 1550 | } | 1550 | } |
| 1551 | } | 1551 | } |
| ... | @@ -1558,8 +1558,6 @@ fn renderBuiltinCall( | ... | @@ -1558,8 +1558,6 @@ fn renderBuiltinCall( |
| 1558 | ) Error!void { | 1558 | ) Error!void { |
| 1559 | const tree = r.tree; | 1559 | const tree = r.tree; |
| 1560 | const ais = r.ais; | 1560 | const ais = r.ais; |
| 1561 | const token_tags = tree.tokens.items(.tag); | ||
| 1562 | const main_tokens = tree.nodes.items(.main_token); | ||
| 1563 | 1561 | ||
| 1564 | try renderToken(r, builtin_token, .none); // @name | 1562 | try renderToken(r, builtin_token, .none); // @name |
| 1565 | 1563 | ||
| ... | @@ -1572,8 +1570,8 @@ fn renderBuiltinCall( | ... | @@ -1572,8 +1570,8 @@ fn renderBuiltinCall( |
| 1572 | const slice = tree.tokenSlice(builtin_token); | 1570 | const slice = tree.tokenSlice(builtin_token); |
| 1573 | if (mem.eql(u8, slice, "@import")) f: { | 1571 | if (mem.eql(u8, slice, "@import")) f: { |
| 1574 | const param = params[0]; | 1572 | const param = params[0]; |
| 1575 | const str_lit_token = main_tokens[param]; | 1573 | const str_lit_token = tree.nodeMainToken(param); |
| 1576 | assert(token_tags[str_lit_token] == .string_literal); | 1574 | assert(tree.tokenTag(str_lit_token) == .string_literal); |
| 1577 | const token_bytes = tree.tokenSlice(str_lit_token); | 1575 | const token_bytes = tree.tokenSlice(str_lit_token); |
| 1578 | const imported_string = std.zig.string_literal.parseAlloc(r.gpa, token_bytes) catch |err| switch (err) { | 1576 | const imported_string = std.zig.string_literal.parseAlloc(r.gpa, token_bytes) catch |err| switch (err) { |
| 1579 | error.OutOfMemory => return error.OutOfMemory, | 1577 | error.OutOfMemory => return error.OutOfMemory, |
| ... | @@ -1592,13 +1590,13 @@ fn renderBuiltinCall( | ... | @@ -1592,13 +1590,13 @@ fn renderBuiltinCall( |
| 1592 | const last_param = params[params.len - 1]; | 1590 | const last_param = params[params.len - 1]; |
| 1593 | const after_last_param_token = tree.lastToken(last_param) + 1; | 1591 | const after_last_param_token = tree.lastToken(last_param) + 1; |
| 1594 | 1592 | ||
| 1595 | if (token_tags[after_last_param_token] != .comma) { | 1593 | if (tree.tokenTag(after_last_param_token) != .comma) { |
| 1596 | // Render all on one line, no trailing comma. | 1594 | // Render all on one line, no trailing comma. |
| 1597 | try renderToken(r, builtin_token + 1, .none); // ( | 1595 | try renderToken(r, builtin_token + 1, .none); // ( |
| 1598 | 1596 | ||
| 1599 | for (params, 0..) |param_node, i| { | 1597 | for (params, 0..) |param_node, i| { |
| 1600 | const first_param_token = tree.firstToken(param_node); | 1598 | const first_param_token = tree.firstToken(param_node); |
| 1601 | if (token_tags[first_param_token] == .multiline_string_literal_line or | 1599 | if (tree.tokenTag(first_param_token) == .multiline_string_literal_line or |
| 1602 | hasSameLineComment(tree, first_param_token - 1)) | 1600 | hasSameLineComment(tree, first_param_token - 1)) |
| 1603 | { | 1601 | { |
| 1604 | try ais.pushIndent(.normal); | 1602 | try ais.pushIndent(.normal); |
| ... | @@ -1633,11 +1631,9 @@ fn renderBuiltinCall( | ... | @@ -1633,11 +1631,9 @@ fn renderBuiltinCall( |
| 1633 | fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!void { | 1631 | fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!void { |
| 1634 | const tree = r.tree; | 1632 | const tree = r.tree; |
| 1635 | const ais = r.ais; | 1633 | const ais = r.ais; |
| 1636 | const token_tags = tree.tokens.items(.tag); | ||
| 1637 | const token_starts = tree.tokens.items(.start); | ||
| 1638 | 1634 | ||
| 1639 | const after_fn_token = fn_proto.ast.fn_token + 1; | 1635 | const after_fn_token = fn_proto.ast.fn_token + 1; |
| 1640 | const lparen = if (token_tags[after_fn_token] == .identifier) blk: { | 1636 | const lparen = if (tree.tokenTag(after_fn_token) == .identifier) blk: { |
| 1641 | try renderToken(r, fn_proto.ast.fn_token, .space); // fn | 1637 | try renderToken(r, fn_proto.ast.fn_token, .space); // fn |
| 1642 | try renderIdentifier(r, after_fn_token, .none, .preserve_when_shadowing); // name | 1638 | try renderIdentifier(r, after_fn_token, .none, .preserve_when_shadowing); // name |
| 1643 | break :blk after_fn_token + 1; | 1639 | break :blk after_fn_token + 1; |
| ... | @@ -1645,41 +1641,42 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi | ... | @@ -1645,41 +1641,42 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi |
| 1645 | try renderToken(r, fn_proto.ast.fn_token, .space); // fn | 1641 | try renderToken(r, fn_proto.ast.fn_token, .space); // fn |
| 1646 | break :blk fn_proto.ast.fn_token + 1; | 1642 | break :blk fn_proto.ast.fn_token + 1; |
| 1647 | }; | 1643 | }; |
| 1648 | assert(token_tags[lparen] == .l_paren); | 1644 | assert(tree.tokenTag(lparen) == .l_paren); |
| 1649 | 1645 | ||
| 1650 | const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1; | 1646 | const return_type = fn_proto.ast.return_type.unwrap().?; |
| 1647 | const maybe_bang = tree.firstToken(return_type) - 1; | ||
| 1651 | const rparen = blk: { | 1648 | const rparen = blk: { |
| 1652 | // These may appear in any order, so we have to check the token_starts array | 1649 | // These may appear in any order, so we have to check the token_starts array |
| 1653 | // to find out which is first. | 1650 | // to find out which is first. |
| 1654 | var rparen = if (token_tags[maybe_bang] == .bang) maybe_bang - 1 else maybe_bang; | 1651 | var rparen = if (tree.tokenTag(maybe_bang) == .bang) maybe_bang - 1 else maybe_bang; |
| 1655 | var smallest_start = token_starts[maybe_bang]; | 1652 | var smallest_start = tree.tokenStart(maybe_bang); |
| 1656 | if (fn_proto.ast.align_expr != 0) { | 1653 | if (fn_proto.ast.align_expr.unwrap()) |align_expr| { |
| 1657 | const tok = tree.firstToken(fn_proto.ast.align_expr) - 3; | 1654 | const tok = tree.firstToken(align_expr) - 3; |
| 1658 | const start = token_starts[tok]; | 1655 | const start = tree.tokenStart(tok); |
| 1659 | if (start < smallest_start) { | 1656 | if (start < smallest_start) { |
| 1660 | rparen = tok; | 1657 | rparen = tok; |
| 1661 | smallest_start = start; | 1658 | smallest_start = start; |
| 1662 | } | 1659 | } |
| 1663 | } | 1660 | } |
| 1664 | if (fn_proto.ast.addrspace_expr != 0) { | 1661 | if (fn_proto.ast.addrspace_expr.unwrap()) |addrspace_expr| { |
| 1665 | const tok = tree.firstToken(fn_proto.ast.addrspace_expr) - 3; | 1662 | const tok = tree.firstToken(addrspace_expr) - 3; |
| 1666 | const start = token_starts[tok]; | 1663 | const start = tree.tokenStart(tok); |
| 1667 | if (start < smallest_start) { | 1664 | if (start < smallest_start) { |
| 1668 | rparen = tok; | 1665 | rparen = tok; |
| 1669 | smallest_start = start; | 1666 | smallest_start = start; |
| 1670 | } | 1667 | } |
| 1671 | } | 1668 | } |
| 1672 | if (fn_proto.ast.section_expr != 0) { | 1669 | if (fn_proto.ast.section_expr.unwrap()) |section_expr| { |
| 1673 | const tok = tree.firstToken(fn_proto.ast.section_expr) - 3; | 1670 | const tok = tree.firstToken(section_expr) - 3; |
| 1674 | const start = token_starts[tok]; | 1671 | const start = tree.tokenStart(tok); |
| 1675 | if (start < smallest_start) { | 1672 | if (start < smallest_start) { |
| 1676 | rparen = tok; | 1673 | rparen = tok; |
| 1677 | smallest_start = start; | 1674 | smallest_start = start; |
| 1678 | } | 1675 | } |
| 1679 | } | 1676 | } |
| 1680 | if (fn_proto.ast.callconv_expr != 0) { | 1677 | if (fn_proto.ast.callconv_expr.unwrap()) |callconv_expr| { |
| 1681 | const tok = tree.firstToken(fn_proto.ast.callconv_expr) - 3; | 1678 | const tok = tree.firstToken(callconv_expr) - 3; |
| 1682 | const start = token_starts[tok]; | 1679 | const start = tree.tokenStart(tok); |
| 1683 | if (start < smallest_start) { | 1680 | if (start < smallest_start) { |
| 1684 | rparen = tok; | 1681 | rparen = tok; |
| 1685 | smallest_start = start; | 1682 | smallest_start = start; |
| ... | @@ -1687,11 +1684,11 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi | ... | @@ -1687,11 +1684,11 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi |
| 1687 | } | 1684 | } |
| 1688 | break :blk rparen; | 1685 | break :blk rparen; |
| 1689 | }; | 1686 | }; |
| 1690 | assert(token_tags[rparen] == .r_paren); | 1687 | assert(tree.tokenTag(rparen) == .r_paren); |
| 1691 | 1688 | ||
| 1692 | // The params list is a sparse set that does *not* include anytype or ... parameters. | 1689 | // The params list is a sparse set that does *not* include anytype or ... parameters. |
| 1693 | 1690 | ||
| 1694 | const trailing_comma = token_tags[rparen - 1] == .comma; | 1691 | const trailing_comma = tree.tokenTag(rparen - 1) == .comma; |
| 1695 | if (!trailing_comma and !hasComment(tree, lparen, rparen)) { | 1692 | if (!trailing_comma and !hasComment(tree, lparen, rparen)) { |
| 1696 | // Render all on one line, no trailing comma. | 1693 | // Render all on one line, no trailing comma. |
| 1697 | try renderToken(r, lparen, .none); // ( | 1694 | try renderToken(r, lparen, .none); // ( |
| ... | @@ -1700,7 +1697,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi | ... | @@ -1700,7 +1697,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi |
| 1700 | var last_param_token = lparen; | 1697 | var last_param_token = lparen; |
| 1701 | while (true) { | 1698 | while (true) { |
| 1702 | last_param_token += 1; | 1699 | last_param_token += 1; |
| 1703 | switch (token_tags[last_param_token]) { | 1700 | switch (tree.tokenTag(last_param_token)) { |
| 1704 | .doc_comment => { | 1701 | .doc_comment => { |
| 1705 | try renderToken(r, last_param_token, .newline); | 1702 | try renderToken(r, last_param_token, .newline); |
| 1706 | continue; | 1703 | continue; |
| ... | @@ -1725,15 +1722,15 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi | ... | @@ -1725,15 +1722,15 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi |
| 1725 | }, | 1722 | }, |
| 1726 | else => {}, // Parameter type without a name. | 1723 | else => {}, // Parameter type without a name. |
| 1727 | } | 1724 | } |
| 1728 | if (token_tags[last_param_token] == .identifier and | 1725 | if (tree.tokenTag(last_param_token) == .identifier and |
| 1729 | token_tags[last_param_token + 1] == .colon) | 1726 | tree.tokenTag(last_param_token + 1) == .colon) |
| 1730 | { | 1727 | { |
| 1731 | try renderIdentifier(r, last_param_token, .none, .preserve_when_shadowing); // name | 1728 | try renderIdentifier(r, last_param_token, .none, .preserve_when_shadowing); // name |
| 1732 | last_param_token += 1; | 1729 | last_param_token = last_param_token + 1; |
| 1733 | try renderToken(r, last_param_token, .space); // : | 1730 | try renderToken(r, last_param_token, .space); // : |
| 1734 | last_param_token += 1; | 1731 | last_param_token += 1; |
| 1735 | } | 1732 | } |
| 1736 | if (token_tags[last_param_token] == .keyword_anytype) { | 1733 | if (tree.tokenTag(last_param_token) == .keyword_anytype) { |
| 1737 | try renderToken(r, last_param_token, .none); // anytype | 1734 | try renderToken(r, last_param_token, .none); // anytype |
| 1738 | continue; | 1735 | continue; |
| 1739 | } | 1736 | } |
| ... | @@ -1751,7 +1748,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi | ... | @@ -1751,7 +1748,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi |
| 1751 | var last_param_token = lparen; | 1748 | var last_param_token = lparen; |
| 1752 | while (true) { | 1749 | while (true) { |
| 1753 | last_param_token += 1; | 1750 | last_param_token += 1; |
| 1754 | switch (token_tags[last_param_token]) { | 1751 | switch (tree.tokenTag(last_param_token)) { |
| 1755 | .doc_comment => { | 1752 | .doc_comment => { |
| 1756 | try renderToken(r, last_param_token, .newline); | 1753 | try renderToken(r, last_param_token, .newline); |
| 1757 | continue; | 1754 | continue; |
| ... | @@ -1767,24 +1764,24 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi | ... | @@ -1767,24 +1764,24 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi |
| 1767 | .identifier => {}, | 1764 | .identifier => {}, |
| 1768 | .keyword_anytype => { | 1765 | .keyword_anytype => { |
| 1769 | try renderToken(r, last_param_token, .comma); // anytype | 1766 | try renderToken(r, last_param_token, .comma); // anytype |
| 1770 | if (token_tags[last_param_token + 1] == .comma) | 1767 | if (tree.tokenTag(last_param_token + 1) == .comma) |
| 1771 | last_param_token += 1; | 1768 | last_param_token += 1; |
| 1772 | continue; | 1769 | continue; |
| 1773 | }, | 1770 | }, |
| 1774 | .r_paren => break, | 1771 | .r_paren => break, |
| 1775 | else => {}, // Parameter type without a name. | 1772 | else => {}, // Parameter type without a name. |
| 1776 | } | 1773 | } |
| 1777 | if (token_tags[last_param_token] == .identifier and | 1774 | if (tree.tokenTag(last_param_token) == .identifier and |
| 1778 | token_tags[last_param_token + 1] == .colon) | 1775 | tree.tokenTag(last_param_token + 1) == .colon) |
| 1779 | { | 1776 | { |
| 1780 | try renderIdentifier(r, last_param_token, .none, .preserve_when_shadowing); // name | 1777 | try renderIdentifier(r, last_param_token, .none, .preserve_when_shadowing); // name |
| 1781 | last_param_token += 1; | 1778 | last_param_token += 1; |
| 1782 | try renderToken(r, last_param_token, .space); // : | 1779 | try renderToken(r, last_param_token, .space); // : |
| 1783 | last_param_token += 1; | 1780 | last_param_token += 1; |
| 1784 | } | 1781 | } |
| 1785 | if (token_tags[last_param_token] == .keyword_anytype) { | 1782 | if (tree.tokenTag(last_param_token) == .keyword_anytype) { |
| 1786 | try renderToken(r, last_param_token, .comma); // anytype | 1783 | try renderToken(r, last_param_token, .comma); // anytype |
| 1787 | if (token_tags[last_param_token + 1] == .comma) | 1784 | if (tree.tokenTag(last_param_token + 1) == .comma) |
| 1788 | last_param_token += 1; | 1785 | last_param_token += 1; |
| 1789 | continue; | 1786 | continue; |
| 1790 | } | 1787 | } |
| ... | @@ -1794,60 +1791,62 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi | ... | @@ -1794,60 +1791,62 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi |
| 1794 | try renderExpression(r, param, .comma); | 1791 | try renderExpression(r, param, .comma); |
| 1795 | ais.popSpace(); | 1792 | ais.popSpace(); |
| 1796 | last_param_token = tree.lastToken(param); | 1793 | last_param_token = tree.lastToken(param); |
| 1797 | if (token_tags[last_param_token + 1] == .comma) last_param_token += 1; | 1794 | if (tree.tokenTag(last_param_token + 1) == .comma) last_param_token += 1; |
| 1798 | } | 1795 | } |
| 1799 | ais.popIndent(); | 1796 | ais.popIndent(); |
| 1800 | } | 1797 | } |
| 1801 | 1798 | ||
| 1802 | try renderToken(r, rparen, .space); // ) | 1799 | try renderToken(r, rparen, .space); // ) |
| 1803 | 1800 | ||
| 1804 | if (fn_proto.ast.align_expr != 0) { | 1801 | if (fn_proto.ast.align_expr.unwrap()) |align_expr| { |
| 1805 | const align_lparen = tree.firstToken(fn_proto.ast.align_expr) - 1; | 1802 | const align_lparen = tree.firstToken(align_expr) - 1; |
| 1806 | const align_rparen = tree.lastToken(fn_proto.ast.align_expr) + 1; | 1803 | const align_rparen = tree.lastToken(align_expr) + 1; |
| 1807 | 1804 | ||
| 1808 | try renderToken(r, align_lparen - 1, .none); // align | 1805 | try renderToken(r, align_lparen - 1, .none); // align |
| 1809 | try renderToken(r, align_lparen, .none); // ( | 1806 | try renderToken(r, align_lparen, .none); // ( |
| 1810 | try renderExpression(r, fn_proto.ast.align_expr, .none); | 1807 | try renderExpression(r, align_expr, .none); |
| 1811 | try renderToken(r, align_rparen, .space); // ) | 1808 | try renderToken(r, align_rparen, .space); // ) |
| 1812 | } | 1809 | } |
| 1813 | 1810 | ||
| 1814 | if (fn_proto.ast.addrspace_expr != 0) { | 1811 | if (fn_proto.ast.addrspace_expr.unwrap()) |addrspace_expr| { |
| 1815 | const align_lparen = tree.firstToken(fn_proto.ast.addrspace_expr) - 1; | 1812 | const align_lparen = tree.firstToken(addrspace_expr) - 1; |
| 1816 | const align_rparen = tree.lastToken(fn_proto.ast.addrspace_expr) + 1; | 1813 | const align_rparen = tree.lastToken(addrspace_expr) + 1; |
| 1817 | 1814 | ||
| 1818 | try renderToken(r, align_lparen - 1, .none); // addrspace | 1815 | try renderToken(r, align_lparen - 1, .none); // addrspace |
| 1819 | try renderToken(r, align_lparen, .none); // ( | 1816 | try renderToken(r, align_lparen, .none); // ( |
| 1820 | try renderExpression(r, fn_proto.ast.addrspace_expr, .none); | 1817 | try renderExpression(r, addrspace_expr, .none); |
| 1821 | try renderToken(r, align_rparen, .space); // ) | 1818 | try renderToken(r, align_rparen, .space); // ) |
| 1822 | } | 1819 | } |
| 1823 | 1820 | ||
| 1824 | if (fn_proto.ast.section_expr != 0) { | 1821 | if (fn_proto.ast.section_expr.unwrap()) |section_expr| { |
| 1825 | const section_lparen = tree.firstToken(fn_proto.ast.section_expr) - 1; | 1822 | const section_lparen = tree.firstToken(section_expr) - 1; |
| 1826 | const section_rparen = tree.lastToken(fn_proto.ast.section_expr) + 1; | 1823 | const section_rparen = tree.lastToken(section_expr) + 1; |
| 1827 | 1824 | ||
| 1828 | try renderToken(r, section_lparen - 1, .none); // section | 1825 | try renderToken(r, section_lparen - 1, .none); // section |
| 1829 | try renderToken(r, section_lparen, .none); // ( | 1826 | try renderToken(r, section_lparen, .none); // ( |
| 1830 | try renderExpression(r, fn_proto.ast.section_expr, .none); | 1827 | try renderExpression(r, section_expr, .none); |
| 1831 | try renderToken(r, section_rparen, .space); // ) | 1828 | try renderToken(r, section_rparen, .space); // ) |
| 1832 | } | 1829 | } |
| 1833 | 1830 | ||
| 1834 | // Keep in sync with logic in `renderMember`. Search this file for the marker PROMOTE_CALLCONV_INLINE | 1831 | if (fn_proto.ast.callconv_expr.unwrap()) |callconv_expr| { |
| 1835 | const is_callconv_inline = mem.eql(u8, "@\"inline\"", tree.tokenSlice(tree.nodes.items(.main_token)[fn_proto.ast.callconv_expr])); | 1832 | // Keep in sync with logic in `renderMember`. Search this file for the marker PROMOTE_CALLCONV_INLINE |
| 1836 | const is_declaration = fn_proto.name_token != null; | 1833 | const is_callconv_inline = mem.eql(u8, "@\"inline\"", tree.tokenSlice(tree.nodeMainToken(callconv_expr))); |
| 1837 | if (fn_proto.ast.callconv_expr != 0 and !(is_declaration and is_callconv_inline)) { | 1834 | const is_declaration = fn_proto.name_token != null; |
| 1838 | const callconv_lparen = tree.firstToken(fn_proto.ast.callconv_expr) - 1; | 1835 | if (!(is_declaration and is_callconv_inline)) { |
| 1839 | const callconv_rparen = tree.lastToken(fn_proto.ast.callconv_expr) + 1; | 1836 | const callconv_lparen = tree.firstToken(callconv_expr) - 1; |
| 1837 | const callconv_rparen = tree.lastToken(callconv_expr) + 1; | ||
| 1840 | 1838 | ||
| 1841 | try renderToken(r, callconv_lparen - 1, .none); // callconv | 1839 | try renderToken(r, callconv_lparen - 1, .none); // callconv |
| 1842 | try renderToken(r, callconv_lparen, .none); // ( | 1840 | try renderToken(r, callconv_lparen, .none); // ( |
| 1843 | try renderExpression(r, fn_proto.ast.callconv_expr, .none); | 1841 | try renderExpression(r, callconv_expr, .none); |
| 1844 | try renderToken(r, callconv_rparen, .space); // ) | 1842 | try renderToken(r, callconv_rparen, .space); // ) |
| 1843 | } | ||
| 1845 | } | 1844 | } |
| 1846 | 1845 | ||
| 1847 | if (token_tags[maybe_bang] == .bang) { | 1846 | if (tree.tokenTag(maybe_bang) == .bang) { |
| 1848 | try renderToken(r, maybe_bang, .none); // ! | 1847 | try renderToken(r, maybe_bang, .none); // ! |
| 1849 | } | 1848 | } |
| 1850 | return renderExpression(r, fn_proto.ast.return_type, space); | 1849 | return renderExpression(r, return_type, space); |
| 1851 | } | 1850 | } |
| 1852 | 1851 | ||
| 1853 | fn renderSwitchCase( | 1852 | fn renderSwitchCase( |
| ... | @@ -1857,9 +1856,7 @@ fn renderSwitchCase( | ... | @@ -1857,9 +1856,7 @@ fn renderSwitchCase( |
| 1857 | ) Error!void { | 1856 | ) Error!void { |
| 1858 | const ais = r.ais; | 1857 | const ais = r.ais; |
| 1859 | const tree = r.tree; | 1858 | const tree = r.tree; |
| 1860 | const node_tags = tree.nodes.items(.tag); | 1859 | const trailing_comma = tree.tokenTag(switch_case.ast.arrow_token - 1) == .comma; |
| 1861 | const token_tags = tree.tokens.items(.tag); | ||
| 1862 | const trailing_comma = token_tags[switch_case.ast.arrow_token - 1] == .comma; | ||
| 1863 | const has_comment_before_arrow = blk: { | 1860 | const has_comment_before_arrow = blk: { |
| 1864 | if (switch_case.ast.values.len == 0) break :blk false; | 1861 | if (switch_case.ast.values.len == 0) break :blk false; |
| 1865 | break :blk hasComment(tree, tree.firstToken(switch_case.ast.values[0]), switch_case.ast.arrow_token); | 1862 | break :blk hasComment(tree, tree.firstToken(switch_case.ast.values[0]), switch_case.ast.arrow_token); |
| ... | @@ -1886,7 +1883,7 @@ fn renderSwitchCase( | ... | @@ -1886,7 +1883,7 @@ fn renderSwitchCase( |
| 1886 | } | 1883 | } |
| 1887 | 1884 | ||
| 1888 | // Render the arrow and everything after it | 1885 | // Render the arrow and everything after it |
| 1889 | const pre_target_space = if (node_tags[switch_case.ast.target_expr] == .multiline_string_literal) | 1886 | const pre_target_space = if (tree.nodeTag(switch_case.ast.target_expr) == .multiline_string_literal) |
| 1890 | // Newline gets inserted when rendering the target expr. | 1887 | // Newline gets inserted when rendering the target expr. |
| 1891 | Space.none | 1888 | Space.none |
| 1892 | else | 1889 | else |
| ... | @@ -1896,12 +1893,12 @@ fn renderSwitchCase( | ... | @@ -1896,12 +1893,12 @@ fn renderSwitchCase( |
| 1896 | 1893 | ||
| 1897 | if (switch_case.payload_token) |payload_token| { | 1894 | if (switch_case.payload_token) |payload_token| { |
| 1898 | try renderToken(r, payload_token - 1, .none); // pipe | 1895 | try renderToken(r, payload_token - 1, .none); // pipe |
| 1899 | const ident = payload_token + @intFromBool(token_tags[payload_token] == .asterisk); | 1896 | const ident = payload_token + @intFromBool(tree.tokenTag(payload_token) == .asterisk); |
| 1900 | if (token_tags[payload_token] == .asterisk) { | 1897 | if (tree.tokenTag(payload_token) == .asterisk) { |
| 1901 | try renderToken(r, payload_token, .none); // asterisk | 1898 | try renderToken(r, payload_token, .none); // asterisk |
| 1902 | } | 1899 | } |
| 1903 | try renderIdentifier(r, ident, .none, .preserve_when_shadowing); // identifier | 1900 | try renderIdentifier(r, ident, .none, .preserve_when_shadowing); // identifier |
| 1904 | if (token_tags[ident + 1] == .comma) { | 1901 | if (tree.tokenTag(ident + 1) == .comma) { |
| 1905 | try renderToken(r, ident + 1, .space); // , | 1902 | try renderToken(r, ident + 1, .space); // , |
| 1906 | try renderIdentifier(r, ident + 2, .none, .preserve_when_shadowing); // identifier | 1903 | try renderIdentifier(r, ident + 2, .none, .preserve_when_shadowing); // identifier |
| 1907 | try renderToken(r, ident + 3, pre_target_space); // pipe | 1904 | try renderToken(r, ident + 3, pre_target_space); // pipe |
| ... | @@ -1921,12 +1918,9 @@ fn renderBlock( | ... | @@ -1921,12 +1918,9 @@ fn renderBlock( |
| 1921 | ) Error!void { | 1918 | ) Error!void { |
| 1922 | const tree = r.tree; | 1919 | const tree = r.tree; |
| 1923 | const ais = r.ais; | 1920 | const ais = r.ais; |
| 1924 | const token_tags = tree.tokens.items(.tag); | 1921 | const lbrace = tree.nodeMainToken(block_node); |
| 1925 | const lbrace = tree.nodes.items(.main_token)[block_node]; | ||
| 1926 | 1922 | ||
| 1927 | if (token_tags[lbrace - 1] == .colon and | 1923 | if (tree.isTokenPrecededByTags(lbrace, &.{ .identifier, .colon })) { |
| 1928 | token_tags[lbrace - 2] == .identifier) | ||
| 1929 | { | ||
| 1930 | try renderIdentifier(r, lbrace - 2, .none, .eagerly_unquote); // identifier | 1924 | try renderIdentifier(r, lbrace - 2, .none, .eagerly_unquote); // identifier |
| 1931 | try renderToken(r, lbrace - 1, .space); // : | 1925 | try renderToken(r, lbrace - 1, .space); // : |
| 1932 | } | 1926 | } |
| ... | @@ -1948,13 +1942,12 @@ fn finishRenderBlock( | ... | @@ -1948,13 +1942,12 @@ fn finishRenderBlock( |
| 1948 | space: Space, | 1942 | space: Space, |
| 1949 | ) Error!void { | 1943 | ) Error!void { |
| 1950 | const tree = r.tree; | 1944 | const tree = r.tree; |
| 1951 | const node_tags = tree.nodes.items(.tag); | ||
| 1952 | const ais = r.ais; | 1945 | const ais = r.ais; |
| 1953 | for (statements, 0..) |stmt, i| { | 1946 | for (statements, 0..) |stmt, i| { |
| 1954 | if (i != 0) try renderExtraNewline(r, stmt); | 1947 | if (i != 0) try renderExtraNewline(r, stmt); |
| 1955 | if (r.fixups.omit_nodes.contains(stmt)) continue; | 1948 | if (r.fixups.omit_nodes.contains(stmt)) continue; |
| 1956 | try ais.pushSpace(.semicolon); | 1949 | try ais.pushSpace(.semicolon); |
| 1957 | switch (node_tags[stmt]) { | 1950 | switch (tree.nodeTag(stmt)) { |
| 1958 | .global_var_decl, | 1951 | .global_var_decl, |
| 1959 | .local_var_decl, | 1952 | .local_var_decl, |
| 1960 | .simple_var_decl, | 1953 | .simple_var_decl, |
| ... | @@ -1978,12 +1971,13 @@ fn renderStructInit( | ... | @@ -1978,12 +1971,13 @@ fn renderStructInit( |
| 1978 | ) Error!void { | 1971 | ) Error!void { |
| 1979 | const tree = r.tree; | 1972 | const tree = r.tree; |
| 1980 | const ais = r.ais; | 1973 | const ais = r.ais; |
| 1981 | const token_tags = tree.tokens.items(.tag); | 1974 | |
| 1982 | if (struct_init.ast.type_expr == 0) { | 1975 | if (struct_init.ast.type_expr.unwrap()) |type_expr| { |
| 1983 | try renderToken(r, struct_init.ast.lbrace - 1, .none); // . | 1976 | try renderExpression(r, type_expr, .none); // T |
| 1984 | } else { | 1977 | } else { |
| 1985 | try renderExpression(r, struct_init.ast.type_expr, .none); // T | 1978 | try renderToken(r, struct_init.ast.lbrace - 1, .none); // . |
| 1986 | } | 1979 | } |
| 1980 | |||
| 1987 | if (struct_init.ast.fields.len == 0) { | 1981 | if (struct_init.ast.fields.len == 0) { |
| 1988 | try ais.pushIndent(.normal); | 1982 | try ais.pushIndent(.normal); |
| 1989 | try renderToken(r, struct_init.ast.lbrace, .none); // lbrace | 1983 | try renderToken(r, struct_init.ast.lbrace, .none); // lbrace |
| ... | @@ -1992,7 +1986,7 @@ fn renderStructInit( | ... | @@ -1992,7 +1986,7 @@ fn renderStructInit( |
| 1992 | } | 1986 | } |
| 1993 | 1987 | ||
| 1994 | const rbrace = tree.lastToken(struct_node); | 1988 | const rbrace = tree.lastToken(struct_node); |
| 1995 | const trailing_comma = token_tags[rbrace - 1] == .comma; | 1989 | const trailing_comma = tree.tokenTag(rbrace - 1) == .comma; |
| 1996 | if (trailing_comma or hasComment(tree, struct_init.ast.lbrace, rbrace)) { | 1990 | if (trailing_comma or hasComment(tree, struct_init.ast.lbrace, rbrace)) { |
| 1997 | // Render one field init per line. | 1991 | // Render one field init per line. |
| 1998 | try ais.pushIndent(.normal); | 1992 | try ais.pushIndent(.normal); |
| ... | @@ -2002,9 +1996,8 @@ fn renderStructInit( | ... | @@ -2002,9 +1996,8 @@ fn renderStructInit( |
| 2002 | try renderIdentifier(r, struct_init.ast.lbrace + 2, .space, .eagerly_unquote); // name | 1996 | try renderIdentifier(r, struct_init.ast.lbrace + 2, .space, .eagerly_unquote); // name |
| 2003 | // Don't output a space after the = if expression is a multiline string, | 1997 | // Don't output a space after the = if expression is a multiline string, |
| 2004 | // since then it will start on the next line. | 1998 | // since then it will start on the next line. |
| 2005 | const nodes = tree.nodes.items(.tag); | ||
| 2006 | const field_node = struct_init.ast.fields[0]; | 1999 | const field_node = struct_init.ast.fields[0]; |
| 2007 | const expr = nodes[field_node]; | 2000 | const expr = tree.nodeTag(field_node); |
| 2008 | var space_after_equal: Space = if (expr == .multiline_string_literal) .none else .space; | 2001 | var space_after_equal: Space = if (expr == .multiline_string_literal) .none else .space; |
| 2009 | try renderToken(r, struct_init.ast.lbrace + 3, space_after_equal); // = | 2002 | try renderToken(r, struct_init.ast.lbrace + 3, space_after_equal); // = |
| 2010 | 2003 | ||
| ... | @@ -2017,7 +2010,7 @@ fn renderStructInit( | ... | @@ -2017,7 +2010,7 @@ fn renderStructInit( |
| 2017 | try renderExtraNewlineToken(r, init_token - 3); | 2010 | try renderExtraNewlineToken(r, init_token - 3); |
| 2018 | try renderToken(r, init_token - 3, .none); // . | 2011 | try renderToken(r, init_token - 3, .none); // . |
| 2019 | try renderIdentifier(r, init_token - 2, .space, .eagerly_unquote); // name | 2012 | try renderIdentifier(r, init_token - 2, .space, .eagerly_unquote); // name |
| 2020 | space_after_equal = if (nodes[field_init] == .multiline_string_literal) .none else .space; | 2013 | space_after_equal = if (tree.nodeTag(field_init) == .multiline_string_literal) .none else .space; |
| 2021 | try renderToken(r, init_token - 1, space_after_equal); // = | 2014 | try renderToken(r, init_token - 1, space_after_equal); // = |
| 2022 | 2015 | ||
| 2023 | try ais.pushSpace(.comma); | 2016 | try ais.pushSpace(.comma); |
| ... | @@ -2050,12 +2043,11 @@ fn renderArrayInit( | ... | @@ -2050,12 +2043,11 @@ fn renderArrayInit( |
| 2050 | const tree = r.tree; | 2043 | const tree = r.tree; |
| 2051 | const ais = r.ais; | 2044 | const ais = r.ais; |
| 2052 | const gpa = r.gpa; | 2045 | const gpa = r.gpa; |
| 2053 | const token_tags = tree.tokens.items(.tag); | ||
| 2054 | 2046 | ||
| 2055 | if (array_init.ast.type_expr == 0) { | 2047 | if (array_init.ast.type_expr.unwrap()) |type_expr| { |
| 2056 | try renderToken(r, array_init.ast.lbrace - 1, .none); // . | 2048 | try renderExpression(r, type_expr, .none); // T |
| 2057 | } else { | 2049 | } else { |
| 2058 | try renderExpression(r, array_init.ast.type_expr, .none); // T | 2050 | try renderToken(r, array_init.ast.lbrace - 1, .none); // . |
| 2059 | } | 2051 | } |
| 2060 | 2052 | ||
| 2061 | if (array_init.ast.elements.len == 0) { | 2053 | if (array_init.ast.elements.len == 0) { |
| ... | @@ -2067,14 +2059,14 @@ fn renderArrayInit( | ... | @@ -2067,14 +2059,14 @@ fn renderArrayInit( |
| 2067 | 2059 | ||
| 2068 | const last_elem = array_init.ast.elements[array_init.ast.elements.len - 1]; | 2060 | const last_elem = array_init.ast.elements[array_init.ast.elements.len - 1]; |
| 2069 | const last_elem_token = tree.lastToken(last_elem); | 2061 | const last_elem_token = tree.lastToken(last_elem); |
| 2070 | const trailing_comma = token_tags[last_elem_token + 1] == .comma; | 2062 | const trailing_comma = tree.tokenTag(last_elem_token + 1) == .comma; |
| 2071 | const rbrace = if (trailing_comma) last_elem_token + 2 else last_elem_token + 1; | 2063 | const rbrace = if (trailing_comma) last_elem_token + 2 else last_elem_token + 1; |
| 2072 | assert(token_tags[rbrace] == .r_brace); | 2064 | assert(tree.tokenTag(rbrace) == .r_brace); |
| 2073 | 2065 | ||
| 2074 | if (array_init.ast.elements.len == 1) { | 2066 | if (array_init.ast.elements.len == 1) { |
| 2075 | const only_elem = array_init.ast.elements[0]; | 2067 | const only_elem = array_init.ast.elements[0]; |
| 2076 | const first_token = tree.firstToken(only_elem); | 2068 | const first_token = tree.firstToken(only_elem); |
| 2077 | if (token_tags[first_token] != .multiline_string_literal_line and | 2069 | if (tree.tokenTag(first_token) != .multiline_string_literal_line and |
| 2078 | !anythingBetween(tree, last_elem_token, rbrace)) | 2070 | !anythingBetween(tree, last_elem_token, rbrace)) |
| 2079 | { | 2071 | { |
| 2080 | try renderToken(r, array_init.ast.lbrace, .none); | 2072 | try renderToken(r, array_init.ast.lbrace, .none); |
| ... | @@ -2137,7 +2129,7 @@ fn renderArrayInit( | ... | @@ -2137,7 +2129,7 @@ fn renderArrayInit( |
| 2137 | } | 2129 | } |
| 2138 | 2130 | ||
| 2139 | const maybe_comma = expr_last_token + 1; | 2131 | const maybe_comma = expr_last_token + 1; |
| 2140 | if (token_tags[maybe_comma] == .comma) { | 2132 | if (tree.tokenTag(maybe_comma) == .comma) { |
| 2141 | if (hasSameLineComment(tree, maybe_comma)) | 2133 | if (hasSameLineComment(tree, maybe_comma)) |
| 2142 | break :sec_end i - this_line_size + 1; | 2134 | break :sec_end i - this_line_size + 1; |
| 2143 | } | 2135 | } |
| ... | @@ -2277,13 +2269,12 @@ fn renderContainerDecl( | ... | @@ -2277,13 +2269,12 @@ fn renderContainerDecl( |
| 2277 | ) Error!void { | 2269 | ) Error!void { |
| 2278 | const tree = r.tree; | 2270 | const tree = r.tree; |
| 2279 | const ais = r.ais; | 2271 | const ais = r.ais; |
| 2280 | const token_tags = tree.tokens.items(.tag); | ||
| 2281 | 2272 | ||
| 2282 | if (container_decl.layout_token) |layout_token| { | 2273 | if (container_decl.layout_token) |layout_token| { |
| 2283 | try renderToken(r, layout_token, .space); | 2274 | try renderToken(r, layout_token, .space); |
| 2284 | } | 2275 | } |
| 2285 | 2276 | ||
| 2286 | const container: Container = switch (token_tags[container_decl.ast.main_token]) { | 2277 | const container: Container = switch (tree.tokenTag(container_decl.ast.main_token)) { |
| 2287 | .keyword_enum => .@"enum", | 2278 | .keyword_enum => .@"enum", |
| 2288 | .keyword_struct => for (container_decl.ast.members) |member| { | 2279 | .keyword_struct => for (container_decl.ast.members) |member| { |
| 2289 | if (tree.fullContainerField(member)) |field| if (!field.ast.tuple_like) break .other; | 2280 | if (tree.fullContainerField(member)) |field| if (!field.ast.tuple_like) break .other; |
| ... | @@ -2296,10 +2287,10 @@ fn renderContainerDecl( | ... | @@ -2296,10 +2287,10 @@ fn renderContainerDecl( |
| 2296 | try renderToken(r, container_decl.ast.main_token, .none); // union | 2287 | try renderToken(r, container_decl.ast.main_token, .none); // union |
| 2297 | try renderToken(r, enum_token - 1, .none); // lparen | 2288 | try renderToken(r, enum_token - 1, .none); // lparen |
| 2298 | try renderToken(r, enum_token, .none); // enum | 2289 | try renderToken(r, enum_token, .none); // enum |
| 2299 | if (container_decl.ast.arg != 0) { | 2290 | if (container_decl.ast.arg.unwrap()) |arg| { |
| 2300 | try renderToken(r, enum_token + 1, .none); // lparen | 2291 | try renderToken(r, enum_token + 1, .none); // lparen |
| 2301 | try renderExpression(r, container_decl.ast.arg, .none); | 2292 | try renderExpression(r, arg, .none); |
| 2302 | const rparen = tree.lastToken(container_decl.ast.arg) + 1; | 2293 | const rparen = tree.lastToken(arg) + 1; |
| 2303 | try renderToken(r, rparen, .none); // rparen | 2294 | try renderToken(r, rparen, .none); // rparen |
| 2304 | try renderToken(r, rparen + 1, .space); // rparen | 2295 | try renderToken(r, rparen + 1, .space); // rparen |
| 2305 | lbrace = rparen + 2; | 2296 | lbrace = rparen + 2; |
| ... | @@ -2307,11 +2298,11 @@ fn renderContainerDecl( | ... | @@ -2307,11 +2298,11 @@ fn renderContainerDecl( |
| 2307 | try renderToken(r, enum_token + 1, .space); // rparen | 2298 | try renderToken(r, enum_token + 1, .space); // rparen |
| 2308 | lbrace = enum_token + 2; | 2299 | lbrace = enum_token + 2; |
| 2309 | } | 2300 | } |
| 2310 | } else if (container_decl.ast.arg != 0) { | 2301 | } else if (container_decl.ast.arg.unwrap()) |arg| { |
| 2311 | try renderToken(r, container_decl.ast.main_token, .none); // union | 2302 | try renderToken(r, container_decl.ast.main_token, .none); // union |
| 2312 | try renderToken(r, container_decl.ast.main_token + 1, .none); // lparen | 2303 | try renderToken(r, container_decl.ast.main_token + 1, .none); // lparen |
| 2313 | try renderExpression(r, container_decl.ast.arg, .none); | 2304 | try renderExpression(r, arg, .none); |
| 2314 | const rparen = tree.lastToken(container_decl.ast.arg) + 1; | 2305 | const rparen = tree.lastToken(arg) + 1; |
| 2315 | try renderToken(r, rparen, .space); // rparen | 2306 | try renderToken(r, rparen, .space); // rparen |
| 2316 | lbrace = rparen + 1; | 2307 | lbrace = rparen + 1; |
| 2317 | } else { | 2308 | } else { |
| ... | @@ -2320,9 +2311,10 @@ fn renderContainerDecl( | ... | @@ -2320,9 +2311,10 @@ fn renderContainerDecl( |
| 2320 | } | 2311 | } |
| 2321 | 2312 | ||
| 2322 | const rbrace = tree.lastToken(container_decl_node); | 2313 | const rbrace = tree.lastToken(container_decl_node); |
| 2314 | |||
| 2323 | if (container_decl.ast.members.len == 0) { | 2315 | if (container_decl.ast.members.len == 0) { |
| 2324 | try ais.pushIndent(.normal); | 2316 | try ais.pushIndent(.normal); |
| 2325 | if (token_tags[lbrace + 1] == .container_doc_comment) { | 2317 | if (tree.tokenTag(lbrace + 1) == .container_doc_comment) { |
| 2326 | try renderToken(r, lbrace, .newline); // lbrace | 2318 | try renderToken(r, lbrace, .newline); // lbrace |
| 2327 | try renderContainerDocComments(r, lbrace + 1); | 2319 | try renderContainerDocComments(r, lbrace + 1); |
| 2328 | } else { | 2320 | } else { |
| ... | @@ -2332,7 +2324,7 @@ fn renderContainerDecl( | ... | @@ -2332,7 +2324,7 @@ fn renderContainerDecl( |
| 2332 | return renderToken(r, rbrace, space); // rbrace | 2324 | return renderToken(r, rbrace, space); // rbrace |
| 2333 | } | 2325 | } |
| 2334 | 2326 | ||
| 2335 | const src_has_trailing_comma = token_tags[rbrace - 1] == .comma; | 2327 | const src_has_trailing_comma = tree.tokenTag(rbrace - 1) == .comma; |
| 2336 | if (!src_has_trailing_comma) one_line: { | 2328 | if (!src_has_trailing_comma) one_line: { |
| 2337 | // We print all the members in-line unless one of the following conditions are true: | 2329 | // We print all the members in-line unless one of the following conditions are true: |
| 2338 | 2330 | ||
| ... | @@ -2342,10 +2334,10 @@ fn renderContainerDecl( | ... | @@ -2342,10 +2334,10 @@ fn renderContainerDecl( |
| 2342 | } | 2334 | } |
| 2343 | 2335 | ||
| 2344 | // 2. The container has a container comment. | 2336 | // 2. The container has a container comment. |
| 2345 | if (token_tags[lbrace + 1] == .container_doc_comment) break :one_line; | 2337 | if (tree.tokenTag(lbrace + 1) == .container_doc_comment) break :one_line; |
| 2346 | 2338 | ||
| 2347 | // 3. A member of the container has a doc comment. | 2339 | // 3. A member of the container has a doc comment. |
| 2348 | for (token_tags[lbrace + 1 .. rbrace - 1]) |tag| { | 2340 | for (tree.tokens.items(.tag)[lbrace + 1 .. rbrace - 1]) |tag| { |
| 2349 | if (tag == .doc_comment) break :one_line; | 2341 | if (tag == .doc_comment) break :one_line; |
| 2350 | } | 2342 | } |
| 2351 | 2343 | ||
| ... | @@ -2365,12 +2357,12 @@ fn renderContainerDecl( | ... | @@ -2365,12 +2357,12 @@ fn renderContainerDecl( |
| 2365 | // One member per line. | 2357 | // One member per line. |
| 2366 | try ais.pushIndent(.normal); | 2358 | try ais.pushIndent(.normal); |
| 2367 | try renderToken(r, lbrace, .newline); // lbrace | 2359 | try renderToken(r, lbrace, .newline); // lbrace |
| 2368 | if (token_tags[lbrace + 1] == .container_doc_comment) { | 2360 | if (tree.tokenTag(lbrace + 1) == .container_doc_comment) { |
| 2369 | try renderContainerDocComments(r, lbrace + 1); | 2361 | try renderContainerDocComments(r, lbrace + 1); |
| 2370 | } | 2362 | } |
| 2371 | for (container_decl.ast.members, 0..) |member, i| { | 2363 | for (container_decl.ast.members, 0..) |member, i| { |
| 2372 | if (i != 0) try renderExtraNewline(r, member); | 2364 | if (i != 0) try renderExtraNewline(r, member); |
| 2373 | switch (tree.nodes.items(.tag)[member]) { | 2365 | switch (tree.nodeTag(member)) { |
| 2374 | // For container fields, ensure a trailing comma is added if necessary. | 2366 | // For container fields, ensure a trailing comma is added if necessary. |
| 2375 | .container_field_init, | 2367 | .container_field_init, |
| 2376 | .container_field_align, | 2368 | .container_field_align, |
| ... | @@ -2396,7 +2388,6 @@ fn renderAsm( | ... | @@ -2396,7 +2388,6 @@ fn renderAsm( |
| 2396 | ) Error!void { | 2388 | ) Error!void { |
| 2397 | const tree = r.tree; | 2389 | const tree = r.tree; |
| 2398 | const ais = r.ais; | 2390 | const ais = r.ais; |
| 2399 | const token_tags = tree.tokens.items(.tag); | ||
| 2400 | 2391 | ||
| 2401 | try renderToken(r, asm_node.ast.asm_token, .space); // asm | 2392 | try renderToken(r, asm_node.ast.asm_token, .space); // asm |
| 2402 | 2393 | ||
| ... | @@ -2422,13 +2413,13 @@ fn renderAsm( | ... | @@ -2422,13 +2413,13 @@ fn renderAsm( |
| 2422 | while (true) : (tok_i += 1) { | 2413 | while (true) : (tok_i += 1) { |
| 2423 | try renderToken(r, tok_i, .none); | 2414 | try renderToken(r, tok_i, .none); |
| 2424 | tok_i += 1; | 2415 | tok_i += 1; |
| 2425 | switch (token_tags[tok_i]) { | 2416 | switch (tree.tokenTag(tok_i)) { |
| 2426 | .r_paren => { | 2417 | .r_paren => { |
| 2427 | ais.popIndent(); | 2418 | ais.popIndent(); |
| 2428 | return renderToken(r, tok_i, space); | 2419 | return renderToken(r, tok_i, space); |
| 2429 | }, | 2420 | }, |
| 2430 | .comma => { | 2421 | .comma => { |
| 2431 | if (token_tags[tok_i + 1] == .r_paren) { | 2422 | if (tree.tokenTag(tok_i + 1) == .r_paren) { |
| 2432 | ais.popIndent(); | 2423 | ais.popIndent(); |
| 2433 | return renderToken(r, tok_i + 1, space); | 2424 | return renderToken(r, tok_i + 1, space); |
| 2434 | } else { | 2425 | } else { |
| ... | @@ -2480,7 +2471,7 @@ fn renderAsm( | ... | @@ -2480,7 +2471,7 @@ fn renderAsm( |
| 2480 | ais.popSpace(); | 2471 | ais.popSpace(); |
| 2481 | const comma_or_colon = tree.lastToken(asm_output) + 1; | 2472 | const comma_or_colon = tree.lastToken(asm_output) + 1; |
| 2482 | ais.popIndent(); | 2473 | ais.popIndent(); |
| 2483 | break :colon2 switch (token_tags[comma_or_colon]) { | 2474 | break :colon2 switch (tree.tokenTag(comma_or_colon)) { |
| 2484 | .comma => comma_or_colon + 1, | 2475 | .comma => comma_or_colon + 1, |
| 2485 | else => comma_or_colon, | 2476 | else => comma_or_colon, |
| 2486 | }; | 2477 | }; |
| ... | @@ -2516,7 +2507,7 @@ fn renderAsm( | ... | @@ -2516,7 +2507,7 @@ fn renderAsm( |
| 2516 | ais.popSpace(); | 2507 | ais.popSpace(); |
| 2517 | const comma_or_colon = tree.lastToken(asm_input) + 1; | 2508 | const comma_or_colon = tree.lastToken(asm_input) + 1; |
| 2518 | ais.popIndent(); | 2509 | ais.popIndent(); |
| 2519 | break :colon3 switch (token_tags[comma_or_colon]) { | 2510 | break :colon3 switch (tree.tokenTag(comma_or_colon)) { |
| 2520 | .comma => comma_or_colon + 1, | 2511 | .comma => comma_or_colon + 1, |
| 2521 | else => comma_or_colon, | 2512 | else => comma_or_colon, |
| 2522 | }; | 2513 | }; |
| ... | @@ -2529,7 +2520,7 @@ fn renderAsm( | ... | @@ -2529,7 +2520,7 @@ fn renderAsm( |
| 2529 | const first_clobber = asm_node.first_clobber.?; | 2520 | const first_clobber = asm_node.first_clobber.?; |
| 2530 | var tok_i = first_clobber; | 2521 | var tok_i = first_clobber; |
| 2531 | while (true) { | 2522 | while (true) { |
| 2532 | switch (token_tags[tok_i + 1]) { | 2523 | switch (tree.tokenTag(tok_i + 1)) { |
| 2533 | .r_paren => { | 2524 | .r_paren => { |
| 2534 | ais.setIndentDelta(indent_delta); | 2525 | ais.setIndentDelta(indent_delta); |
| 2535 | try renderToken(r, tok_i, .newline); | 2526 | try renderToken(r, tok_i, .newline); |
| ... | @@ -2537,7 +2528,7 @@ fn renderAsm( | ... | @@ -2537,7 +2528,7 @@ fn renderAsm( |
| 2537 | return renderToken(r, tok_i + 1, space); | 2528 | return renderToken(r, tok_i + 1, space); |
| 2538 | }, | 2529 | }, |
| 2539 | .comma => { | 2530 | .comma => { |
| 2540 | switch (token_tags[tok_i + 2]) { | 2531 | switch (tree.tokenTag(tok_i + 2)) { |
| 2541 | .r_paren => { | 2532 | .r_paren => { |
| 2542 | ais.setIndentDelta(indent_delta); | 2533 | ais.setIndentDelta(indent_delta); |
| 2543 | try renderToken(r, tok_i, .newline); | 2534 | try renderToken(r, tok_i, .newline); |
| ... | @@ -2576,7 +2567,6 @@ fn renderParamList( | ... | @@ -2576,7 +2567,6 @@ fn renderParamList( |
| 2576 | ) Error!void { | 2567 | ) Error!void { |
| 2577 | const tree = r.tree; | 2568 | const tree = r.tree; |
| 2578 | const ais = r.ais; | 2569 | const ais = r.ais; |
| 2579 | const token_tags = tree.tokens.items(.tag); | ||
| 2580 | 2570 | ||
| 2581 | if (params.len == 0) { | 2571 | if (params.len == 0) { |
| 2582 | try ais.pushIndent(.normal); | 2572 | try ais.pushIndent(.normal); |
| ... | @@ -2587,7 +2577,7 @@ fn renderParamList( | ... | @@ -2587,7 +2577,7 @@ fn renderParamList( |
| 2587 | 2577 | ||
| 2588 | const last_param = params[params.len - 1]; | 2578 | const last_param = params[params.len - 1]; |
| 2589 | const after_last_param_tok = tree.lastToken(last_param) + 1; | 2579 | const after_last_param_tok = tree.lastToken(last_param) + 1; |
| 2590 | if (token_tags[after_last_param_tok] == .comma) { | 2580 | if (tree.tokenTag(after_last_param_tok) == .comma) { |
| 2591 | try ais.pushIndent(.normal); | 2581 | try ais.pushIndent(.normal); |
| 2592 | try renderToken(r, lparen, .newline); // ( | 2582 | try renderToken(r, lparen, .newline); // ( |
| 2593 | for (params, 0..) |param_node, i| { | 2583 | for (params, 0..) |param_node, i| { |
| ... | @@ -2616,7 +2606,7 @@ fn renderParamList( | ... | @@ -2616,7 +2606,7 @@ fn renderParamList( |
| 2616 | if (i + 1 < params.len) { | 2606 | if (i + 1 < params.len) { |
| 2617 | const comma = tree.lastToken(param_node) + 1; | 2607 | const comma = tree.lastToken(param_node) + 1; |
| 2618 | const next_multiline_string = | 2608 | const next_multiline_string = |
| 2619 | token_tags[tree.firstToken(params[i + 1])] == .multiline_string_literal_line; | 2609 | tree.tokenTag(tree.firstToken(params[i + 1])) == .multiline_string_literal_line; |
| 2620 | const comma_space: Space = if (next_multiline_string) .none else .space; | 2610 | const comma_space: Space = if (next_multiline_string) .none else .space; |
| 2621 | try renderToken(r, comma, comma_space); | 2611 | try renderToken(r, comma, comma_space); |
| 2622 | } | 2612 | } |
| ... | @@ -2629,9 +2619,8 @@ fn renderParamList( | ... | @@ -2629,9 +2619,8 @@ fn renderParamList( |
| 2629 | /// If a comma is present, and `space` is `Space.comma`, render only a single comma. | 2619 | /// If a comma is present, and `space` is `Space.comma`, render only a single comma. |
| 2630 | fn renderExpressionComma(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | 2620 | fn renderExpressionComma(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 2631 | const tree = r.tree; | 2621 | const tree = r.tree; |
| 2632 | const token_tags = tree.tokens.items(.tag); | ||
| 2633 | const maybe_comma = tree.lastToken(node) + 1; | 2622 | const maybe_comma = tree.lastToken(node) + 1; |
| 2634 | if (token_tags[maybe_comma] == .comma and space != .comma) { | 2623 | if (tree.tokenTag(maybe_comma) == .comma and space != .comma) { |
| 2635 | try renderExpression(r, node, .none); | 2624 | try renderExpression(r, node, .none); |
| 2636 | return renderToken(r, maybe_comma, space); | 2625 | return renderToken(r, maybe_comma, space); |
| 2637 | } else { | 2626 | } else { |
| ... | @@ -2643,9 +2632,8 @@ fn renderExpressionComma(r: *Render, node: Ast.Node.Index, space: Space) Error!v | ... | @@ -2643,9 +2632,8 @@ fn renderExpressionComma(r: *Render, node: Ast.Node.Index, space: Space) Error!v |
| 2643 | /// If a comma is present, and `space` is `Space.comma`, render only a single comma. | 2632 | /// If a comma is present, and `space` is `Space.comma`, render only a single comma. |
| 2644 | fn renderTokenComma(r: *Render, token: Ast.TokenIndex, space: Space) Error!void { | 2633 | fn renderTokenComma(r: *Render, token: Ast.TokenIndex, space: Space) Error!void { |
| 2645 | const tree = r.tree; | 2634 | const tree = r.tree; |
| 2646 | const token_tags = tree.tokens.items(.tag); | ||
| 2647 | const maybe_comma = token + 1; | 2635 | const maybe_comma = token + 1; |
| 2648 | if (token_tags[maybe_comma] == .comma and space != .comma) { | 2636 | if (tree.tokenTag(maybe_comma) == .comma and space != .comma) { |
| 2649 | try renderToken(r, token, .none); | 2637 | try renderToken(r, token, .none); |
| 2650 | return renderToken(r, maybe_comma, space); | 2638 | return renderToken(r, maybe_comma, space); |
| 2651 | } else { | 2639 | } else { |
| ... | @@ -2657,9 +2645,8 @@ fn renderTokenComma(r: *Render, token: Ast.TokenIndex, space: Space) Error!void | ... | @@ -2657,9 +2645,8 @@ fn renderTokenComma(r: *Render, token: Ast.TokenIndex, space: Space) Error!void |
| 2657 | /// If a comma is present, and `space` is `Space.comma`, render only a single comma. | 2645 | /// If a comma is present, and `space` is `Space.comma`, render only a single comma. |
| 2658 | fn renderIdentifierComma(r: *Render, token: Ast.TokenIndex, space: Space, quote: QuoteBehavior) Error!void { | 2646 | fn renderIdentifierComma(r: *Render, token: Ast.TokenIndex, space: Space, quote: QuoteBehavior) Error!void { |
| 2659 | const tree = r.tree; | 2647 | const tree = r.tree; |
| 2660 | const token_tags = tree.tokens.items(.tag); | ||
| 2661 | const maybe_comma = token + 1; | 2648 | const maybe_comma = token + 1; |
| 2662 | if (token_tags[maybe_comma] == .comma and space != .comma) { | 2649 | if (tree.tokenTag(maybe_comma) == .comma and space != .comma) { |
| 2663 | try renderIdentifier(r, token, .none, quote); | 2650 | try renderIdentifier(r, token, .none, quote); |
| 2664 | return renderToken(r, maybe_comma, space); | 2651 | return renderToken(r, maybe_comma, space); |
| 2665 | } else { | 2652 | } else { |
| ... | @@ -2709,37 +2696,39 @@ fn renderTokenOverrideSpaceMode(r: *Render, token_index: Ast.TokenIndex, space: | ... | @@ -2709,37 +2696,39 @@ fn renderTokenOverrideSpaceMode(r: *Render, token_index: Ast.TokenIndex, space: |
| 2709 | fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space: Space) Error!void { | 2696 | fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space: Space) Error!void { |
| 2710 | const tree = r.tree; | 2697 | const tree = r.tree; |
| 2711 | const ais = r.ais; | 2698 | const ais = r.ais; |
| 2712 | const token_tags = tree.tokens.items(.tag); | ||
| 2713 | const token_starts = tree.tokens.items(.start); | ||
| 2714 | 2699 | ||
| 2715 | const token_start = token_starts[token_index]; | 2700 | const next_token_tag = tree.tokenTag(token_index + 1); |
| 2716 | 2701 | ||
| 2717 | if (space == .skip) return; | 2702 | if (space == .skip) return; |
| 2718 | 2703 | ||
| 2719 | if (space == .comma and token_tags[token_index + 1] != .comma) { | 2704 | if (space == .comma and next_token_tag != .comma) { |
| 2720 | try ais.writer().writeByte(','); | 2705 | try ais.writer().writeByte(','); |
| 2721 | } | 2706 | } |
| 2722 | if (space == .semicolon or space == .comma) ais.enableSpaceMode(space); | 2707 | if (space == .semicolon or space == .comma) ais.enableSpaceMode(space); |
| 2723 | defer ais.disableSpaceMode(); | 2708 | defer ais.disableSpaceMode(); |
| 2724 | const comment = try renderComments(r, token_start + lexeme_len, token_starts[token_index + 1]); | 2709 | const comment = try renderComments( |
| 2710 | r, | ||
| 2711 | tree.tokenStart(token_index) + lexeme_len, | ||
| 2712 | tree.tokenStart(token_index + 1), | ||
| 2713 | ); | ||
| 2725 | switch (space) { | 2714 | switch (space) { |
| 2726 | .none => {}, | 2715 | .none => {}, |
| 2727 | .space => if (!comment) try ais.writer().writeByte(' '), | 2716 | .space => if (!comment) try ais.writer().writeByte(' '), |
| 2728 | .newline => if (!comment) try ais.insertNewline(), | 2717 | .newline => if (!comment) try ais.insertNewline(), |
| 2729 | 2718 | ||
| 2730 | .comma => if (token_tags[token_index + 1] == .comma) { | 2719 | .comma => if (next_token_tag == .comma) { |
| 2731 | try renderToken(r, token_index + 1, .newline); | 2720 | try renderToken(r, token_index + 1, .newline); |
| 2732 | } else if (!comment) { | 2721 | } else if (!comment) { |
| 2733 | try ais.insertNewline(); | 2722 | try ais.insertNewline(); |
| 2734 | }, | 2723 | }, |
| 2735 | 2724 | ||
| 2736 | .comma_space => if (token_tags[token_index + 1] == .comma) { | 2725 | .comma_space => if (next_token_tag == .comma) { |
| 2737 | try renderToken(r, token_index + 1, .space); | 2726 | try renderToken(r, token_index + 1, .space); |
| 2738 | } else if (!comment) { | 2727 | } else if (!comment) { |
| 2739 | try ais.writer().writeByte(' '); | 2728 | try ais.writer().writeByte(' '); |
| 2740 | }, | 2729 | }, |
| 2741 | 2730 | ||
| 2742 | .semicolon => if (token_tags[token_index + 1] == .semicolon) { | 2731 | .semicolon => if (next_token_tag == .semicolon) { |
| 2743 | try renderToken(r, token_index + 1, .newline); | 2732 | try renderToken(r, token_index + 1, .newline); |
| 2744 | } else if (!comment) { | 2733 | } else if (!comment) { |
| 2745 | try ais.insertNewline(); | 2734 | try ais.insertNewline(); |
| ... | @@ -2770,8 +2759,7 @@ const QuoteBehavior = enum { | ... | @@ -2770,8 +2759,7 @@ const QuoteBehavior = enum { |
| 2770 | 2759 | ||
| 2771 | fn renderIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space, quote: QuoteBehavior) Error!void { | 2760 | fn renderIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space, quote: QuoteBehavior) Error!void { |
| 2772 | const tree = r.tree; | 2761 | const tree = r.tree; |
| 2773 | const token_tags = tree.tokens.items(.tag); | 2762 | assert(tree.tokenTag(token_index) == .identifier); |
| 2774 | assert(token_tags[token_index] == .identifier); | ||
| 2775 | const lexeme = tokenSliceForRender(tree, token_index); | 2763 | const lexeme = tokenSliceForRender(tree, token_index); |
| 2776 | 2764 | ||
| 2777 | if (r.fixups.rename_identifiers.get(lexeme)) |mangled| { | 2765 | if (r.fixups.rename_identifiers.get(lexeme)) |mangled| { |
| ... | @@ -2880,8 +2868,7 @@ fn renderIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space, quote | ... | @@ -2880,8 +2868,7 @@ fn renderIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space, quote |
| 2880 | fn renderQuotedIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space, comptime unquote: bool) !void { | 2868 | fn renderQuotedIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space, comptime unquote: bool) !void { |
| 2881 | const tree = r.tree; | 2869 | const tree = r.tree; |
| 2882 | const ais = r.ais; | 2870 | const ais = r.ais; |
| 2883 | const token_tags = tree.tokens.items(.tag); | 2871 | assert(tree.tokenTag(token_index) == .identifier); |
| 2884 | assert(token_tags[token_index] == .identifier); | ||
| 2885 | const lexeme = tokenSliceForRender(tree, token_index); | 2872 | const lexeme = tokenSliceForRender(tree, token_index); |
| 2886 | assert(lexeme.len >= 3 and lexeme[0] == '@'); | 2873 | assert(lexeme.len >= 3 and lexeme[0] == '@'); |
| 2887 | 2874 | ||
| ... | @@ -2934,12 +2921,10 @@ fn renderIdentifierContents(writer: anytype, bytes: []const u8) !void { | ... | @@ -2934,12 +2921,10 @@ fn renderIdentifierContents(writer: anytype, bytes: []const u8) !void { |
| 2934 | /// fn_proto should be wrapped and have a trailing comma inserted even if | 2921 | /// fn_proto should be wrapped and have a trailing comma inserted even if |
| 2935 | /// there is none in the source. | 2922 | /// there is none in the source. |
| 2936 | fn hasComment(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool { | 2923 | fn hasComment(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool { |
| 2937 | const token_starts = tree.tokens.items(.start); | 2924 | for (start_token..end_token) |i| { |
| 2938 | 2925 | const token: Ast.TokenIndex = @intCast(i); | |
| 2939 | var i = start_token; | 2926 | const start = tree.tokenStart(token) + tree.tokenSlice(token).len; |
| 2940 | while (i < end_token) : (i += 1) { | 2927 | const end = tree.tokenStart(token + 1); |
| 2941 | const start = token_starts[i] + tree.tokenSlice(i).len; | ||
| 2942 | const end = token_starts[i + 1]; | ||
| 2943 | if (mem.indexOf(u8, tree.source[start..end], "//") != null) return true; | 2928 | if (mem.indexOf(u8, tree.source[start..end], "//") != null) return true; |
| 2944 | } | 2929 | } |
| 2945 | 2930 | ||
| ... | @@ -2949,16 +2934,11 @@ fn hasComment(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) | ... | @@ -2949,16 +2934,11 @@ fn hasComment(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) |
| 2949 | /// Returns true if there exists a multiline string literal between the start | 2934 | /// Returns true if there exists a multiline string literal between the start |
| 2950 | /// of token `start_token` and the start of token `end_token`. | 2935 | /// of token `start_token` and the start of token `end_token`. |
| 2951 | fn hasMultilineString(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool { | 2936 | fn hasMultilineString(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool { |
| 2952 | const token_tags = tree.tokens.items(.tag); | 2937 | return std.mem.indexOfScalar( |
| 2953 | 2938 | Token.Tag, | |
| 2954 | for (token_tags[start_token..end_token]) |tag| { | 2939 | tree.tokens.items(.tag)[start_token..end_token], |
| 2955 | switch (tag) { | 2940 | .multiline_string_literal_line, |
| 2956 | .multiline_string_literal_line => return true, | 2941 | ) != null; |
| 2957 | else => continue, | ||
| 2958 | } | ||
| 2959 | } | ||
| 2960 | |||
| 2961 | return false; | ||
| 2962 | } | 2942 | } |
| 2963 | 2943 | ||
| 2964 | /// Assumes that start is the first byte past the previous token and | 2944 | /// Assumes that start is the first byte past the previous token and |
| ... | @@ -3034,18 +3014,17 @@ fn renderExtraNewline(r: *Render, node: Ast.Node.Index) Error!void { | ... | @@ -3034,18 +3014,17 @@ fn renderExtraNewline(r: *Render, node: Ast.Node.Index) Error!void { |
| 3034 | fn renderExtraNewlineToken(r: *Render, token_index: Ast.TokenIndex) Error!void { | 3014 | fn renderExtraNewlineToken(r: *Render, token_index: Ast.TokenIndex) Error!void { |
| 3035 | const tree = r.tree; | 3015 | const tree = r.tree; |
| 3036 | const ais = r.ais; | 3016 | const ais = r.ais; |
| 3037 | const token_starts = tree.tokens.items(.start); | 3017 | const token_start = tree.tokenStart(token_index); |
| 3038 | const token_start = token_starts[token_index]; | ||
| 3039 | if (token_start == 0) return; | 3018 | if (token_start == 0) return; |
| 3040 | const prev_token_end = if (token_index == 0) | 3019 | const prev_token_end = if (token_index == 0) |
| 3041 | 0 | 3020 | 0 |
| 3042 | else | 3021 | else |
| 3043 | token_starts[token_index - 1] + tokenSliceForRender(tree, token_index - 1).len; | 3022 | tree.tokenStart(token_index - 1) + tokenSliceForRender(tree, token_index - 1).len; |
| 3044 | 3023 | ||
| 3045 | // If there is a immediately preceding comment or doc_comment, | 3024 | // If there is a immediately preceding comment or doc_comment, |
| 3046 | // skip it because required extra newline has already been rendered. | 3025 | // skip it because required extra newline has already been rendered. |
| 3047 | if (mem.indexOf(u8, tree.source[prev_token_end..token_start], "//") != null) return; | 3026 | if (mem.indexOf(u8, tree.source[prev_token_end..token_start], "//") != null) return; |
| 3048 | if (token_index > 0 and tree.tokens.items(.tag)[token_index - 1] == .doc_comment) return; | 3027 | if (tree.isTokenPrecededByTags(token_index, &.{.doc_comment})) return; |
| 3049 | 3028 | ||
| 3050 | // Iterate backwards to the end of the previous token, stopping if a | 3029 | // Iterate backwards to the end of the previous token, stopping if a |
| 3051 | // non-whitespace character is encountered or two newlines have been found. | 3030 | // non-whitespace character is encountered or two newlines have been found. |
| ... | @@ -3063,10 +3042,9 @@ fn renderExtraNewlineToken(r: *Render, token_index: Ast.TokenIndex) Error!void { | ... | @@ -3063,10 +3042,9 @@ fn renderExtraNewlineToken(r: *Render, token_index: Ast.TokenIndex) Error!void { |
| 3063 | fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void { | 3042 | fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void { |
| 3064 | const tree = r.tree; | 3043 | const tree = r.tree; |
| 3065 | // Search backwards for the first doc comment. | 3044 | // Search backwards for the first doc comment. |
| 3066 | const token_tags = tree.tokens.items(.tag); | ||
| 3067 | if (end_token == 0) return; | 3045 | if (end_token == 0) return; |
| 3068 | var tok = end_token - 1; | 3046 | var tok = end_token - 1; |
| 3069 | while (token_tags[tok] == .doc_comment) { | 3047 | while (tree.tokenTag(tok) == .doc_comment) { |
| 3070 | if (tok == 0) break; | 3048 | if (tok == 0) break; |
| 3071 | tok -= 1; | 3049 | tok -= 1; |
| 3072 | } else { | 3050 | } else { |
| ... | @@ -3076,7 +3054,7 @@ fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void { | ... | @@ -3076,7 +3054,7 @@ fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void { |
| 3076 | if (first_tok == end_token) return; | 3054 | if (first_tok == end_token) return; |
| 3077 | 3055 | ||
| 3078 | if (first_tok != 0) { | 3056 | if (first_tok != 0) { |
| 3079 | const prev_token_tag = token_tags[first_tok - 1]; | 3057 | const prev_token_tag = tree.tokenTag(first_tok - 1); |
| 3080 | 3058 | ||
| 3081 | // Prevent accidental use of `renderDocComments` for a function argument doc comment | 3059 | // Prevent accidental use of `renderDocComments` for a function argument doc comment |
| 3082 | assert(prev_token_tag != .l_paren); | 3060 | assert(prev_token_tag != .l_paren); |
| ... | @@ -3086,7 +3064,7 @@ fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void { | ... | @@ -3086,7 +3064,7 @@ fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void { |
| 3086 | } | 3064 | } |
| 3087 | } | 3065 | } |
| 3088 | 3066 | ||
| 3089 | while (token_tags[tok] == .doc_comment) : (tok += 1) { | 3067 | while (tree.tokenTag(tok) == .doc_comment) : (tok += 1) { |
| 3090 | try renderToken(r, tok, .newline); | 3068 | try renderToken(r, tok, .newline); |
| 3091 | } | 3069 | } |
| 3092 | } | 3070 | } |
| ... | @@ -3094,15 +3072,14 @@ fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void { | ... | @@ -3094,15 +3072,14 @@ fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void { |
| 3094 | /// start_token is first container doc comment token. | 3072 | /// start_token is first container doc comment token. |
| 3095 | fn renderContainerDocComments(r: *Render, start_token: Ast.TokenIndex) Error!void { | 3073 | fn renderContainerDocComments(r: *Render, start_token: Ast.TokenIndex) Error!void { |
| 3096 | const tree = r.tree; | 3074 | const tree = r.tree; |
| 3097 | const token_tags = tree.tokens.items(.tag); | ||
| 3098 | var tok = start_token; | 3075 | var tok = start_token; |
| 3099 | while (token_tags[tok] == .container_doc_comment) : (tok += 1) { | 3076 | while (tree.tokenTag(tok) == .container_doc_comment) : (tok += 1) { |
| 3100 | try renderToken(r, tok, .newline); | 3077 | try renderToken(r, tok, .newline); |
| 3101 | } | 3078 | } |
| 3102 | // Render extra newline if there is one between final container doc comment and | 3079 | // Render extra newline if there is one between final container doc comment and |
| 3103 | // the next token. If the next token is a doc comment, that code path | 3080 | // the next token. If the next token is a doc comment, that code path |
| 3104 | // will have its own logic to insert a newline. | 3081 | // will have its own logic to insert a newline. |
| 3105 | if (token_tags[tok] != .doc_comment) { | 3082 | if (tree.tokenTag(tok) != .doc_comment) { |
| 3106 | try renderExtraNewlineToken(r, tok); | 3083 | try renderExtraNewlineToken(r, tok); |
| 3107 | } | 3084 | } |
| 3108 | } | 3085 | } |
| ... | @@ -3112,11 +3089,10 @@ fn discardAllParams(r: *Render, fn_proto_node: Ast.Node.Index) Error!void { | ... | @@ -3112,11 +3089,10 @@ fn discardAllParams(r: *Render, fn_proto_node: Ast.Node.Index) Error!void { |
| 3112 | const ais = r.ais; | 3089 | const ais = r.ais; |
| 3113 | var buf: [1]Ast.Node.Index = undefined; | 3090 | var buf: [1]Ast.Node.Index = undefined; |
| 3114 | const fn_proto = tree.fullFnProto(&buf, fn_proto_node).?; | 3091 | const fn_proto = tree.fullFnProto(&buf, fn_proto_node).?; |
| 3115 | const token_tags = tree.tokens.items(.tag); | ||
| 3116 | var it = fn_proto.iterate(tree); | 3092 | var it = fn_proto.iterate(tree); |
| 3117 | while (it.next()) |param| { | 3093 | while (it.next()) |param| { |
| 3118 | const name_ident = param.name_token.?; | 3094 | const name_ident = param.name_token.?; |
| 3119 | assert(token_tags[name_ident] == .identifier); | 3095 | assert(tree.tokenTag(name_ident) == .identifier); |
| 3120 | const w = ais.writer(); | 3096 | const w = ais.writer(); |
| 3121 | try w.writeAll("_ = "); | 3097 | try w.writeAll("_ = "); |
| 3122 | try w.writeAll(tokenSliceForRender(r.tree, name_ident)); | 3098 | try w.writeAll(tokenSliceForRender(r.tree, name_ident)); |
| ... | @@ -3126,7 +3102,7 @@ fn discardAllParams(r: *Render, fn_proto_node: Ast.Node.Index) Error!void { | ... | @@ -3126,7 +3102,7 @@ fn discardAllParams(r: *Render, fn_proto_node: Ast.Node.Index) Error!void { |
| 3126 | 3102 | ||
| 3127 | fn tokenSliceForRender(tree: Ast, token_index: Ast.TokenIndex) []const u8 { | 3103 | fn tokenSliceForRender(tree: Ast, token_index: Ast.TokenIndex) []const u8 { |
| 3128 | var ret = tree.tokenSlice(token_index); | 3104 | var ret = tree.tokenSlice(token_index); |
| 3129 | switch (tree.tokens.items(.tag)[token_index]) { | 3105 | switch (tree.tokenTag(token_index)) { |
| 3130 | .container_doc_comment, .doc_comment => { | 3106 | .container_doc_comment, .doc_comment => { |
| 3131 | ret = mem.trimRight(u8, ret, &std.ascii.whitespace); | 3107 | ret = mem.trimRight(u8, ret, &std.ascii.whitespace); |
| 3132 | }, | 3108 | }, |
| ... | @@ -3136,8 +3112,7 @@ fn tokenSliceForRender(tree: Ast, token_index: Ast.TokenIndex) []const u8 { | ... | @@ -3136,8 +3112,7 @@ fn tokenSliceForRender(tree: Ast, token_index: Ast.TokenIndex) []const u8 { |
| 3136 | } | 3112 | } |
| 3137 | 3113 | ||
| 3138 | fn hasSameLineComment(tree: Ast, token_index: Ast.TokenIndex) bool { | 3114 | fn hasSameLineComment(tree: Ast, token_index: Ast.TokenIndex) bool { |
| 3139 | const token_starts = tree.tokens.items(.start); | 3115 | const between_source = tree.source[tree.tokenStart(token_index)..tree.tokenStart(token_index + 1)]; |
| 3140 | const between_source = tree.source[token_starts[token_index]..token_starts[token_index + 1]]; | ||
| 3141 | for (between_source) |byte| switch (byte) { | 3116 | for (between_source) |byte| switch (byte) { |
| 3142 | '\n' => return false, | 3117 | '\n' => return false, |
| 3143 | '/' => return true, | 3118 | '/' => return true, |
| ... | @@ -3150,8 +3125,7 @@ fn hasSameLineComment(tree: Ast, token_index: Ast.TokenIndex) bool { | ... | @@ -3150,8 +3125,7 @@ fn hasSameLineComment(tree: Ast, token_index: Ast.TokenIndex) bool { |
| 3150 | /// start_token and end_token. | 3125 | /// start_token and end_token. |
| 3151 | fn anythingBetween(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool { | 3126 | fn anythingBetween(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool { |
| 3152 | if (start_token + 1 != end_token) return true; | 3127 | if (start_token + 1 != end_token) return true; |
| 3153 | const token_starts = tree.tokens.items(.start); | 3128 | const between_source = tree.source[tree.tokenStart(start_token)..tree.tokenStart(start_token + 1)]; |
| 3154 | const between_source = tree.source[token_starts[start_token]..token_starts[start_token + 1]]; | ||
| 3155 | for (between_source) |byte| switch (byte) { | 3129 | for (between_source) |byte| switch (byte) { |
| 3156 | '/' => return true, | 3130 | '/' => return true, |
| 3157 | else => continue, | 3131 | else => continue, |
| ... | @@ -3245,12 +3219,10 @@ fn nodeCausesSliceOpSpace(tag: Ast.Node.Tag) bool { | ... | @@ -3245,12 +3219,10 @@ fn nodeCausesSliceOpSpace(tag: Ast.Node.Tag) bool { |
| 3245 | 3219 | ||
| 3246 | // Returns the number of nodes in `exprs` that are on the same line as `rtoken`. | 3220 | // Returns the number of nodes in `exprs` that are on the same line as `rtoken`. |
| 3247 | fn rowSize(tree: Ast, exprs: []const Ast.Node.Index, rtoken: Ast.TokenIndex) usize { | 3221 | fn rowSize(tree: Ast, exprs: []const Ast.Node.Index, rtoken: Ast.TokenIndex) usize { |
| 3248 | const token_tags = tree.tokens.items(.tag); | ||
| 3249 | |||
| 3250 | const first_token = tree.firstToken(exprs[0]); | 3222 | const first_token = tree.firstToken(exprs[0]); |
| 3251 | if (tree.tokensOnSameLine(first_token, rtoken)) { | 3223 | if (tree.tokensOnSameLine(first_token, rtoken)) { |
| 3252 | const maybe_comma = rtoken - 1; | 3224 | const maybe_comma = rtoken - 1; |
| 3253 | if (token_tags[maybe_comma] == .comma) | 3225 | if (tree.tokenTag(maybe_comma) == .comma) |
| 3254 | return 1; | 3226 | return 1; |
| 3255 | return exprs.len; // no newlines | 3227 | return exprs.len; // no newlines |
| 3256 | } | 3228 | } |
lib/std/zon/parse.zig+11-17| ... | @@ -196,16 +196,15 @@ pub const Error = union(enum) { | ... | @@ -196,16 +196,15 @@ pub const Error = union(enum) { |
| 196 | return .{ .err = self, .status = status }; | 196 | return .{ .err = self, .status = status }; |
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | fn zoirErrorLocation(ast: Ast, maybe_token: Ast.TokenIndex, node_or_offset: u32) Ast.Location { | 199 | fn zoirErrorLocation(ast: Ast, maybe_token: Ast.OptionalTokenIndex, node_or_offset: u32) Ast.Location { |
| 200 | if (maybe_token == Zoir.CompileError.invalid_token) { | 200 | if (maybe_token.unwrap()) |token| { |
| 201 | const main_tokens = ast.nodes.items(.main_token); | 201 | var location = ast.tokenLocation(0, token); |
| 202 | const ast_node = node_or_offset; | ||
| 203 | const token = main_tokens[ast_node]; | ||
| 204 | return ast.tokenLocation(0, token); | ||
| 205 | } else { | ||
| 206 | var location = ast.tokenLocation(0, maybe_token); | ||
| 207 | location.column += node_or_offset; | 202 | location.column += node_or_offset; |
| 208 | return location; | 203 | return location; |
| 204 | } else { | ||
| 205 | const ast_node: Ast.Node.Index = @enumFromInt(node_or_offset); | ||
| 206 | const token = ast.nodeMainToken(ast_node); | ||
| 207 | return ast.tokenLocation(0, token); | ||
| 209 | } | 208 | } |
| 210 | } | 209 | } |
| 211 | }; | 210 | }; |
| ... | @@ -632,7 +631,7 @@ const Parser = struct { | ... | @@ -632,7 +631,7 @@ const Parser = struct { |
| 632 | switch (try ZonGen.parseStrLit(self.ast, ast_node, buf.writer(self.gpa))) { | 631 | switch (try ZonGen.parseStrLit(self.ast, ast_node, buf.writer(self.gpa))) { |
| 633 | .success => {}, | 632 | .success => {}, |
| 634 | .failure => |err| { | 633 | .failure => |err| { |
| 635 | const token = self.ast.nodes.items(.main_token)[ast_node]; | 634 | const token = self.ast.nodeMainToken(ast_node); |
| 636 | const raw_string = self.ast.tokenSlice(token); | 635 | const raw_string = self.ast.tokenSlice(token); |
| 637 | return self.failTokenFmt(token, @intCast(err.offset()), "{s}", .{err.fmt(raw_string)}); | 636 | return self.failTokenFmt(token, @intCast(err.offset()), "{s}", .{err.fmt(raw_string)}); |
| 638 | }, | 637 | }, |
| ... | @@ -1005,8 +1004,7 @@ const Parser = struct { | ... | @@ -1005,8 +1004,7 @@ const Parser = struct { |
| 1005 | args: anytype, | 1004 | args: anytype, |
| 1006 | ) error{ OutOfMemory, ParseZon } { | 1005 | ) error{ OutOfMemory, ParseZon } { |
| 1007 | @branchHint(.cold); | 1006 | @branchHint(.cold); |
| 1008 | const main_tokens = self.ast.nodes.items(.main_token); | 1007 | const token = self.ast.nodeMainToken(node.getAstNode(self.zoir)); |
| 1009 | const token = main_tokens[node.getAstNode(self.zoir)]; | ||
| 1010 | return self.failTokenFmt(token, 0, fmt, args); | 1008 | return self.failTokenFmt(token, 0, fmt, args); |
| 1011 | } | 1009 | } |
| 1012 | 1010 | ||
| ... | @@ -1025,8 +1023,7 @@ const Parser = struct { | ... | @@ -1025,8 +1023,7 @@ const Parser = struct { |
| 1025 | message: []const u8, | 1023 | message: []const u8, |
| 1026 | ) error{ParseZon} { | 1024 | ) error{ParseZon} { |
| 1027 | @branchHint(.cold); | 1025 | @branchHint(.cold); |
| 1028 | const main_tokens = self.ast.nodes.items(.main_token); | 1026 | const token = self.ast.nodeMainToken(node.getAstNode(self.zoir)); |
| 1029 | const token = main_tokens[node.getAstNode(self.zoir)]; | ||
| 1030 | return self.failToken(.{ | 1027 | return self.failToken(.{ |
| 1031 | .token = token, | 1028 | .token = token, |
| 1032 | .offset = 0, | 1029 | .offset = 0, |
| ... | @@ -1059,10 +1056,7 @@ const Parser = struct { | ... | @@ -1059,10 +1056,7 @@ const Parser = struct { |
| 1059 | const struct_init = self.ast.fullStructInit(&buf, node.getAstNode(self.zoir)).?; | 1056 | const struct_init = self.ast.fullStructInit(&buf, node.getAstNode(self.zoir)).?; |
| 1060 | const field_node = struct_init.ast.fields[f]; | 1057 | const field_node = struct_init.ast.fields[f]; |
| 1061 | break :b self.ast.firstToken(field_node) - 2; | 1058 | break :b self.ast.firstToken(field_node) - 2; |
| 1062 | } else b: { | 1059 | } else self.ast.nodeMainToken(node.getAstNode(self.zoir)); |
| 1063 | const main_tokens = self.ast.nodes.items(.main_token); | ||
| 1064 | break :b main_tokens[node.getAstNode(self.zoir)]; | ||
| 1065 | }; | ||
| 1066 | switch (@typeInfo(T)) { | 1060 | switch (@typeInfo(T)) { |
| 1067 | inline .@"struct", .@"union", .@"enum" => |info| { | 1061 | inline .@"struct", .@"union", .@"enum" => |info| { |
| 1068 | const note: Error.TypeCheckFailure.Note = if (info.fields.len == 0) b: { | 1062 | const note: Error.TypeCheckFailure.Note = if (info.fields.len == 0) b: { |
src/Package/Fetch.zig+10-10| ... | @@ -30,7 +30,7 @@ | ... | @@ -30,7 +30,7 @@ |
| 30 | arena: std.heap.ArenaAllocator, | 30 | arena: std.heap.ArenaAllocator, |
| 31 | location: Location, | 31 | location: Location, |
| 32 | location_tok: std.zig.Ast.TokenIndex, | 32 | location_tok: std.zig.Ast.TokenIndex, |
| 33 | hash_tok: std.zig.Ast.TokenIndex, | 33 | hash_tok: std.zig.Ast.OptionalTokenIndex, |
| 34 | name_tok: std.zig.Ast.TokenIndex, | 34 | name_tok: std.zig.Ast.TokenIndex, |
| 35 | lazy_status: LazyStatus, | 35 | lazy_status: LazyStatus, |
| 36 | parent_package_root: Cache.Path, | 36 | parent_package_root: Cache.Path, |
| ... | @@ -317,8 +317,8 @@ pub fn run(f: *Fetch) RunError!void { | ... | @@ -317,8 +317,8 @@ pub fn run(f: *Fetch) RunError!void { |
| 317 | f.location_tok, | 317 | f.location_tok, |
| 318 | try eb.addString("expected path relative to build root; found absolute path"), | 318 | try eb.addString("expected path relative to build root; found absolute path"), |
| 319 | ); | 319 | ); |
| 320 | if (f.hash_tok != 0) return f.fail( | 320 | if (f.hash_tok.unwrap()) |hash_tok| return f.fail( |
| 321 | f.hash_tok, | 321 | hash_tok, |
| 322 | try eb.addString("path-based dependencies are not hashed"), | 322 | try eb.addString("path-based dependencies are not hashed"), |
| 323 | ); | 323 | ); |
| 324 | // Packages fetched by URL may not use relative paths to escape outside the | 324 | // Packages fetched by URL may not use relative paths to escape outside the |
| ... | @@ -555,17 +555,18 @@ fn runResource( | ... | @@ -555,17 +555,18 @@ fn runResource( |
| 555 | // job is done. | 555 | // job is done. |
| 556 | 556 | ||
| 557 | if (remote_hash) |declared_hash| { | 557 | if (remote_hash) |declared_hash| { |
| 558 | const hash_tok = f.hash_tok.unwrap().?; | ||
| 558 | if (declared_hash.isOld()) { | 559 | if (declared_hash.isOld()) { |
| 559 | const actual_hex = Package.multiHashHexDigest(f.computed_hash.digest); | 560 | const actual_hex = Package.multiHashHexDigest(f.computed_hash.digest); |
| 560 | if (!std.mem.eql(u8, declared_hash.toSlice(), &actual_hex)) { | 561 | if (!std.mem.eql(u8, declared_hash.toSlice(), &actual_hex)) { |
| 561 | return f.fail(f.hash_tok, try eb.printString( | 562 | return f.fail(hash_tok, try eb.printString( |
| 562 | "hash mismatch: manifest declares {s} but the fetched package has {s}", | 563 | "hash mismatch: manifest declares {s} but the fetched package has {s}", |
| 563 | .{ declared_hash.toSlice(), actual_hex }, | 564 | .{ declared_hash.toSlice(), actual_hex }, |
| 564 | )); | 565 | )); |
| 565 | } | 566 | } |
| 566 | } else { | 567 | } else { |
| 567 | if (!computed_package_hash.eql(&declared_hash)) { | 568 | if (!computed_package_hash.eql(&declared_hash)) { |
| 568 | return f.fail(f.hash_tok, try eb.printString( | 569 | return f.fail(hash_tok, try eb.printString( |
| 569 | "hash mismatch: manifest declares {s} but the fetched package has {s}", | 570 | "hash mismatch: manifest declares {s} but the fetched package has {s}", |
| 570 | .{ declared_hash.toSlice(), computed_package_hash.toSlice() }, | 571 | .{ declared_hash.toSlice(), computed_package_hash.toSlice() }, |
| 571 | )); | 572 | )); |
| ... | @@ -813,15 +814,14 @@ fn srcLoc( | ... | @@ -813,15 +814,14 @@ fn srcLoc( |
| 813 | ) Allocator.Error!ErrorBundle.SourceLocationIndex { | 814 | ) Allocator.Error!ErrorBundle.SourceLocationIndex { |
| 814 | const ast = f.parent_manifest_ast orelse return .none; | 815 | const ast = f.parent_manifest_ast orelse return .none; |
| 815 | const eb = &f.error_bundle; | 816 | const eb = &f.error_bundle; |
| 816 | const token_starts = ast.tokens.items(.start); | ||
| 817 | const start_loc = ast.tokenLocation(0, tok); | 817 | const start_loc = ast.tokenLocation(0, tok); |
| 818 | const src_path = try eb.printString("{}" ++ fs.path.sep_str ++ Manifest.basename, .{f.parent_package_root}); | 818 | const src_path = try eb.printString("{}" ++ fs.path.sep_str ++ Manifest.basename, .{f.parent_package_root}); |
| 819 | const msg_off = 0; | 819 | const msg_off = 0; |
| 820 | return eb.addSourceLocation(.{ | 820 | return eb.addSourceLocation(.{ |
| 821 | .src_path = src_path, | 821 | .src_path = src_path, |
| 822 | .span_start = token_starts[tok], | 822 | .span_start = ast.tokenStart(tok), |
| 823 | .span_end = @intCast(token_starts[tok] + ast.tokenSlice(tok).len), | 823 | .span_end = @intCast(ast.tokenStart(tok) + ast.tokenSlice(tok).len), |
| 824 | .span_main = token_starts[tok] + msg_off, | 824 | .span_main = ast.tokenStart(tok) + msg_off, |
| 825 | .line = @intCast(start_loc.line), | 825 | .line = @intCast(start_loc.line), |
| 826 | .column = @intCast(start_loc.column), | 826 | .column = @intCast(start_loc.column), |
| 827 | .source_line = try eb.addString(ast.source[start_loc.line_start..start_loc.line_end]), | 827 | .source_line = try eb.addString(ast.source[start_loc.line_start..start_loc.line_end]), |
| ... | @@ -2322,7 +2322,7 @@ const TestFetchBuilder = struct { | ... | @@ -2322,7 +2322,7 @@ const TestFetchBuilder = struct { |
| 2322 | .arena = std.heap.ArenaAllocator.init(allocator), | 2322 | .arena = std.heap.ArenaAllocator.init(allocator), |
| 2323 | .location = .{ .path_or_url = path_or_url }, | 2323 | .location = .{ .path_or_url = path_or_url }, |
| 2324 | .location_tok = 0, | 2324 | .location_tok = 0, |
| 2325 | .hash_tok = 0, | 2325 | .hash_tok = .none, |
| 2326 | .name_tok = 0, | 2326 | .name_tok = 0, |
| 2327 | .lazy_status = .eager, | 2327 | .lazy_status = .eager, |
| 2328 | .parent_package_root = Cache.Path{ .root_dir = Cache.Directory{ .handle = cache_dir, .path = null } }, | 2328 | .parent_package_root = Cache.Path{ .root_dir = Cache.Directory{ .handle = cache_dir, .path = null } }, |
src/Package/Manifest.zig+42-61| ... | @@ -17,8 +17,8 @@ pub const Dependency = struct { | ... | @@ -17,8 +17,8 @@ pub const Dependency = struct { |
| 17 | location_tok: Ast.TokenIndex, | 17 | location_tok: Ast.TokenIndex, |
| 18 | location_node: Ast.Node.Index, | 18 | location_node: Ast.Node.Index, |
| 19 | hash: ?[]const u8, | 19 | hash: ?[]const u8, |
| 20 | hash_tok: Ast.TokenIndex, | 20 | hash_tok: Ast.OptionalTokenIndex, |
| 21 | hash_node: Ast.Node.Index, | 21 | hash_node: Ast.Node.OptionalIndex, |
| 22 | node: Ast.Node.Index, | 22 | node: Ast.Node.Index, |
| 23 | name_tok: Ast.TokenIndex, | 23 | name_tok: Ast.TokenIndex, |
| 24 | lazy: bool, | 24 | lazy: bool, |
| ... | @@ -40,7 +40,7 @@ id: u32, | ... | @@ -40,7 +40,7 @@ id: u32, |
| 40 | version: std.SemanticVersion, | 40 | version: std.SemanticVersion, |
| 41 | version_node: Ast.Node.Index, | 41 | version_node: Ast.Node.Index, |
| 42 | dependencies: std.StringArrayHashMapUnmanaged(Dependency), | 42 | dependencies: std.StringArrayHashMapUnmanaged(Dependency), |
| 43 | dependencies_node: Ast.Node.Index, | 43 | dependencies_node: Ast.Node.OptionalIndex, |
| 44 | paths: std.StringArrayHashMapUnmanaged(void), | 44 | paths: std.StringArrayHashMapUnmanaged(void), |
| 45 | minimum_zig_version: ?std.SemanticVersion, | 45 | minimum_zig_version: ?std.SemanticVersion, |
| 46 | 46 | ||
| ... | @@ -58,10 +58,7 @@ pub const ParseOptions = struct { | ... | @@ -58,10 +58,7 @@ pub const ParseOptions = struct { |
| 58 | pub const Error = Allocator.Error; | 58 | pub const Error = Allocator.Error; |
| 59 | 59 | ||
| 60 | pub fn parse(gpa: Allocator, ast: Ast, options: ParseOptions) Error!Manifest { | 60 | pub fn parse(gpa: Allocator, ast: Ast, options: ParseOptions) Error!Manifest { |
| 61 | const node_tags = ast.nodes.items(.tag); | 61 | const main_node_index = ast.nodeData(.root).node; |
| 62 | const node_datas = ast.nodes.items(.data); | ||
| 63 | assert(node_tags[0] == .root); | ||
| 64 | const main_node_index = node_datas[0].lhs; | ||
| 65 | 62 | ||
| 66 | var arena_instance = std.heap.ArenaAllocator.init(gpa); | 63 | var arena_instance = std.heap.ArenaAllocator.init(gpa); |
| 67 | errdefer arena_instance.deinit(); | 64 | errdefer arena_instance.deinit(); |
| ... | @@ -75,9 +72,9 @@ pub fn parse(gpa: Allocator, ast: Ast, options: ParseOptions) Error!Manifest { | ... | @@ -75,9 +72,9 @@ pub fn parse(gpa: Allocator, ast: Ast, options: ParseOptions) Error!Manifest { |
| 75 | .name = undefined, | 72 | .name = undefined, |
| 76 | .id = 0, | 73 | .id = 0, |
| 77 | .version = undefined, | 74 | .version = undefined, |
| 78 | .version_node = 0, | 75 | .version_node = undefined, |
| 79 | .dependencies = .{}, | 76 | .dependencies = .{}, |
| 80 | .dependencies_node = 0, | 77 | .dependencies_node = .none, |
| 81 | .paths = .{}, | 78 | .paths = .{}, |
| 82 | .allow_missing_paths_field = options.allow_missing_paths_field, | 79 | .allow_missing_paths_field = options.allow_missing_paths_field, |
| 83 | .allow_name_string = options.allow_name_string, | 80 | .allow_name_string = options.allow_name_string, |
| ... | @@ -121,8 +118,6 @@ pub fn copyErrorsIntoBundle( | ... | @@ -121,8 +118,6 @@ pub fn copyErrorsIntoBundle( |
| 121 | src_path: u32, | 118 | src_path: u32, |
| 122 | eb: *std.zig.ErrorBundle.Wip, | 119 | eb: *std.zig.ErrorBundle.Wip, |
| 123 | ) Allocator.Error!void { | 120 | ) Allocator.Error!void { |
| 124 | const token_starts = ast.tokens.items(.start); | ||
| 125 | |||
| 126 | for (man.errors) |msg| { | 121 | for (man.errors) |msg| { |
| 127 | const start_loc = ast.tokenLocation(0, msg.tok); | 122 | const start_loc = ast.tokenLocation(0, msg.tok); |
| 128 | 123 | ||
| ... | @@ -130,9 +125,9 @@ pub fn copyErrorsIntoBundle( | ... | @@ -130,9 +125,9 @@ pub fn copyErrorsIntoBundle( |
| 130 | .msg = try eb.addString(msg.msg), | 125 | .msg = try eb.addString(msg.msg), |
| 131 | .src_loc = try eb.addSourceLocation(.{ | 126 | .src_loc = try eb.addSourceLocation(.{ |
| 132 | .src_path = src_path, | 127 | .src_path = src_path, |
| 133 | .span_start = token_starts[msg.tok], | 128 | .span_start = ast.tokenStart(msg.tok), |
| 134 | .span_end = @intCast(token_starts[msg.tok] + ast.tokenSlice(msg.tok).len), | 129 | .span_end = @intCast(ast.tokenStart(msg.tok) + ast.tokenSlice(msg.tok).len), |
| 135 | .span_main = token_starts[msg.tok] + msg.off, | 130 | .span_main = ast.tokenStart(msg.tok) + msg.off, |
| 136 | .line = @intCast(start_loc.line), | 131 | .line = @intCast(start_loc.line), |
| 137 | .column = @intCast(start_loc.column), | 132 | .column = @intCast(start_loc.column), |
| 138 | .source_line = try eb.addString(ast.source[start_loc.line_start..start_loc.line_end]), | 133 | .source_line = try eb.addString(ast.source[start_loc.line_start..start_loc.line_end]), |
| ... | @@ -153,7 +148,7 @@ const Parse = struct { | ... | @@ -153,7 +148,7 @@ const Parse = struct { |
| 153 | version: std.SemanticVersion, | 148 | version: std.SemanticVersion, |
| 154 | version_node: Ast.Node.Index, | 149 | version_node: Ast.Node.Index, |
| 155 | dependencies: std.StringArrayHashMapUnmanaged(Dependency), | 150 | dependencies: std.StringArrayHashMapUnmanaged(Dependency), |
| 156 | dependencies_node: Ast.Node.Index, | 151 | dependencies_node: Ast.Node.OptionalIndex, |
| 157 | paths: std.StringArrayHashMapUnmanaged(void), | 152 | paths: std.StringArrayHashMapUnmanaged(void), |
| 158 | allow_missing_paths_field: bool, | 153 | allow_missing_paths_field: bool, |
| 159 | allow_name_string: bool, | 154 | allow_name_string: bool, |
| ... | @@ -164,8 +159,7 @@ const Parse = struct { | ... | @@ -164,8 +159,7 @@ const Parse = struct { |
| 164 | 159 | ||
| 165 | fn parseRoot(p: *Parse, node: Ast.Node.Index) !void { | 160 | fn parseRoot(p: *Parse, node: Ast.Node.Index) !void { |
| 166 | const ast = p.ast; | 161 | const ast = p.ast; |
| 167 | const main_tokens = ast.nodes.items(.main_token); | 162 | const main_token = ast.nodeMainToken(node); |
| 168 | const main_token = main_tokens[node]; | ||
| 169 | 163 | ||
| 170 | var buf: [2]Ast.Node.Index = undefined; | 164 | var buf: [2]Ast.Node.Index = undefined; |
| 171 | const struct_init = ast.fullStructInit(&buf, node) orelse { | 165 | const struct_init = ast.fullStructInit(&buf, node) orelse { |
| ... | @@ -184,7 +178,7 @@ const Parse = struct { | ... | @@ -184,7 +178,7 @@ const Parse = struct { |
| 184 | // things manually provides an opportunity to do any additional verification | 178 | // things manually provides an opportunity to do any additional verification |
| 185 | // that is desirable on a per-field basis. | 179 | // that is desirable on a per-field basis. |
| 186 | if (mem.eql(u8, field_name, "dependencies")) { | 180 | if (mem.eql(u8, field_name, "dependencies")) { |
| 187 | p.dependencies_node = field_init; | 181 | p.dependencies_node = field_init.toOptional(); |
| 188 | try parseDependencies(p, field_init); | 182 | try parseDependencies(p, field_init); |
| 189 | } else if (mem.eql(u8, field_name, "paths")) { | 183 | } else if (mem.eql(u8, field_name, "paths")) { |
| 190 | have_included_paths = true; | 184 | have_included_paths = true; |
| ... | @@ -198,17 +192,17 @@ const Parse = struct { | ... | @@ -198,17 +192,17 @@ const Parse = struct { |
| 198 | p.version_node = field_init; | 192 | p.version_node = field_init; |
| 199 | const version_text = try parseString(p, field_init); | 193 | const version_text = try parseString(p, field_init); |
| 200 | if (version_text.len > max_version_len) { | 194 | if (version_text.len > max_version_len) { |
| 201 | try appendError(p, main_tokens[field_init], "version string length {d} exceeds maximum of {d}", .{ version_text.len, max_version_len }); | 195 | try appendError(p, ast.nodeMainToken(field_init), "version string length {d} exceeds maximum of {d}", .{ version_text.len, max_version_len }); |
| 202 | } | 196 | } |
| 203 | p.version = std.SemanticVersion.parse(version_text) catch |err| v: { | 197 | p.version = std.SemanticVersion.parse(version_text) catch |err| v: { |
| 204 | try appendError(p, main_tokens[field_init], "unable to parse semantic version: {s}", .{@errorName(err)}); | 198 | try appendError(p, ast.nodeMainToken(field_init), "unable to parse semantic version: {s}", .{@errorName(err)}); |
| 205 | break :v undefined; | 199 | break :v undefined; |
| 206 | }; | 200 | }; |
| 207 | have_version = true; | 201 | have_version = true; |
| 208 | } else if (mem.eql(u8, field_name, "minimum_zig_version")) { | 202 | } else if (mem.eql(u8, field_name, "minimum_zig_version")) { |
| 209 | const version_text = try parseString(p, field_init); | 203 | const version_text = try parseString(p, field_init); |
| 210 | p.minimum_zig_version = std.SemanticVersion.parse(version_text) catch |err| v: { | 204 | p.minimum_zig_version = std.SemanticVersion.parse(version_text) catch |err| v: { |
| 211 | try appendError(p, main_tokens[field_init], "unable to parse semantic version: {s}", .{@errorName(err)}); | 205 | try appendError(p, ast.nodeMainToken(field_init), "unable to parse semantic version: {s}", .{@errorName(err)}); |
| 212 | break :v null; | 206 | break :v null; |
| 213 | }; | 207 | }; |
| 214 | } else { | 208 | } else { |
| ... | @@ -251,11 +245,10 @@ const Parse = struct { | ... | @@ -251,11 +245,10 @@ const Parse = struct { |
| 251 | 245 | ||
| 252 | fn parseDependencies(p: *Parse, node: Ast.Node.Index) !void { | 246 | fn parseDependencies(p: *Parse, node: Ast.Node.Index) !void { |
| 253 | const ast = p.ast; | 247 | const ast = p.ast; |
| 254 | const main_tokens = ast.nodes.items(.main_token); | ||
| 255 | 248 | ||
| 256 | var buf: [2]Ast.Node.Index = undefined; | 249 | var buf: [2]Ast.Node.Index = undefined; |
| 257 | const struct_init = ast.fullStructInit(&buf, node) orelse { | 250 | const struct_init = ast.fullStructInit(&buf, node) orelse { |
| 258 | const tok = main_tokens[node]; | 251 | const tok = ast.nodeMainToken(node); |
| 259 | return fail(p, tok, "expected dependencies expression to be a struct", .{}); | 252 | return fail(p, tok, "expected dependencies expression to be a struct", .{}); |
| 260 | }; | 253 | }; |
| 261 | 254 | ||
| ... | @@ -269,23 +262,22 @@ const Parse = struct { | ... | @@ -269,23 +262,22 @@ const Parse = struct { |
| 269 | 262 | ||
| 270 | fn parseDependency(p: *Parse, node: Ast.Node.Index) !Dependency { | 263 | fn parseDependency(p: *Parse, node: Ast.Node.Index) !Dependency { |
| 271 | const ast = p.ast; | 264 | const ast = p.ast; |
| 272 | const main_tokens = ast.nodes.items(.main_token); | ||
| 273 | 265 | ||
| 274 | var buf: [2]Ast.Node.Index = undefined; | 266 | var buf: [2]Ast.Node.Index = undefined; |
| 275 | const struct_init = ast.fullStructInit(&buf, node) orelse { | 267 | const struct_init = ast.fullStructInit(&buf, node) orelse { |
| 276 | const tok = main_tokens[node]; | 268 | const tok = ast.nodeMainToken(node); |
| 277 | return fail(p, tok, "expected dependency expression to be a struct", .{}); | 269 | return fail(p, tok, "expected dependency expression to be a struct", .{}); |
| 278 | }; | 270 | }; |
| 279 | 271 | ||
| 280 | var dep: Dependency = .{ | 272 | var dep: Dependency = .{ |
| 281 | .location = undefined, | 273 | .location = undefined, |
| 282 | .location_tok = 0, | 274 | .location_tok = undefined, |
| 283 | .location_node = undefined, | 275 | .location_node = undefined, |
| 284 | .hash = null, | 276 | .hash = null, |
| 285 | .hash_tok = 0, | 277 | .hash_tok = .none, |
| 286 | .hash_node = undefined, | 278 | .hash_node = .none, |
| 287 | .node = node, | 279 | .node = node, |
| 288 | .name_tok = 0, | 280 | .name_tok = undefined, |
| 289 | .lazy = false, | 281 | .lazy = false, |
| 290 | }; | 282 | }; |
| 291 | var has_location = false; | 283 | var has_location = false; |
| ... | @@ -299,7 +291,7 @@ const Parse = struct { | ... | @@ -299,7 +291,7 @@ const Parse = struct { |
| 299 | // that is desirable on a per-field basis. | 291 | // that is desirable on a per-field basis. |
| 300 | if (mem.eql(u8, field_name, "url")) { | 292 | if (mem.eql(u8, field_name, "url")) { |
| 301 | if (has_location) { | 293 | if (has_location) { |
| 302 | return fail(p, main_tokens[field_init], "dependency should specify only one of 'url' and 'path' fields.", .{}); | 294 | return fail(p, ast.nodeMainToken(field_init), "dependency should specify only one of 'url' and 'path' fields.", .{}); |
| 303 | } | 295 | } |
| 304 | dep.location = .{ | 296 | dep.location = .{ |
| 305 | .url = parseString(p, field_init) catch |err| switch (err) { | 297 | .url = parseString(p, field_init) catch |err| switch (err) { |
| ... | @@ -308,11 +300,11 @@ const Parse = struct { | ... | @@ -308,11 +300,11 @@ const Parse = struct { |
| 308 | }, | 300 | }, |
| 309 | }; | 301 | }; |
| 310 | has_location = true; | 302 | has_location = true; |
| 311 | dep.location_tok = main_tokens[field_init]; | 303 | dep.location_tok = ast.nodeMainToken(field_init); |
| 312 | dep.location_node = field_init; | 304 | dep.location_node = field_init; |
| 313 | } else if (mem.eql(u8, field_name, "path")) { | 305 | } else if (mem.eql(u8, field_name, "path")) { |
| 314 | if (has_location) { | 306 | if (has_location) { |
| 315 | return fail(p, main_tokens[field_init], "dependency should specify only one of 'url' and 'path' fields.", .{}); | 307 | return fail(p, ast.nodeMainToken(field_init), "dependency should specify only one of 'url' and 'path' fields.", .{}); |
| 316 | } | 308 | } |
| 317 | dep.location = .{ | 309 | dep.location = .{ |
| 318 | .path = parseString(p, field_init) catch |err| switch (err) { | 310 | .path = parseString(p, field_init) catch |err| switch (err) { |
| ... | @@ -321,15 +313,15 @@ const Parse = struct { | ... | @@ -321,15 +313,15 @@ const Parse = struct { |
| 321 | }, | 313 | }, |
| 322 | }; | 314 | }; |
| 323 | has_location = true; | 315 | has_location = true; |
| 324 | dep.location_tok = main_tokens[field_init]; | 316 | dep.location_tok = ast.nodeMainToken(field_init); |
| 325 | dep.location_node = field_init; | 317 | dep.location_node = field_init; |
| 326 | } else if (mem.eql(u8, field_name, "hash")) { | 318 | } else if (mem.eql(u8, field_name, "hash")) { |
| 327 | dep.hash = parseHash(p, field_init) catch |err| switch (err) { | 319 | dep.hash = parseHash(p, field_init) catch |err| switch (err) { |
| 328 | error.ParseFailure => continue, | 320 | error.ParseFailure => continue, |
| 329 | else => |e| return e, | 321 | else => |e| return e, |
| 330 | }; | 322 | }; |
| 331 | dep.hash_tok = main_tokens[field_init]; | 323 | dep.hash_tok = .fromToken(ast.nodeMainToken(field_init)); |
| 332 | dep.hash_node = field_init; | 324 | dep.hash_node = field_init.toOptional(); |
| 333 | } else if (mem.eql(u8, field_name, "lazy")) { | 325 | } else if (mem.eql(u8, field_name, "lazy")) { |
| 334 | dep.lazy = parseBool(p, field_init) catch |err| switch (err) { | 326 | dep.lazy = parseBool(p, field_init) catch |err| switch (err) { |
| 335 | error.ParseFailure => continue, | 327 | error.ParseFailure => continue, |
| ... | @@ -342,7 +334,7 @@ const Parse = struct { | ... | @@ -342,7 +334,7 @@ const Parse = struct { |
| 342 | } | 334 | } |
| 343 | 335 | ||
| 344 | if (!has_location) { | 336 | if (!has_location) { |
| 345 | try appendError(p, main_tokens[node], "dependency requires location field, one of 'url' or 'path'.", .{}); | 337 | try appendError(p, ast.nodeMainToken(node), "dependency requires location field, one of 'url' or 'path'.", .{}); |
| 346 | } | 338 | } |
| 347 | 339 | ||
| 348 | return dep; | 340 | return dep; |
| ... | @@ -350,11 +342,10 @@ const Parse = struct { | ... | @@ -350,11 +342,10 @@ const Parse = struct { |
| 350 | 342 | ||
| 351 | fn parseIncludedPaths(p: *Parse, node: Ast.Node.Index) !void { | 343 | fn parseIncludedPaths(p: *Parse, node: Ast.Node.Index) !void { |
| 352 | const ast = p.ast; | 344 | const ast = p.ast; |
| 353 | const main_tokens = ast.nodes.items(.main_token); | ||
| 354 | 345 | ||
| 355 | var buf: [2]Ast.Node.Index = undefined; | 346 | var buf: [2]Ast.Node.Index = undefined; |
| 356 | const array_init = ast.fullArrayInit(&buf, node) orelse { | 347 | const array_init = ast.fullArrayInit(&buf, node) orelse { |
| 357 | const tok = main_tokens[node]; | 348 | const tok = ast.nodeMainToken(node); |
| 358 | return fail(p, tok, "expected paths expression to be a list of strings", .{}); | 349 | return fail(p, tok, "expected paths expression to be a list of strings", .{}); |
| 359 | }; | 350 | }; |
| 360 | 351 | ||
| ... | @@ -369,12 +360,10 @@ const Parse = struct { | ... | @@ -369,12 +360,10 @@ const Parse = struct { |
| 369 | 360 | ||
| 370 | fn parseBool(p: *Parse, node: Ast.Node.Index) !bool { | 361 | fn parseBool(p: *Parse, node: Ast.Node.Index) !bool { |
| 371 | const ast = p.ast; | 362 | const ast = p.ast; |
| 372 | const node_tags = ast.nodes.items(.tag); | 363 | if (ast.nodeTag(node) != .identifier) { |
| 373 | const main_tokens = ast.nodes.items(.main_token); | 364 | return fail(p, ast.nodeMainToken(node), "expected identifier", .{}); |
| 374 | if (node_tags[node] != .identifier) { | ||
| 375 | return fail(p, main_tokens[node], "expected identifier", .{}); | ||
| 376 | } | 365 | } |
| 377 | const ident_token = main_tokens[node]; | 366 | const ident_token = ast.nodeMainToken(node); |
| 378 | const token_bytes = ast.tokenSlice(ident_token); | 367 | const token_bytes = ast.tokenSlice(ident_token); |
| 379 | if (mem.eql(u8, token_bytes, "true")) { | 368 | if (mem.eql(u8, token_bytes, "true")) { |
| 380 | return true; | 369 | return true; |
| ... | @@ -387,10 +376,8 @@ const Parse = struct { | ... | @@ -387,10 +376,8 @@ const Parse = struct { |
| 387 | 376 | ||
| 388 | fn parseFingerprint(p: *Parse, node: Ast.Node.Index) !Package.Fingerprint { | 377 | fn parseFingerprint(p: *Parse, node: Ast.Node.Index) !Package.Fingerprint { |
| 389 | const ast = p.ast; | 378 | const ast = p.ast; |
| 390 | const node_tags = ast.nodes.items(.tag); | 379 | const main_token = ast.nodeMainToken(node); |
| 391 | const main_tokens = ast.nodes.items(.main_token); | 380 | if (ast.nodeTag(node) != .number_literal) { |
| 392 | const main_token = main_tokens[node]; | ||
| 393 | if (node_tags[node] != .number_literal) { | ||
| 394 | return fail(p, main_token, "expected integer literal", .{}); | 381 | return fail(p, main_token, "expected integer literal", .{}); |
| 395 | } | 382 | } |
| 396 | const token_bytes = ast.tokenSlice(main_token); | 383 | const token_bytes = ast.tokenSlice(main_token); |
| ... | @@ -406,11 +393,9 @@ const Parse = struct { | ... | @@ -406,11 +393,9 @@ const Parse = struct { |
| 406 | 393 | ||
| 407 | fn parseName(p: *Parse, node: Ast.Node.Index) ![]const u8 { | 394 | fn parseName(p: *Parse, node: Ast.Node.Index) ![]const u8 { |
| 408 | const ast = p.ast; | 395 | const ast = p.ast; |
| 409 | const node_tags = ast.nodes.items(.tag); | 396 | const main_token = ast.nodeMainToken(node); |
| 410 | const main_tokens = ast.nodes.items(.main_token); | ||
| 411 | const main_token = main_tokens[node]; | ||
| 412 | 397 | ||
| 413 | if (p.allow_name_string and node_tags[node] == .string_literal) { | 398 | if (p.allow_name_string and ast.nodeTag(node) == .string_literal) { |
| 414 | const name = try parseString(p, node); | 399 | const name = try parseString(p, node); |
| 415 | if (!std.zig.isValidId(name)) | 400 | if (!std.zig.isValidId(name)) |
| 416 | return fail(p, main_token, "name must be a valid bare zig identifier (hint: switch from string to enum literal)", .{}); | 401 | return fail(p, main_token, "name must be a valid bare zig identifier (hint: switch from string to enum literal)", .{}); |
| ... | @@ -423,7 +408,7 @@ const Parse = struct { | ... | @@ -423,7 +408,7 @@ const Parse = struct { |
| 423 | return name; | 408 | return name; |
| 424 | } | 409 | } |
| 425 | 410 | ||
| 426 | if (node_tags[node] != .enum_literal) | 411 | if (ast.nodeTag(node) != .enum_literal) |
| 427 | return fail(p, main_token, "expected enum literal", .{}); | 412 | return fail(p, main_token, "expected enum literal", .{}); |
| 428 | 413 | ||
| 429 | const ident_name = ast.tokenSlice(main_token); | 414 | const ident_name = ast.tokenSlice(main_token); |
| ... | @@ -440,12 +425,10 @@ const Parse = struct { | ... | @@ -440,12 +425,10 @@ const Parse = struct { |
| 440 | 425 | ||
| 441 | fn parseString(p: *Parse, node: Ast.Node.Index) ![]const u8 { | 426 | fn parseString(p: *Parse, node: Ast.Node.Index) ![]const u8 { |
| 442 | const ast = p.ast; | 427 | const ast = p.ast; |
| 443 | const node_tags = ast.nodes.items(.tag); | 428 | if (ast.nodeTag(node) != .string_literal) { |
| 444 | const main_tokens = ast.nodes.items(.main_token); | 429 | return fail(p, ast.nodeMainToken(node), "expected string literal", .{}); |
| 445 | if (node_tags[node] != .string_literal) { | ||
| 446 | return fail(p, main_tokens[node], "expected string literal", .{}); | ||
| 447 | } | 430 | } |
| 448 | const str_lit_token = main_tokens[node]; | 431 | const str_lit_token = ast.nodeMainToken(node); |
| 449 | const token_bytes = ast.tokenSlice(str_lit_token); | 432 | const token_bytes = ast.tokenSlice(str_lit_token); |
| 450 | p.buf.clearRetainingCapacity(); | 433 | p.buf.clearRetainingCapacity(); |
| 451 | try parseStrLit(p, str_lit_token, &p.buf, token_bytes, 0); | 434 | try parseStrLit(p, str_lit_token, &p.buf, token_bytes, 0); |
| ... | @@ -455,8 +438,7 @@ const Parse = struct { | ... | @@ -455,8 +438,7 @@ const Parse = struct { |
| 455 | 438 | ||
| 456 | fn parseHash(p: *Parse, node: Ast.Node.Index) ![]const u8 { | 439 | fn parseHash(p: *Parse, node: Ast.Node.Index) ![]const u8 { |
| 457 | const ast = p.ast; | 440 | const ast = p.ast; |
| 458 | const main_tokens = ast.nodes.items(.main_token); | 441 | const tok = ast.nodeMainToken(node); |
| 459 | const tok = main_tokens[node]; | ||
| 460 | const h = try parseString(p, node); | 442 | const h = try parseString(p, node); |
| 461 | 443 | ||
| 462 | if (h.len > Package.Hash.max_len) { | 444 | if (h.len > Package.Hash.max_len) { |
| ... | @@ -469,8 +451,7 @@ const Parse = struct { | ... | @@ -469,8 +451,7 @@ const Parse = struct { |
| 469 | /// TODO: try to DRY this with AstGen.identifierTokenString | 451 | /// TODO: try to DRY this with AstGen.identifierTokenString |
| 470 | fn identifierTokenString(p: *Parse, token: Ast.TokenIndex) InnerError![]const u8 { | 452 | fn identifierTokenString(p: *Parse, token: Ast.TokenIndex) InnerError![]const u8 { |
| 471 | const ast = p.ast; | 453 | const ast = p.ast; |
| 472 | const token_tags = ast.tokens.items(.tag); | 454 | assert(ast.tokenTag(token) == .identifier); |
| 473 | assert(token_tags[token] == .identifier); | ||
| 474 | const ident_name = ast.tokenSlice(token); | 455 | const ident_name = ast.tokenSlice(token); |
| 475 | if (!mem.startsWith(u8, ident_name, "@")) { | 456 | if (!mem.startsWith(u8, ident_name, "@")) { |
| 476 | return ident_name; | 457 | return ident_name; |
src/Sema.zig+110-87| ... | @@ -407,18 +407,18 @@ pub const Block = struct { | ... | @@ -407,18 +407,18 @@ pub const Block = struct { |
| 407 | return block.comptime_reason != null; | 407 | return block.comptime_reason != null; |
| 408 | } | 408 | } |
| 409 | 409 | ||
| 410 | fn builtinCallArgSrc(block: *Block, builtin_call_node: i32, arg_index: u32) LazySrcLoc { | 410 | fn builtinCallArgSrc(block: *Block, builtin_call_node: std.zig.Ast.Node.Offset, arg_index: u32) LazySrcLoc { |
| 411 | return block.src(.{ .node_offset_builtin_call_arg = .{ | 411 | return block.src(.{ .node_offset_builtin_call_arg = .{ |
| 412 | .builtin_call_node = builtin_call_node, | 412 | .builtin_call_node = builtin_call_node, |
| 413 | .arg_index = arg_index, | 413 | .arg_index = arg_index, |
| 414 | } }); | 414 | } }); |
| 415 | } | 415 | } |
| 416 | 416 | ||
| 417 | pub fn nodeOffset(block: Block, node_offset: i32) LazySrcLoc { | 417 | pub fn nodeOffset(block: Block, node_offset: std.zig.Ast.Node.Offset) LazySrcLoc { |
| 418 | return block.src(LazySrcLoc.Offset.nodeOffset(node_offset)); | 418 | return block.src(LazySrcLoc.Offset.nodeOffset(node_offset)); |
| 419 | } | 419 | } |
| 420 | 420 | ||
| 421 | fn tokenOffset(block: Block, tok_offset: u32) LazySrcLoc { | 421 | fn tokenOffset(block: Block, tok_offset: std.zig.Ast.TokenOffset) LazySrcLoc { |
| 422 | return block.src(.{ .token_offset = tok_offset }); | 422 | return block.src(.{ .token_offset = tok_offset }); |
| 423 | } | 423 | } |
| 424 | 424 | ||
| ... | @@ -1860,7 +1860,7 @@ fn analyzeBodyInner( | ... | @@ -1860,7 +1860,7 @@ fn analyzeBodyInner( |
| 1860 | if (!block.isComptime()) break :blk try sema.zirTry(block, inst); | 1860 | if (!block.isComptime()) break :blk try sema.zirTry(block, inst); |
| 1861 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 1861 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 1862 | const src = block.nodeOffset(inst_data.src_node); | 1862 | const src = block.nodeOffset(inst_data.src_node); |
| 1863 | const operand_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 1863 | const operand_src = block.src(.{ .node_offset_try_operand = inst_data.src_node }); |
| 1864 | const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index); | 1864 | const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index); |
| 1865 | const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len); | 1865 | const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len); |
| 1866 | const err_union = try sema.resolveInst(extra.data.operand); | 1866 | const err_union = try sema.resolveInst(extra.data.operand); |
| ... | @@ -1883,7 +1883,7 @@ fn analyzeBodyInner( | ... | @@ -1883,7 +1883,7 @@ fn analyzeBodyInner( |
| 1883 | if (!block.isComptime()) break :blk try sema.zirTryPtr(block, inst); | 1883 | if (!block.isComptime()) break :blk try sema.zirTryPtr(block, inst); |
| 1884 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 1884 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 1885 | const src = block.nodeOffset(inst_data.src_node); | 1885 | const src = block.nodeOffset(inst_data.src_node); |
| 1886 | const operand_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 1886 | const operand_src = block.src(.{ .node_offset_try_operand = inst_data.src_node }); |
| 1887 | const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index); | 1887 | const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index); |
| 1888 | const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len); | 1888 | const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len); |
| 1889 | const operand = try sema.resolveInst(extra.data.operand); | 1889 | const operand = try sema.resolveInst(extra.data.operand); |
| ... | @@ -2166,7 +2166,7 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) | ... | @@ -2166,7 +2166,7 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) |
| 2166 | const addrs_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(addr_arr_ty)); | 2166 | const addrs_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(addr_arr_ty)); |
| 2167 | 2167 | ||
| 2168 | // var st: StackTrace = undefined; | 2168 | // var st: StackTrace = undefined; |
| 2169 | const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(0), .StackTrace); | 2169 | const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(.zero), .StackTrace); |
| 2170 | try stack_trace_ty.resolveFields(pt); | 2170 | try stack_trace_ty.resolveFields(pt); |
| 2171 | const st_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(stack_trace_ty)); | 2171 | const st_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(stack_trace_ty)); |
| 2172 | 2172 | ||
| ... | @@ -2901,7 +2901,7 @@ fn zirStructDecl( | ... | @@ -2901,7 +2901,7 @@ fn zirStructDecl( |
| 2901 | const tracked_inst = try block.trackZir(inst); | 2901 | const tracked_inst = try block.trackZir(inst); |
| 2902 | const src: LazySrcLoc = .{ | 2902 | const src: LazySrcLoc = .{ |
| 2903 | .base_node_inst = tracked_inst, | 2903 | .base_node_inst = tracked_inst, |
| 2904 | .offset = LazySrcLoc.Offset.nodeOffset(0), | 2904 | .offset = LazySrcLoc.Offset.nodeOffset(.zero), |
| 2905 | }; | 2905 | }; |
| 2906 | 2906 | ||
| 2907 | var extra_index = extra.end; | 2907 | var extra_index = extra.end; |
| ... | @@ -3114,7 +3114,7 @@ fn zirEnumDecl( | ... | @@ -3114,7 +3114,7 @@ fn zirEnumDecl( |
| 3114 | var extra_index: usize = extra.end; | 3114 | var extra_index: usize = extra.end; |
| 3115 | 3115 | ||
| 3116 | const tracked_inst = try block.trackZir(inst); | 3116 | const tracked_inst = try block.trackZir(inst); |
| 3117 | const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(0) }; | 3117 | const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(.zero) }; |
| 3118 | 3118 | ||
| 3119 | const tag_type_ref = if (small.has_tag_type) blk: { | 3119 | const tag_type_ref = if (small.has_tag_type) blk: { |
| 3120 | const tag_type_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); | 3120 | const tag_type_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); |
| ... | @@ -3277,7 +3277,7 @@ fn zirUnionDecl( | ... | @@ -3277,7 +3277,7 @@ fn zirUnionDecl( |
| 3277 | var extra_index: usize = extra.end; | 3277 | var extra_index: usize = extra.end; |
| 3278 | 3278 | ||
| 3279 | const tracked_inst = try block.trackZir(inst); | 3279 | const tracked_inst = try block.trackZir(inst); |
| 3280 | const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(0) }; | 3280 | const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(.zero) }; |
| 3281 | 3281 | ||
| 3282 | extra_index += @intFromBool(small.has_tag_type); | 3282 | extra_index += @intFromBool(small.has_tag_type); |
| 3283 | const captures_len = if (small.has_captures_len) blk: { | 3283 | const captures_len = if (small.has_captures_len) blk: { |
| ... | @@ -3402,7 +3402,7 @@ fn zirOpaqueDecl( | ... | @@ -3402,7 +3402,7 @@ fn zirOpaqueDecl( |
| 3402 | var extra_index: usize = extra.end; | 3402 | var extra_index: usize = extra.end; |
| 3403 | 3403 | ||
| 3404 | const tracked_inst = try block.trackZir(inst); | 3404 | const tracked_inst = try block.trackZir(inst); |
| 3405 | const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(0) }; | 3405 | const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(.zero) }; |
| 3406 | 3406 | ||
| 3407 | const captures_len = if (small.has_captures_len) blk: { | 3407 | const captures_len = if (small.has_captures_len) blk: { |
| 3408 | const captures_len = sema.code.extra[extra_index]; | 3408 | const captures_len = sema.code.extra[extra_index]; |
| ... | @@ -3835,7 +3835,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -3835,7 +3835,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 3835 | if (try elem_ty.comptimeOnlySema(pt)) { | 3835 | if (try elem_ty.comptimeOnlySema(pt)) { |
| 3836 | // The value was initialized through RLS, so we didn't detect the runtime condition earlier. | 3836 | // The value was initialized through RLS, so we didn't detect the runtime condition earlier. |
| 3837 | // TODO: source location of runtime control flow | 3837 | // TODO: source location of runtime control flow |
| 3838 | const init_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); | 3838 | const init_src = block.src(.{ .node_offset_var_decl_init = inst_data.src_node }); |
| 3839 | return sema.fail(block, init_src, "value with comptime-only type '{}' depends on runtime control flow", .{elem_ty.fmt(pt)}); | 3839 | return sema.fail(block, init_src, "value with comptime-only type '{}' depends on runtime control flow", .{elem_ty.fmt(pt)}); |
| 3840 | } | 3840 | } |
| 3841 | 3841 | ||
| ... | @@ -6690,8 +6690,8 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -6690,8 +6690,8 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError |
| 6690 | if (block.label) |label| { | 6690 | if (block.label) |label| { |
| 6691 | if (label.zir_block == zir_block) { | 6691 | if (label.zir_block == zir_block) { |
| 6692 | const br_ref = try start_block.addBr(label.merges.block_inst, operand); | 6692 | const br_ref = try start_block.addBr(label.merges.block_inst, operand); |
| 6693 | const src_loc = if (extra.operand_src_node != Zir.Inst.Break.no_src_node) | 6693 | const src_loc = if (extra.operand_src_node.unwrap()) |operand_src_node| |
| 6694 | start_block.nodeOffset(extra.operand_src_node) | 6694 | start_block.nodeOffset(operand_src_node) |
| 6695 | else | 6695 | else |
| 6696 | null; | 6696 | null; |
| 6697 | try label.merges.src_locs.append(sema.gpa, src_loc); | 6697 | try label.merges.src_locs.append(sema.gpa, src_loc); |
| ... | @@ -6715,8 +6715,7 @@ fn zirSwitchContinue(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -6715,8 +6715,7 @@ fn zirSwitchContinue(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) Com |
| 6715 | 6715 | ||
| 6716 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"break"; | 6716 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"break"; |
| 6717 | const extra = sema.code.extraData(Zir.Inst.Break, inst_data.payload_index).data; | 6717 | const extra = sema.code.extraData(Zir.Inst.Break, inst_data.payload_index).data; |
| 6718 | assert(extra.operand_src_node != Zir.Inst.Break.no_src_node); | 6718 | const operand_src = start_block.nodeOffset(extra.operand_src_node.unwrap().?); |
| 6719 | const operand_src = start_block.nodeOffset(extra.operand_src_node); | ||
| 6720 | const uncoerced_operand = try sema.resolveInst(inst_data.operand); | 6719 | const uncoerced_operand = try sema.resolveInst(inst_data.operand); |
| 6721 | const switch_inst = extra.block_inst; | 6720 | const switch_inst = extra.block_inst; |
| 6722 | 6721 | ||
| ... | @@ -7048,7 +7047,7 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref | ... | @@ -7048,7 +7047,7 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref |
| 7048 | 7047 | ||
| 7049 | if (!block.ownerModule().error_tracing) return .none; | 7048 | if (!block.ownerModule().error_tracing) return .none; |
| 7050 | 7049 | ||
| 7051 | const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(0), .StackTrace); | 7050 | const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(.zero), .StackTrace); |
| 7052 | try stack_trace_ty.resolveFields(pt); | 7051 | try stack_trace_ty.resolveFields(pt); |
| 7053 | const field_name = try zcu.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls); | 7052 | const field_name = try zcu.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls); |
| 7054 | const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) { | 7053 | const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) { |
| ... | @@ -7346,7 +7345,7 @@ fn checkCallArgumentCount( | ... | @@ -7346,7 +7345,7 @@ fn checkCallArgumentCount( |
| 7346 | if (maybe_func_inst) |func_inst| { | 7345 | if (maybe_func_inst) |func_inst| { |
| 7347 | try sema.errNote(.{ | 7346 | try sema.errNote(.{ |
| 7348 | .base_node_inst = func_inst, | 7347 | .base_node_inst = func_inst, |
| 7349 | .offset = LazySrcLoc.Offset.nodeOffset(0), | 7348 | .offset = LazySrcLoc.Offset.nodeOffset(.zero), |
| 7350 | }, msg, "function declared here", .{}); | 7349 | }, msg, "function declared here", .{}); |
| 7351 | } | 7350 | } |
| 7352 | break :msg msg; | 7351 | break :msg msg; |
| ... | @@ -7418,7 +7417,7 @@ const CallArgsInfo = union(enum) { | ... | @@ -7418,7 +7417,7 @@ const CallArgsInfo = union(enum) { |
| 7418 | /// The list of resolved (but uncoerced) arguments is known ahead of time, but | 7417 | /// The list of resolved (but uncoerced) arguments is known ahead of time, but |
| 7419 | /// originated from a usage of the @call builtin at the given node offset. | 7418 | /// originated from a usage of the @call builtin at the given node offset. |
| 7420 | call_builtin: struct { | 7419 | call_builtin: struct { |
| 7421 | call_node_offset: i32, | 7420 | call_node_offset: std.zig.Ast.Node.Offset, |
| 7422 | args: []const Air.Inst.Ref, | 7421 | args: []const Air.Inst.Ref, |
| 7423 | }, | 7422 | }, |
| 7424 | 7423 | ||
| ... | @@ -7436,7 +7435,7 @@ const CallArgsInfo = union(enum) { | ... | @@ -7436,7 +7435,7 @@ const CallArgsInfo = union(enum) { |
| 7436 | /// analyzing arguments. | 7435 | /// analyzing arguments. |
| 7437 | call_inst: Zir.Inst.Index, | 7436 | call_inst: Zir.Inst.Index, |
| 7438 | /// The node offset of `call_inst`. | 7437 | /// The node offset of `call_inst`. |
| 7439 | call_node_offset: i32, | 7438 | call_node_offset: std.zig.Ast.Node.Offset, |
| 7440 | /// The number of arguments to this call, not including `bound_arg`. | 7439 | /// The number of arguments to this call, not including `bound_arg`. |
| 7441 | num_args: u32, | 7440 | num_args: u32, |
| 7442 | /// The ZIR corresponding to all function arguments (other than `bound_arg`, if it | 7441 | /// The ZIR corresponding to all function arguments (other than `bound_arg`, if it |
| ... | @@ -7599,7 +7598,7 @@ fn analyzeCall( | ... | @@ -7599,7 +7598,7 @@ fn analyzeCall( |
| 7599 | const maybe_func_inst = try sema.funcDeclSrcInst(callee); | 7598 | const maybe_func_inst = try sema.funcDeclSrcInst(callee); |
| 7600 | const func_ret_ty_src: LazySrcLoc = if (maybe_func_inst) |fn_decl_inst| .{ | 7599 | const func_ret_ty_src: LazySrcLoc = if (maybe_func_inst) |fn_decl_inst| .{ |
| 7601 | .base_node_inst = fn_decl_inst, | 7600 | .base_node_inst = fn_decl_inst, |
| 7602 | .offset = .{ .node_offset_fn_type_ret_ty = 0 }, | 7601 | .offset = .{ .node_offset_fn_type_ret_ty = .zero }, |
| 7603 | } else func_src; | 7602 | } else func_src; |
| 7604 | 7603 | ||
| 7605 | const func_ty_info = zcu.typeToFunc(func_ty).?; | 7604 | const func_ty_info = zcu.typeToFunc(func_ty).?; |
| ... | @@ -7613,7 +7612,7 @@ fn analyzeCall( | ... | @@ -7613,7 +7612,7 @@ fn analyzeCall( |
| 7613 | errdefer msg.destroy(gpa); | 7612 | errdefer msg.destroy(gpa); |
| 7614 | if (maybe_func_inst) |func_inst| try sema.errNote(.{ | 7613 | if (maybe_func_inst) |func_inst| try sema.errNote(.{ |
| 7615 | .base_node_inst = func_inst, | 7614 | .base_node_inst = func_inst, |
| 7616 | .offset = .nodeOffset(0), | 7615 | .offset = .nodeOffset(.zero), |
| 7617 | }, msg, "function declared here", .{}); | 7616 | }, msg, "function declared here", .{}); |
| 7618 | break :msg msg; | 7617 | break :msg msg; |
| 7619 | }); | 7618 | }); |
| ... | @@ -9574,7 +9573,7 @@ const Section = union(enum) { | ... | @@ -9574,7 +9573,7 @@ const Section = union(enum) { |
| 9574 | fn funcCommon( | 9573 | fn funcCommon( |
| 9575 | sema: *Sema, | 9574 | sema: *Sema, |
| 9576 | block: *Block, | 9575 | block: *Block, |
| 9577 | src_node_offset: i32, | 9576 | src_node_offset: std.zig.Ast.Node.Offset, |
| 9578 | func_inst: Zir.Inst.Index, | 9577 | func_inst: Zir.Inst.Index, |
| 9579 | cc: std.builtin.CallingConvention, | 9578 | cc: std.builtin.CallingConvention, |
| 9580 | /// this might be Type.generic_poison | 9579 | /// this might be Type.generic_poison |
| ... | @@ -9948,7 +9947,7 @@ fn finishFunc( | ... | @@ -9948,7 +9947,7 @@ fn finishFunc( |
| 9948 | if (!is_generic and sema.wantErrorReturnTracing(return_type)) { | 9947 | if (!is_generic and sema.wantErrorReturnTracing(return_type)) { |
| 9949 | // Make sure that StackTrace's fields are resolved so that the backend can | 9948 | // Make sure that StackTrace's fields are resolved so that the backend can |
| 9950 | // lower this fn type. | 9949 | // lower this fn type. |
| 9951 | const unresolved_stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(0), .StackTrace); | 9950 | const unresolved_stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(.zero), .StackTrace); |
| 9952 | try unresolved_stack_trace_ty.resolveFields(pt); | 9951 | try unresolved_stack_trace_ty.resolveFields(pt); |
| 9953 | } | 9952 | } |
| 9954 | 9953 | ||
| ... | @@ -12599,7 +12598,7 @@ fn analyzeSwitchRuntimeBlock( | ... | @@ -12599,7 +12598,7 @@ fn analyzeSwitchRuntimeBlock( |
| 12599 | union_originally: bool, | 12598 | union_originally: bool, |
| 12600 | maybe_union_ty: Type, | 12599 | maybe_union_ty: Type, |
| 12601 | err_set: bool, | 12600 | err_set: bool, |
| 12602 | switch_node_offset: i32, | 12601 | switch_node_offset: std.zig.Ast.Node.Offset, |
| 12603 | special_prong_src: LazySrcLoc, | 12602 | special_prong_src: LazySrcLoc, |
| 12604 | seen_enum_fields: []?LazySrcLoc, | 12603 | seen_enum_fields: []?LazySrcLoc, |
| 12605 | seen_errors: SwitchErrorSet, | 12604 | seen_errors: SwitchErrorSet, |
| ... | @@ -13219,7 +13218,7 @@ fn resolveSwitchComptimeLoop( | ... | @@ -13219,7 +13218,7 @@ fn resolveSwitchComptimeLoop( |
| 13219 | maybe_ptr_operand_ty: Type, | 13218 | maybe_ptr_operand_ty: Type, |
| 13220 | cond_ty: Type, | 13219 | cond_ty: Type, |
| 13221 | init_cond_val: Value, | 13220 | init_cond_val: Value, |
| 13222 | switch_node_offset: i32, | 13221 | switch_node_offset: std.zig.Ast.Node.Offset, |
| 13223 | special: SpecialProng, | 13222 | special: SpecialProng, |
| 13224 | case_vals: std.ArrayListUnmanaged(Air.Inst.Ref), | 13223 | case_vals: std.ArrayListUnmanaged(Air.Inst.Ref), |
| 13225 | scalar_cases_len: u32, | 13224 | scalar_cases_len: u32, |
| ... | @@ -13255,7 +13254,7 @@ fn resolveSwitchComptimeLoop( | ... | @@ -13255,7 +13254,7 @@ fn resolveSwitchComptimeLoop( |
| 13255 | const extra = sema.code.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data; | 13254 | const extra = sema.code.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data; |
| 13256 | if (extra.block_inst != spa.switch_block_inst) return error.ComptimeBreak; | 13255 | if (extra.block_inst != spa.switch_block_inst) return error.ComptimeBreak; |
| 13257 | // This is a `switch_continue` targeting this block. Change the operand and start over. | 13256 | // This is a `switch_continue` targeting this block. Change the operand and start over. |
| 13258 | const src = child_block.nodeOffset(extra.operand_src_node); | 13257 | const src = child_block.nodeOffset(extra.operand_src_node.unwrap().?); |
| 13259 | const new_operand_uncoerced = try sema.resolveInst(break_inst.data.@"break".operand); | 13258 | const new_operand_uncoerced = try sema.resolveInst(break_inst.data.@"break".operand); |
| 13260 | const new_operand = try sema.coerce(child_block, maybe_ptr_operand_ty, new_operand_uncoerced, src); | 13259 | const new_operand = try sema.coerce(child_block, maybe_ptr_operand_ty, new_operand_uncoerced, src); |
| 13261 | 13260 | ||
| ... | @@ -13287,7 +13286,7 @@ fn resolveSwitchComptime( | ... | @@ -13287,7 +13286,7 @@ fn resolveSwitchComptime( |
| 13287 | cond_operand: Air.Inst.Ref, | 13286 | cond_operand: Air.Inst.Ref, |
| 13288 | operand_val: Value, | 13287 | operand_val: Value, |
| 13289 | operand_ty: Type, | 13288 | operand_ty: Type, |
| 13290 | switch_node_offset: i32, | 13289 | switch_node_offset: std.zig.Ast.Node.Offset, |
| 13291 | special: SpecialProng, | 13290 | special: SpecialProng, |
| 13292 | case_vals: std.ArrayListUnmanaged(Air.Inst.Ref), | 13291 | case_vals: std.ArrayListUnmanaged(Air.Inst.Ref), |
| 13293 | scalar_cases_len: u32, | 13292 | scalar_cases_len: u32, |
| ... | @@ -13837,7 +13836,7 @@ fn validateSwitchNoRange( | ... | @@ -13837,7 +13836,7 @@ fn validateSwitchNoRange( |
| 13837 | block: *Block, | 13836 | block: *Block, |
| 13838 | ranges_len: u32, | 13837 | ranges_len: u32, |
| 13839 | operand_ty: Type, | 13838 | operand_ty: Type, |
| 13840 | src_node_offset: i32, | 13839 | src_node_offset: std.zig.Ast.Node.Offset, |
| 13841 | ) CompileError!void { | 13840 | ) CompileError!void { |
| 13842 | if (ranges_len == 0) | 13841 | if (ranges_len == 0) |
| 13843 | return; | 13842 | return; |
| ... | @@ -14158,14 +14157,24 @@ fn zirShl( | ... | @@ -14158,14 +14157,24 @@ fn zirShl( |
| 14158 | const pt = sema.pt; | 14157 | const pt = sema.pt; |
| 14159 | const zcu = pt.zcu; | 14158 | const zcu = pt.zcu; |
| 14160 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 14159 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 14161 | const src = block.nodeOffset(inst_data.src_node); | ||
| 14162 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | ||
| 14163 | const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); | ||
| 14164 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 14160 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 14165 | const lhs = try sema.resolveInst(extra.lhs); | 14161 | const lhs = try sema.resolveInst(extra.lhs); |
| 14166 | const rhs = try sema.resolveInst(extra.rhs); | 14162 | const rhs = try sema.resolveInst(extra.rhs); |
| 14167 | const lhs_ty = sema.typeOf(lhs); | 14163 | const lhs_ty = sema.typeOf(lhs); |
| 14168 | const rhs_ty = sema.typeOf(rhs); | 14164 | const rhs_ty = sema.typeOf(rhs); |
| 14165 | |||
| 14166 | const src = block.nodeOffset(inst_data.src_node); | ||
| 14167 | const lhs_src = switch (air_tag) { | ||
| 14168 | .shl, .shl_sat => block.src(.{ .node_offset_bin_lhs = inst_data.src_node }), | ||
| 14169 | .shl_exact => block.builtinCallArgSrc(inst_data.src_node, 0), | ||
| 14170 | else => unreachable, | ||
| 14171 | }; | ||
| 14172 | const rhs_src = switch (air_tag) { | ||
| 14173 | .shl, .shl_sat => block.src(.{ .node_offset_bin_rhs = inst_data.src_node }), | ||
| 14174 | .shl_exact => block.builtinCallArgSrc(inst_data.src_node, 1), | ||
| 14175 | else => unreachable, | ||
| 14176 | }; | ||
| 14177 | |||
| 14169 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); | 14178 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 14170 | 14179 | ||
| 14171 | const scalar_ty = lhs_ty.scalarType(zcu); | 14180 | const scalar_ty = lhs_ty.scalarType(zcu); |
| ... | @@ -14329,14 +14338,24 @@ fn zirShr( | ... | @@ -14329,14 +14338,24 @@ fn zirShr( |
| 14329 | const pt = sema.pt; | 14338 | const pt = sema.pt; |
| 14330 | const zcu = pt.zcu; | 14339 | const zcu = pt.zcu; |
| 14331 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 14340 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 14332 | const src = block.nodeOffset(inst_data.src_node); | ||
| 14333 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | ||
| 14334 | const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); | ||
| 14335 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 14341 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 14336 | const lhs = try sema.resolveInst(extra.lhs); | 14342 | const lhs = try sema.resolveInst(extra.lhs); |
| 14337 | const rhs = try sema.resolveInst(extra.rhs); | 14343 | const rhs = try sema.resolveInst(extra.rhs); |
| 14338 | const lhs_ty = sema.typeOf(lhs); | 14344 | const lhs_ty = sema.typeOf(lhs); |
| 14339 | const rhs_ty = sema.typeOf(rhs); | 14345 | const rhs_ty = sema.typeOf(rhs); |
| 14346 | |||
| 14347 | const src = block.nodeOffset(inst_data.src_node); | ||
| 14348 | const lhs_src = switch (air_tag) { | ||
| 14349 | .shr => block.src(.{ .node_offset_bin_lhs = inst_data.src_node }), | ||
| 14350 | .shr_exact => block.builtinCallArgSrc(inst_data.src_node, 0), | ||
| 14351 | else => unreachable, | ||
| 14352 | }; | ||
| 14353 | const rhs_src = switch (air_tag) { | ||
| 14354 | .shr => block.src(.{ .node_offset_bin_rhs = inst_data.src_node }), | ||
| 14355 | .shr_exact => block.builtinCallArgSrc(inst_data.src_node, 1), | ||
| 14356 | else => unreachable, | ||
| 14357 | }; | ||
| 14358 | |||
| 14340 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); | 14359 | try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); |
| 14341 | const scalar_ty = lhs_ty.scalarType(zcu); | 14360 | const scalar_ty = lhs_ty.scalarType(zcu); |
| 14342 | 14361 | ||
| ... | @@ -14560,7 +14579,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -14560,7 +14579,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 14560 | fn analyzeTupleCat( | 14579 | fn analyzeTupleCat( |
| 14561 | sema: *Sema, | 14580 | sema: *Sema, |
| 14562 | block: *Block, | 14581 | block: *Block, |
| 14563 | src_node: i32, | 14582 | src_node: std.zig.Ast.Node.Offset, |
| 14564 | lhs: Air.Inst.Ref, | 14583 | lhs: Air.Inst.Ref, |
| 14565 | rhs: Air.Inst.Ref, | 14584 | rhs: Air.Inst.Ref, |
| 14566 | ) CompileError!Air.Inst.Ref { | 14585 | ) CompileError!Air.Inst.Ref { |
| ... | @@ -15005,7 +15024,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins | ... | @@ -15005,7 +15024,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins |
| 15005 | fn analyzeTupleMul( | 15024 | fn analyzeTupleMul( |
| 15006 | sema: *Sema, | 15025 | sema: *Sema, |
| 15007 | block: *Block, | 15026 | block: *Block, |
| 15008 | src_node: i32, | 15027 | src_node: std.zig.Ast.Node.Offset, |
| 15009 | operand: Air.Inst.Ref, | 15028 | operand: Air.Inst.Ref, |
| 15010 | factor: usize, | 15029 | factor: usize, |
| 15011 | ) CompileError!Air.Inst.Ref { | 15030 | ) CompileError!Air.Inst.Ref { |
| ... | @@ -15494,8 +15513,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15494,8 +15513,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15494 | const zcu = pt.zcu; | 15513 | const zcu = pt.zcu; |
| 15495 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 15514 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 15496 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); | 15515 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 15497 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 15516 | const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 15498 | const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); | 15517 | const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1); |
| 15499 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 15518 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 15500 | const lhs = try sema.resolveInst(extra.lhs); | 15519 | const lhs = try sema.resolveInst(extra.lhs); |
| 15501 | const rhs = try sema.resolveInst(extra.rhs); | 15520 | const rhs = try sema.resolveInst(extra.rhs); |
| ... | @@ -15660,8 +15679,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15660,8 +15679,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15660 | const zcu = pt.zcu; | 15679 | const zcu = pt.zcu; |
| 15661 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 15680 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 15662 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); | 15681 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 15663 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 15682 | const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 15664 | const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); | 15683 | const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1); |
| 15665 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 15684 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 15666 | const lhs = try sema.resolveInst(extra.lhs); | 15685 | const lhs = try sema.resolveInst(extra.lhs); |
| 15667 | const rhs = try sema.resolveInst(extra.rhs); | 15686 | const rhs = try sema.resolveInst(extra.rhs); |
| ... | @@ -15771,8 +15790,8 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -15771,8 +15790,8 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 15771 | const zcu = pt.zcu; | 15790 | const zcu = pt.zcu; |
| 15772 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 15791 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 15773 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); | 15792 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 15774 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 15793 | const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 15775 | const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); | 15794 | const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1); |
| 15776 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 15795 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 15777 | const lhs = try sema.resolveInst(extra.lhs); | 15796 | const lhs = try sema.resolveInst(extra.lhs); |
| 15778 | const rhs = try sema.resolveInst(extra.rhs); | 15797 | const rhs = try sema.resolveInst(extra.rhs); |
| ... | @@ -16201,8 +16220,8 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -16201,8 +16220,8 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 16201 | const zcu = pt.zcu; | 16220 | const zcu = pt.zcu; |
| 16202 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 16221 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 16203 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); | 16222 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 16204 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 16223 | const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 16205 | const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); | 16224 | const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1); |
| 16206 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 16225 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 16207 | const lhs = try sema.resolveInst(extra.lhs); | 16226 | const lhs = try sema.resolveInst(extra.lhs); |
| 16208 | const rhs = try sema.resolveInst(extra.rhs); | 16227 | const rhs = try sema.resolveInst(extra.rhs); |
| ... | @@ -16297,8 +16316,8 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -16297,8 +16316,8 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 16297 | const zcu = pt.zcu; | 16316 | const zcu = pt.zcu; |
| 16298 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 16317 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 16299 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); | 16318 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 16300 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 16319 | const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 16301 | const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); | 16320 | const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1); |
| 16302 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 16321 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 16303 | const lhs = try sema.resolveInst(extra.lhs); | 16322 | const lhs = try sema.resolveInst(extra.lhs); |
| 16304 | const rhs = try sema.resolveInst(extra.rhs); | 16323 | const rhs = try sema.resolveInst(extra.rhs); |
| ... | @@ -17867,7 +17886,7 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -17867,7 +17886,7 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 17867 | const ip = &zcu.intern_pool; | 17886 | const ip = &zcu.intern_pool; |
| 17868 | const captures = Type.fromInterned(zcu.namespacePtr(block.namespace).owner_type).getCaptures(zcu); | 17887 | const captures = Type.fromInterned(zcu.namespacePtr(block.namespace).owner_type).getCaptures(zcu); |
| 17869 | 17888 | ||
| 17870 | const src_node: i32 = @bitCast(extended.operand); | 17889 | const src_node: std.zig.Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand))); |
| 17871 | const src = block.nodeOffset(src_node); | 17890 | const src = block.nodeOffset(src_node); |
| 17872 | 17891 | ||
| 17873 | const capture_ty = switch (captures.get(ip)[extended.small].unwrap()) { | 17892 | const capture_ty = switch (captures.get(ip)[extended.small].unwrap()) { |
| ... | @@ -17891,8 +17910,8 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -17891,8 +17910,8 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 17891 | }); | 17910 | }); |
| 17892 | break :name null; | 17911 | break :name null; |
| 17893 | }; | 17912 | }; |
| 17894 | const node: std.zig.Ast.Node.Index = @bitCast(src_node + @as(i32, @bitCast(src_base_node))); | 17913 | const node = src_node.toAbsolute(src_base_node); |
| 17895 | const token = tree.nodes.items(.main_token)[node]; | 17914 | const token = tree.nodeMainToken(node); |
| 17896 | break :name tree.tokenSlice(token); | 17915 | break :name tree.tokenSlice(token); |
| 17897 | }; | 17916 | }; |
| 17898 | 17917 | ||
| ... | @@ -17919,8 +17938,8 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -17919,8 +17938,8 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 17919 | }); | 17938 | }); |
| 17920 | break :name null; | 17939 | break :name null; |
| 17921 | }; | 17940 | }; |
| 17922 | const node: std.zig.Ast.Node.Index = @bitCast(src_node + @as(i32, @bitCast(src_base_node))); | 17941 | const node = src_node.toAbsolute(src_base_node); |
| 17923 | const token = tree.nodes.items(.main_token)[node]; | 17942 | const token = tree.nodeMainToken(node); |
| 17924 | break :name tree.tokenSlice(token); | 17943 | break :name tree.tokenSlice(token); |
| 17925 | }; | 17944 | }; |
| 17926 | 17945 | ||
| ... | @@ -17930,7 +17949,7 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -17930,7 +17949,7 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 17930 | try sema.errMsg(src, "variable not accessible from inner function", .{}); | 17949 | try sema.errMsg(src, "variable not accessible from inner function", .{}); |
| 17931 | errdefer msg.destroy(sema.gpa); | 17950 | errdefer msg.destroy(sema.gpa); |
| 17932 | 17951 | ||
| 17933 | try sema.errNote(block.nodeOffset(0), msg, "crossed function definition here", .{}); | 17952 | try sema.errNote(block.nodeOffset(.zero), msg, "crossed function definition here", .{}); |
| 17934 | 17953 | ||
| 17935 | // TODO add "declared here" note | 17954 | // TODO add "declared here" note |
| 17936 | break :msg msg; | 17955 | break :msg msg; |
| ... | @@ -17962,7 +17981,8 @@ fn zirFrameAddress( | ... | @@ -17962,7 +17981,8 @@ fn zirFrameAddress( |
| 17962 | block: *Block, | 17981 | block: *Block, |
| 17963 | extended: Zir.Inst.Extended.InstData, | 17982 | extended: Zir.Inst.Extended.InstData, |
| 17964 | ) CompileError!Air.Inst.Ref { | 17983 | ) CompileError!Air.Inst.Ref { |
| 17965 | const src = block.nodeOffset(@bitCast(extended.operand)); | 17984 | const src_node: std.zig.Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand))); |
| 17985 | const src = block.nodeOffset(src_node); | ||
| 17966 | try sema.requireRuntimeBlock(block, src, null); | 17986 | try sema.requireRuntimeBlock(block, src, null); |
| 17967 | return try block.addNoOp(.frame_addr); | 17987 | return try block.addNoOp(.frame_addr); |
| 17968 | } | 17988 | } |
| ... | @@ -18059,7 +18079,7 @@ fn zirBuiltinSrc( | ... | @@ -18059,7 +18079,7 @@ fn zirBuiltinSrc( |
| 18059 | } }); | 18079 | } }); |
| 18060 | }; | 18080 | }; |
| 18061 | 18081 | ||
| 18062 | const src_loc_ty = try sema.getBuiltinType(block.nodeOffset(0), .SourceLocation); | 18082 | const src_loc_ty = try sema.getBuiltinType(block.nodeOffset(.zero), .SourceLocation); |
| 18063 | const fields = .{ | 18083 | const fields = .{ |
| 18064 | // module: [:0]const u8, | 18084 | // module: [:0]const u8, |
| 18065 | module_name_val, | 18085 | module_name_val, |
| ... | @@ -19528,7 +19548,7 @@ fn zirCondbr( | ... | @@ -19528,7 +19548,7 @@ fn zirCondbr( |
| 19528 | fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 19548 | fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 19529 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 19549 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 19530 | const src = parent_block.nodeOffset(inst_data.src_node); | 19550 | const src = parent_block.nodeOffset(inst_data.src_node); |
| 19531 | const operand_src = parent_block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 19551 | const operand_src = parent_block.src(.{ .node_offset_try_operand = inst_data.src_node }); |
| 19532 | const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index); | 19552 | const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index); |
| 19533 | const body = sema.code.bodySlice(extra.end, extra.data.body_len); | 19553 | const body = sema.code.bodySlice(extra.end, extra.data.body_len); |
| 19534 | const err_union = try sema.resolveInst(extra.data.operand); | 19554 | const err_union = try sema.resolveInst(extra.data.operand); |
| ... | @@ -19587,7 +19607,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -19587,7 +19607,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError! |
| 19587 | fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 19607 | fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 19588 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 19608 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 19589 | const src = parent_block.nodeOffset(inst_data.src_node); | 19609 | const src = parent_block.nodeOffset(inst_data.src_node); |
| 19590 | const operand_src = parent_block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 19610 | const operand_src = parent_block.src(.{ .node_offset_try_operand = inst_data.src_node }); |
| 19591 | const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index); | 19611 | const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index); |
| 19592 | const body = sema.code.bodySlice(extra.end, extra.data.body_len); | 19612 | const body = sema.code.bodySlice(extra.end, extra.data.body_len); |
| 19593 | const operand = try sema.resolveInst(extra.data.operand); | 19613 | const operand = try sema.resolveInst(extra.data.operand); |
| ... | @@ -19790,7 +19810,7 @@ fn zirRetImplicit( | ... | @@ -19790,7 +19810,7 @@ fn zirRetImplicit( |
| 19790 | } | 19810 | } |
| 19791 | 19811 | ||
| 19792 | const operand = try sema.resolveInst(inst_data.operand); | 19812 | const operand = try sema.resolveInst(inst_data.operand); |
| 19793 | const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = 0 }); | 19813 | const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = .zero }); |
| 19794 | const base_tag = sema.fn_ret_ty.baseZigTypeTag(zcu); | 19814 | const base_tag = sema.fn_ret_ty.baseZigTypeTag(zcu); |
| 19795 | if (base_tag == .noreturn) { | 19815 | if (base_tag == .noreturn) { |
| 19796 | const msg = msg: { | 19816 | const msg = msg: { |
| ... | @@ -21277,7 +21297,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { | ... | @@ -21277,7 +21297,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 21277 | const pt = sema.pt; | 21297 | const pt = sema.pt; |
| 21278 | const zcu = pt.zcu; | 21298 | const zcu = pt.zcu; |
| 21279 | const ip = &zcu.intern_pool; | 21299 | const ip = &zcu.intern_pool; |
| 21280 | const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(0), .StackTrace); | 21300 | const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(.zero), .StackTrace); |
| 21281 | try stack_trace_ty.resolveFields(pt); | 21301 | try stack_trace_ty.resolveFields(pt); |
| 21282 | const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty); | 21302 | const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty); |
| 21283 | const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern()); | 21303 | const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern()); |
| ... | @@ -21299,7 +21319,8 @@ fn zirFrame( | ... | @@ -21299,7 +21319,8 @@ fn zirFrame( |
| 21299 | block: *Block, | 21319 | block: *Block, |
| 21300 | extended: Zir.Inst.Extended.InstData, | 21320 | extended: Zir.Inst.Extended.InstData, |
| 21301 | ) CompileError!Air.Inst.Ref { | 21321 | ) CompileError!Air.Inst.Ref { |
| 21302 | const src = block.nodeOffset(@bitCast(extended.operand)); | 21322 | const src_node: std.zig.Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand))); |
| 21323 | const src = block.nodeOffset(src_node); | ||
| 21303 | return sema.failWithUseOfAsync(block, src); | 21324 | return sema.failWithUseOfAsync(block, src); |
| 21304 | } | 21325 | } |
| 21305 | 21326 | ||
| ... | @@ -21553,13 +21574,13 @@ fn zirReify( | ... | @@ -21553,13 +21574,13 @@ fn zirReify( |
| 21553 | const tracked_inst = try block.trackZir(inst); | 21574 | const tracked_inst = try block.trackZir(inst); |
| 21554 | const src: LazySrcLoc = .{ | 21575 | const src: LazySrcLoc = .{ |
| 21555 | .base_node_inst = tracked_inst, | 21576 | .base_node_inst = tracked_inst, |
| 21556 | .offset = LazySrcLoc.Offset.nodeOffset(0), | 21577 | .offset = LazySrcLoc.Offset.nodeOffset(.zero), |
| 21557 | }; | 21578 | }; |
| 21558 | const operand_src: LazySrcLoc = .{ | 21579 | const operand_src: LazySrcLoc = .{ |
| 21559 | .base_node_inst = tracked_inst, | 21580 | .base_node_inst = tracked_inst, |
| 21560 | .offset = .{ | 21581 | .offset = .{ |
| 21561 | .node_offset_builtin_call_arg = .{ | 21582 | .node_offset_builtin_call_arg = .{ |
| 21562 | .builtin_call_node = 0, // `tracked_inst` is precisely the `reify` instruction, so offset is 0 | 21583 | .builtin_call_node = .zero, // `tracked_inst` is precisely the `reify` instruction, so offset is 0 |
| 21563 | .arg_index = 0, | 21584 | .arg_index = 0, |
| 21564 | }, | 21585 | }, |
| 21565 | }, | 21586 | }, |
| ... | @@ -22867,7 +22888,8 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C | ... | @@ -22867,7 +22888,8 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 22867 | } | 22888 | } |
| 22868 | 22889 | ||
| 22869 | fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { | 22890 | fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 22870 | const src = block.nodeOffset(@bitCast(extended.operand)); | 22891 | const src_node: std.zig.Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand))); |
| 22892 | const src = block.nodeOffset(src_node); | ||
| 22871 | 22893 | ||
| 22872 | const va_list_ty = try sema.getBuiltinType(src, .VaList); | 22894 | const va_list_ty = try sema.getBuiltinType(src, .VaList); |
| 22873 | try sema.requireRuntimeBlock(block, src, null); | 22895 | try sema.requireRuntimeBlock(block, src, null); |
| ... | @@ -24272,12 +24294,12 @@ fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -24272,12 +24294,12 @@ fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 24272 | fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u64 { | 24294 | fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u64 { |
| 24273 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 24295 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 24274 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); | 24296 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 24275 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 24297 | const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 24276 | const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); | 24298 | const field_name_src = block.builtinCallArgSrc(inst_data.src_node, 1); |
| 24277 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 24299 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 24278 | 24300 | ||
| 24279 | const ty = try sema.resolveType(block, lhs_src, extra.lhs); | 24301 | const ty = try sema.resolveType(block, ty_src, extra.lhs); |
| 24280 | const field_name = try sema.resolveConstStringIntern(block, rhs_src, extra.rhs, .{ .simple = .field_name }); | 24302 | const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.rhs, .{ .simple = .field_name }); |
| 24281 | 24303 | ||
| 24282 | const pt = sema.pt; | 24304 | const pt = sema.pt; |
| 24283 | const zcu = pt.zcu; | 24305 | const zcu = pt.zcu; |
| ... | @@ -24285,15 +24307,15 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 | ... | @@ -24285,15 +24307,15 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 |
| 24285 | try ty.resolveLayout(pt); | 24307 | try ty.resolveLayout(pt); |
| 24286 | switch (ty.zigTypeTag(zcu)) { | 24308 | switch (ty.zigTypeTag(zcu)) { |
| 24287 | .@"struct" => {}, | 24309 | .@"struct" => {}, |
| 24288 | else => return sema.fail(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(pt)}), | 24310 | else => return sema.fail(block, ty_src, "expected struct type, found '{}'", .{ty.fmt(pt)}), |
| 24289 | } | 24311 | } |
| 24290 | 24312 | ||
| 24291 | const field_index = if (ty.isTuple(zcu)) blk: { | 24313 | const field_index = if (ty.isTuple(zcu)) blk: { |
| 24292 | if (field_name.eqlSlice("len", ip)) { | 24314 | if (field_name.eqlSlice("len", ip)) { |
| 24293 | return sema.fail(block, src, "no offset available for 'len' field of tuple", .{}); | 24315 | return sema.fail(block, src, "no offset available for 'len' field of tuple", .{}); |
| 24294 | } | 24316 | } |
| 24295 | break :blk try sema.tupleFieldIndex(block, ty, field_name, rhs_src); | 24317 | break :blk try sema.tupleFieldIndex(block, ty, field_name, field_name_src); |
| 24296 | } else try sema.structFieldIndex(block, ty, field_name, rhs_src); | 24318 | } else try sema.structFieldIndex(block, ty, field_name, field_name_src); |
| 24297 | 24319 | ||
| 24298 | if (ty.structFieldIsComptime(field_index, zcu)) { | 24320 | if (ty.structFieldIsComptime(field_index, zcu)) { |
| 24299 | return sema.fail(block, src, "no offset available for comptime field", .{}); | 24321 | return sema.fail(block, src, "no offset available for comptime field", .{}); |
| ... | @@ -25077,7 +25099,7 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -25077,7 +25099,7 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 25077 | fn analyzeShuffle( | 25099 | fn analyzeShuffle( |
| 25078 | sema: *Sema, | 25100 | sema: *Sema, |
| 25079 | block: *Block, | 25101 | block: *Block, |
| 25080 | src_node: i32, | 25102 | src_node: std.zig.Ast.Node.Offset, |
| 25081 | elem_ty: Type, | 25103 | elem_ty: Type, |
| 25082 | a_arg: Air.Inst.Ref, | 25104 | a_arg: Air.Inst.Ref, |
| 25083 | b_arg: Air.Inst.Ref, | 25105 | b_arg: Air.Inst.Ref, |
| ... | @@ -27004,7 +27026,8 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD | ... | @@ -27004,7 +27026,8 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD |
| 27004 | const gpa = zcu.gpa; | 27026 | const gpa = zcu.gpa; |
| 27005 | const ip = &zcu.intern_pool; | 27027 | const ip = &zcu.intern_pool; |
| 27006 | 27028 | ||
| 27007 | const src = block.nodeOffset(@bitCast(extended.operand)); | 27029 | const src_node: std.zig.Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand))); |
| 27030 | const src = block.nodeOffset(src_node); | ||
| 27008 | const value: Zir.Inst.BuiltinValue = @enumFromInt(extended.small); | 27031 | const value: Zir.Inst.BuiltinValue = @enumFromInt(extended.small); |
| 27009 | 27032 | ||
| 27010 | const ty = switch (value) { | 27033 | const ty = switch (value) { |
| ... | @@ -29479,7 +29502,7 @@ const CoerceOpts = struct { | ... | @@ -29479,7 +29502,7 @@ const CoerceOpts = struct { |
| 29479 | return .{ | 29502 | return .{ |
| 29480 | .base_node_inst = func_inst, | 29503 | .base_node_inst = func_inst, |
| 29481 | .offset = .{ .fn_proto_param_type = .{ | 29504 | .offset = .{ .fn_proto_param_type = .{ |
| 29482 | .fn_proto_node_offset = 0, | 29505 | .fn_proto_node_offset = .zero, |
| 29483 | .param_index = info.param_i, | 29506 | .param_index = info.param_i, |
| 29484 | } }, | 29507 | } }, |
| 29485 | }; | 29508 | }; |
| ... | @@ -30084,7 +30107,7 @@ fn coerceExtra( | ... | @@ -30084,7 +30107,7 @@ fn coerceExtra( |
| 30084 | 30107 | ||
| 30085 | const ret_ty_src: LazySrcLoc = .{ | 30108 | const ret_ty_src: LazySrcLoc = .{ |
| 30086 | .base_node_inst = ip.getNav(zcu.funcInfo(sema.func_index).owner_nav).srcInst(ip), | 30109 | .base_node_inst = ip.getNav(zcu.funcInfo(sema.func_index).owner_nav).srcInst(ip), |
| 30087 | .offset = .{ .node_offset_fn_type_ret_ty = 0 }, | 30110 | .offset = .{ .node_offset_fn_type_ret_ty = .zero }, |
| 30088 | }; | 30111 | }; |
| 30089 | try sema.errNote(ret_ty_src, msg, "'noreturn' declared here", .{}); | 30112 | try sema.errNote(ret_ty_src, msg, "'noreturn' declared here", .{}); |
| 30090 | break :msg msg; | 30113 | break :msg msg; |
| ... | @@ -30124,7 +30147,7 @@ fn coerceExtra( | ... | @@ -30124,7 +30147,7 @@ fn coerceExtra( |
| 30124 | { | 30147 | { |
| 30125 | const ret_ty_src: LazySrcLoc = .{ | 30148 | const ret_ty_src: LazySrcLoc = .{ |
| 30126 | .base_node_inst = ip.getNav(zcu.funcInfo(sema.func_index).owner_nav).srcInst(ip), | 30149 | .base_node_inst = ip.getNav(zcu.funcInfo(sema.func_index).owner_nav).srcInst(ip), |
| 30127 | .offset = .{ .node_offset_fn_type_ret_ty = 0 }, | 30150 | .offset = .{ .node_offset_fn_type_ret_ty = .zero }, |
| 30128 | }; | 30151 | }; |
| 30129 | if (inst_ty.isError(zcu) and !dest_ty.isError(zcu)) { | 30152 | if (inst_ty.isError(zcu) and !dest_ty.isError(zcu)) { |
| 30130 | try sema.errNote(ret_ty_src, msg, "function cannot return an error", .{}); | 30153 | try sema.errNote(ret_ty_src, msg, "function cannot return an error", .{}); |
| ... | @@ -32325,7 +32348,7 @@ pub fn ensureNavResolved(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav | ... | @@ -32325,7 +32348,7 @@ pub fn ensureNavResolved(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav |
| 32325 | if (zcu.analysis_in_progress.contains(anal_unit)) { | 32348 | if (zcu.analysis_in_progress.contains(anal_unit)) { |
| 32326 | return sema.failWithOwnedErrorMsg(null, try sema.errMsg(.{ | 32349 | return sema.failWithOwnedErrorMsg(null, try sema.errMsg(.{ |
| 32327 | .base_node_inst = nav.analysis.?.zir_index, | 32350 | .base_node_inst = nav.analysis.?.zir_index, |
| 32328 | .offset = LazySrcLoc.Offset.nodeOffset(0), | 32351 | .offset = LazySrcLoc.Offset.nodeOffset(.zero), |
| 32329 | }, "dependency loop detected", .{})); | 32352 | }, "dependency loop detected", .{})); |
| 32330 | } | 32353 | } |
| 32331 | 32354 | ||
| ... | @@ -33942,7 +33965,7 @@ const PeerTypeCandidateSrc = union(enum) { | ... | @@ -33942,7 +33965,7 @@ const PeerTypeCandidateSrc = union(enum) { |
| 33942 | /// index i in this slice | 33965 | /// index i in this slice |
| 33943 | override: []const ?LazySrcLoc, | 33966 | override: []const ?LazySrcLoc, |
| 33944 | /// resolvePeerTypes originates from a @TypeOf(...) call | 33967 | /// resolvePeerTypes originates from a @TypeOf(...) call |
| 33945 | typeof_builtin_call_node_offset: i32, | 33968 | typeof_builtin_call_node_offset: std.zig.Ast.Node.Offset, |
| 33946 | 33969 | ||
| 33947 | pub fn resolve( | 33970 | pub fn resolve( |
| 33948 | self: PeerTypeCandidateSrc, | 33971 | self: PeerTypeCandidateSrc, |
| ... | @@ -35545,7 +35568,7 @@ fn backingIntType( | ... | @@ -35545,7 +35568,7 @@ fn backingIntType( |
| 35545 | 35568 | ||
| 35546 | const backing_int_src: LazySrcLoc = .{ | 35569 | const backing_int_src: LazySrcLoc = .{ |
| 35547 | .base_node_inst = struct_type.zir_index, | 35570 | .base_node_inst = struct_type.zir_index, |
| 35548 | .offset = .{ .node_offset_container_tag = 0 }, | 35571 | .offset = .{ .node_offset_container_tag = .zero }, |
| 35549 | }; | 35572 | }; |
| 35550 | block.comptime_reason = .{ .reason = .{ | 35573 | block.comptime_reason = .{ .reason = .{ |
| 35551 | .src = backing_int_src, | 35574 | .src = backing_int_src, |
| ... | @@ -35566,7 +35589,7 @@ fn backingIntType( | ... | @@ -35566,7 +35589,7 @@ fn backingIntType( |
| 35566 | struct_type.setBackingIntType(ip, backing_int_ty.toIntern()); | 35589 | struct_type.setBackingIntType(ip, backing_int_ty.toIntern()); |
| 35567 | } else { | 35590 | } else { |
| 35568 | if (fields_bit_sum > std.math.maxInt(u16)) { | 35591 | if (fields_bit_sum > std.math.maxInt(u16)) { |
| 35569 | return sema.fail(&block, block.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum}); | 35592 | return sema.fail(&block, block.nodeOffset(.zero), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum}); |
| 35570 | } | 35593 | } |
| 35571 | const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum)); | 35594 | const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum)); |
| 35572 | struct_type.setBackingIntType(ip, backing_int_ty.toIntern()); | 35595 | struct_type.setBackingIntType(ip, backing_int_ty.toIntern()); |
| ... | @@ -36167,7 +36190,7 @@ fn structFields( | ... | @@ -36167,7 +36190,7 @@ fn structFields( |
| 36167 | .comptime_reason = .{ .reason = .{ | 36190 | .comptime_reason = .{ .reason = .{ |
| 36168 | .src = .{ | 36191 | .src = .{ |
| 36169 | .base_node_inst = struct_type.zir_index, | 36192 | .base_node_inst = struct_type.zir_index, |
| 36170 | .offset = .nodeOffset(0), | 36193 | .offset = .nodeOffset(.zero), |
| 36171 | }, | 36194 | }, |
| 36172 | .r = .{ .simple = .struct_fields }, | 36195 | .r = .{ .simple = .struct_fields }, |
| 36173 | } }, | 36196 | } }, |
| ... | @@ -36508,7 +36531,7 @@ fn unionFields( | ... | @@ -36508,7 +36531,7 @@ fn unionFields( |
| 36508 | 36531 | ||
| 36509 | const src: LazySrcLoc = .{ | 36532 | const src: LazySrcLoc = .{ |
| 36510 | .base_node_inst = union_type.zir_index, | 36533 | .base_node_inst = union_type.zir_index, |
| 36511 | .offset = .nodeOffset(0), | 36534 | .offset = .nodeOffset(.zero), |
| 36512 | }; | 36535 | }; |
| 36513 | 36536 | ||
| 36514 | var block_scope: Block = .{ | 36537 | var block_scope: Block = .{ |
| ... | @@ -36537,7 +36560,7 @@ fn unionFields( | ... | @@ -36537,7 +36560,7 @@ fn unionFields( |
| 36537 | if (tag_type_ref != .none) { | 36560 | if (tag_type_ref != .none) { |
| 36538 | const tag_ty_src: LazySrcLoc = .{ | 36561 | const tag_ty_src: LazySrcLoc = .{ |
| 36539 | .base_node_inst = union_type.zir_index, | 36562 | .base_node_inst = union_type.zir_index, |
| 36540 | .offset = .{ .node_offset_container_tag = 0 }, | 36563 | .offset = .{ .node_offset_container_tag = .zero }, |
| 36541 | }; | 36564 | }; |
| 36542 | const provided_ty = try sema.resolveType(&block_scope, tag_ty_src, tag_type_ref); | 36565 | const provided_ty = try sema.resolveType(&block_scope, tag_ty_src, tag_type_ref); |
| 36543 | if (small.auto_enum_tag) { | 36566 | if (small.auto_enum_tag) { |
| ... | @@ -38512,7 +38535,7 @@ pub fn resolveDeclaredEnum( | ... | @@ -38512,7 +38535,7 @@ pub fn resolveDeclaredEnum( |
| 38512 | const zcu = pt.zcu; | 38535 | const zcu = pt.zcu; |
| 38513 | const gpa = zcu.gpa; | 38536 | const gpa = zcu.gpa; |
| 38514 | 38537 | ||
| 38515 | const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(0) }; | 38538 | const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(.zero) }; |
| 38516 | 38539 | ||
| 38517 | var arena: std.heap.ArenaAllocator = .init(gpa); | 38540 | var arena: std.heap.ArenaAllocator = .init(gpa); |
| 38518 | defer arena.deinit(); | 38541 | defer arena.deinit(); |
| ... | @@ -38599,7 +38622,7 @@ fn resolveDeclaredEnumInner( | ... | @@ -38599,7 +38622,7 @@ fn resolveDeclaredEnumInner( |
| 38599 | 38622 | ||
| 38600 | const bit_bags_count = std.math.divCeil(usize, fields_len, 32) catch unreachable; | 38623 | const bit_bags_count = std.math.divCeil(usize, fields_len, 32) catch unreachable; |
| 38601 | 38624 | ||
| 38602 | const tag_ty_src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = .{ .node_offset_container_tag = 0 } }; | 38625 | const tag_ty_src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = .{ .node_offset_container_tag = .zero } }; |
| 38603 | 38626 | ||
| 38604 | const int_tag_ty = ty: { | 38627 | const int_tag_ty = ty: { |
| 38605 | if (body.len != 0) { | 38628 | if (body.len != 0) { |
| ... | @@ -38752,9 +38775,9 @@ pub fn resolveNavPtrModifiers( | ... | @@ -38752,9 +38775,9 @@ pub fn resolveNavPtrModifiers( |
| 38752 | const gpa = zcu.gpa; | 38775 | const gpa = zcu.gpa; |
| 38753 | const ip = &zcu.intern_pool; | 38776 | const ip = &zcu.intern_pool; |
| 38754 | 38777 | ||
| 38755 | const align_src = block.src(.{ .node_offset_var_decl_align = 0 }); | 38778 | const align_src = block.src(.{ .node_offset_var_decl_align = .zero }); |
| 38756 | const section_src = block.src(.{ .node_offset_var_decl_section = 0 }); | 38779 | const section_src = block.src(.{ .node_offset_var_decl_section = .zero }); |
| 38757 | const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = 0 }); | 38780 | const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = .zero }); |
| 38758 | 38781 | ||
| 38759 | const alignment: InternPool.Alignment = a: { | 38782 | const alignment: InternPool.Alignment = a: { |
| 38760 | const align_body = zir_decl.align_body orelse break :a .none; | 38783 | const align_body = zir_decl.align_body orelse break :a .none; |
| ... | @@ -38827,7 +38850,7 @@ pub fn analyzeMemoizedState(sema: *Sema, block: *Block, simple_src: LazySrcLoc, | ... | @@ -38827,7 +38850,7 @@ pub fn analyzeMemoizedState(sema: *Sema, block: *Block, simple_src: LazySrcLoc, |
| 38827 | 38850 | ||
| 38828 | const src: LazySrcLoc = .{ | 38851 | const src: LazySrcLoc = .{ |
| 38829 | .base_node_inst = ip.getNav(nav).srcInst(ip), | 38852 | .base_node_inst = ip.getNav(nav).srcInst(ip), |
| 38830 | .offset = .nodeOffset(0), | 38853 | .offset = .nodeOffset(.zero), |
| 38831 | }; | 38854 | }; |
| 38832 | 38855 | ||
| 38833 | const result = try sema.analyzeNavVal(block, src, nav); | 38856 | const result = try sema.analyzeNavVal(block, src, nav); |
src/Type.zig+1-1| ... | @@ -3505,7 +3505,7 @@ pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Zcu.LazySrcLoc { | ... | @@ -3505,7 +3505,7 @@ pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Zcu.LazySrcLoc { |
| 3505 | }, | 3505 | }, |
| 3506 | else => return null, | 3506 | else => return null, |
| 3507 | }, | 3507 | }, |
| 3508 | .offset = Zcu.LazySrcLoc.Offset.nodeOffset(0), | 3508 | .offset = Zcu.LazySrcLoc.Offset.nodeOffset(.zero), |
| 3509 | }; | 3509 | }; |
| 3510 | } | 3510 | } |
| 3511 | 3511 |
src/Zcu.zig+278-295| ... | @@ -134,7 +134,7 @@ failed_types: std.AutoArrayHashMapUnmanaged(InternPool.Index, *ErrorMsg) = .empt | ... | @@ -134,7 +134,7 @@ failed_types: std.AutoArrayHashMapUnmanaged(InternPool.Index, *ErrorMsg) = .empt |
| 134 | /// The value is the source location of the `@compileLog` call, convertible to a `LazySrcLoc`. | 134 | /// The value is the source location of the `@compileLog` call, convertible to a `LazySrcLoc`. |
| 135 | compile_log_sources: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct { | 135 | compile_log_sources: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct { |
| 136 | base_node_inst: InternPool.TrackedInst.Index, | 136 | base_node_inst: InternPool.TrackedInst.Index, |
| 137 | node_offset: i32, | 137 | node_offset: Ast.Node.Offset, |
| 138 | pub fn src(self: @This()) LazySrcLoc { | 138 | pub fn src(self: @This()) LazySrcLoc { |
| 139 | return .{ | 139 | return .{ |
| 140 | .base_node_inst = self.base_node_inst, | 140 | .base_node_inst = self.base_node_inst, |
| ... | @@ -1031,10 +1031,6 @@ pub const SrcLoc = struct { | ... | @@ -1031,10 +1031,6 @@ pub const SrcLoc = struct { |
| 1031 | return tree.firstToken(src_loc.base_node); | 1031 | return tree.firstToken(src_loc.base_node); |
| 1032 | } | 1032 | } |
| 1033 | 1033 | ||
| 1034 | pub fn relativeToNodeIndex(src_loc: SrcLoc, offset: i32) Ast.Node.Index { | ||
| 1035 | return @bitCast(offset + @as(i32, @bitCast(src_loc.base_node))); | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | pub const Span = Ast.Span; | 1034 | pub const Span = Ast.Span; |
| 1039 | 1035 | ||
| 1040 | pub fn span(src_loc: SrcLoc, gpa: Allocator) !Span { | 1036 | pub fn span(src_loc: SrcLoc, gpa: Allocator) !Span { |
| ... | @@ -1046,7 +1042,7 @@ pub const SrcLoc = struct { | ... | @@ -1046,7 +1042,7 @@ pub const SrcLoc = struct { |
| 1046 | 1042 | ||
| 1047 | .token_abs => |tok_index| { | 1043 | .token_abs => |tok_index| { |
| 1048 | const tree = try src_loc.file_scope.getTree(gpa); | 1044 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1049 | const start = tree.tokens.items(.start)[tok_index]; | 1045 | const start = tree.tokenStart(tok_index); |
| 1050 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1046 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1051 | return Span{ .start = start, .end = end, .main = start }; | 1047 | return Span{ .start = start, .end = end, .main = start }; |
| 1052 | }, | 1048 | }, |
| ... | @@ -1057,133 +1053,137 @@ pub const SrcLoc = struct { | ... | @@ -1057,133 +1053,137 @@ pub const SrcLoc = struct { |
| 1057 | .byte_offset => |byte_off| { | 1053 | .byte_offset => |byte_off| { |
| 1058 | const tree = try src_loc.file_scope.getTree(gpa); | 1054 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1059 | const tok_index = src_loc.baseSrcToken(); | 1055 | const tok_index = src_loc.baseSrcToken(); |
| 1060 | const start = tree.tokens.items(.start)[tok_index] + byte_off; | 1056 | const start = tree.tokenStart(tok_index) + byte_off; |
| 1061 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1057 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1062 | return Span{ .start = start, .end = end, .main = start }; | 1058 | return Span{ .start = start, .end = end, .main = start }; |
| 1063 | }, | 1059 | }, |
| 1064 | .token_offset => |tok_off| { | 1060 | .token_offset => |tok_off| { |
| 1065 | const tree = try src_loc.file_scope.getTree(gpa); | 1061 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1066 | const tok_index = src_loc.baseSrcToken() + tok_off; | 1062 | const tok_index = tok_off.toAbsolute(src_loc.baseSrcToken()); |
| 1067 | const start = tree.tokens.items(.start)[tok_index]; | 1063 | const start = tree.tokenStart(tok_index); |
| 1068 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1064 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1069 | return Span{ .start = start, .end = end, .main = start }; | 1065 | return Span{ .start = start, .end = end, .main = start }; |
| 1070 | }, | 1066 | }, |
| 1071 | .node_offset => |traced_off| { | 1067 | .node_offset => |traced_off| { |
| 1072 | const node_off = traced_off.x; | 1068 | const node_off = traced_off.x; |
| 1073 | const tree = try src_loc.file_scope.getTree(gpa); | 1069 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1074 | const node = src_loc.relativeToNodeIndex(node_off); | 1070 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1075 | return tree.nodeToSpan(node); | 1071 | return tree.nodeToSpan(node); |
| 1076 | }, | 1072 | }, |
| 1077 | .node_offset_main_token => |node_off| { | 1073 | .node_offset_main_token => |node_off| { |
| 1078 | const tree = try src_loc.file_scope.getTree(gpa); | 1074 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1079 | const node = src_loc.relativeToNodeIndex(node_off); | 1075 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1080 | const main_token = tree.nodes.items(.main_token)[node]; | 1076 | const main_token = tree.nodeMainToken(node); |
| 1081 | return tree.tokensToSpan(main_token, main_token, main_token); | 1077 | return tree.tokensToSpan(main_token, main_token, main_token); |
| 1082 | }, | 1078 | }, |
| 1083 | .node_offset_bin_op => |node_off| { | 1079 | .node_offset_bin_op => |node_off| { |
| 1084 | const tree = try src_loc.file_scope.getTree(gpa); | 1080 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1085 | const node = src_loc.relativeToNodeIndex(node_off); | 1081 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1086 | return tree.nodeToSpan(node); | 1082 | return tree.nodeToSpan(node); |
| 1087 | }, | 1083 | }, |
| 1088 | .node_offset_initializer => |node_off| { | 1084 | .node_offset_initializer => |node_off| { |
| 1089 | const tree = try src_loc.file_scope.getTree(gpa); | 1085 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1090 | const node = src_loc.relativeToNodeIndex(node_off); | 1086 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1091 | return tree.tokensToSpan( | 1087 | return tree.tokensToSpan( |
| 1092 | tree.firstToken(node) - 3, | 1088 | tree.firstToken(node) - 3, |
| 1093 | tree.lastToken(node), | 1089 | tree.lastToken(node), |
| 1094 | tree.nodes.items(.main_token)[node] - 2, | 1090 | tree.nodeMainToken(node) - 2, |
| 1095 | ); | 1091 | ); |
| 1096 | }, | 1092 | }, |
| 1097 | .node_offset_var_decl_ty => |node_off| { | 1093 | .node_offset_var_decl_ty => |node_off| { |
| 1098 | const tree = try src_loc.file_scope.getTree(gpa); | 1094 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1099 | const node = src_loc.relativeToNodeIndex(node_off); | 1095 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1100 | const node_tags = tree.nodes.items(.tag); | 1096 | const full = switch (tree.nodeTag(node)) { |
| 1101 | const full = switch (node_tags[node]) { | ||
| 1102 | .global_var_decl, | 1097 | .global_var_decl, |
| 1103 | .local_var_decl, | 1098 | .local_var_decl, |
| 1104 | .simple_var_decl, | 1099 | .simple_var_decl, |
| 1105 | .aligned_var_decl, | 1100 | .aligned_var_decl, |
| 1106 | => tree.fullVarDecl(node).?, | 1101 | => tree.fullVarDecl(node).?, |
| 1107 | .@"usingnamespace" => { | 1102 | .@"usingnamespace" => { |
| 1108 | const node_data = tree.nodes.items(.data); | 1103 | return tree.nodeToSpan(tree.nodeData(node).node); |
| 1109 | return tree.nodeToSpan(node_data[node].lhs); | ||
| 1110 | }, | 1104 | }, |
| 1111 | else => unreachable, | 1105 | else => unreachable, |
| 1112 | }; | 1106 | }; |
| 1113 | if (full.ast.type_node != 0) { | 1107 | if (full.ast.type_node.unwrap()) |type_node| { |
| 1114 | return tree.nodeToSpan(full.ast.type_node); | 1108 | return tree.nodeToSpan(type_node); |
| 1115 | } | 1109 | } |
| 1116 | const tok_index = full.ast.mut_token + 1; // the name token | 1110 | const tok_index = full.ast.mut_token + 1; // the name token |
| 1117 | const start = tree.tokens.items(.start)[tok_index]; | 1111 | const start = tree.tokenStart(tok_index); |
| 1118 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1112 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1119 | return Span{ .start = start, .end = end, .main = start }; | 1113 | return Span{ .start = start, .end = end, .main = start }; |
| 1120 | }, | 1114 | }, |
| 1121 | .node_offset_var_decl_align => |node_off| { | 1115 | .node_offset_var_decl_align => |node_off| { |
| 1122 | const tree = try src_loc.file_scope.getTree(gpa); | 1116 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1123 | const node = src_loc.relativeToNodeIndex(node_off); | 1117 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1124 | var buf: [1]Ast.Node.Index = undefined; | 1118 | var buf: [1]Ast.Node.Index = undefined; |
| 1125 | const align_node = if (tree.fullVarDecl(node)) |v| | 1119 | const align_node = if (tree.fullVarDecl(node)) |v| |
| 1126 | v.ast.align_node | 1120 | v.ast.align_node.unwrap().? |
| 1127 | else if (tree.fullFnProto(&buf, node)) |f| | 1121 | else if (tree.fullFnProto(&buf, node)) |f| |
| 1128 | f.ast.align_expr | 1122 | f.ast.align_expr.unwrap().? |
| 1129 | else | 1123 | else |
| 1130 | unreachable; | 1124 | unreachable; |
| 1131 | return tree.nodeToSpan(align_node); | 1125 | return tree.nodeToSpan(align_node); |
| 1132 | }, | 1126 | }, |
| 1133 | .node_offset_var_decl_section => |node_off| { | 1127 | .node_offset_var_decl_section => |node_off| { |
| 1134 | const tree = try src_loc.file_scope.getTree(gpa); | 1128 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1135 | const node = src_loc.relativeToNodeIndex(node_off); | 1129 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1136 | var buf: [1]Ast.Node.Index = undefined; | 1130 | var buf: [1]Ast.Node.Index = undefined; |
| 1137 | const section_node = if (tree.fullVarDecl(node)) |v| | 1131 | const section_node = if (tree.fullVarDecl(node)) |v| |
| 1138 | v.ast.section_node | 1132 | v.ast.section_node.unwrap().? |
| 1139 | else if (tree.fullFnProto(&buf, node)) |f| | 1133 | else if (tree.fullFnProto(&buf, node)) |f| |
| 1140 | f.ast.section_expr | 1134 | f.ast.section_expr.unwrap().? |
| 1141 | else | 1135 | else |
| 1142 | unreachable; | 1136 | unreachable; |
| 1143 | return tree.nodeToSpan(section_node); | 1137 | return tree.nodeToSpan(section_node); |
| 1144 | }, | 1138 | }, |
| 1145 | .node_offset_var_decl_addrspace => |node_off| { | 1139 | .node_offset_var_decl_addrspace => |node_off| { |
| 1146 | const tree = try src_loc.file_scope.getTree(gpa); | 1140 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1147 | const node = src_loc.relativeToNodeIndex(node_off); | 1141 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1148 | var buf: [1]Ast.Node.Index = undefined; | 1142 | var buf: [1]Ast.Node.Index = undefined; |
| 1149 | const addrspace_node = if (tree.fullVarDecl(node)) |v| | 1143 | const addrspace_node = if (tree.fullVarDecl(node)) |v| |
| 1150 | v.ast.addrspace_node | 1144 | v.ast.addrspace_node.unwrap().? |
| 1151 | else if (tree.fullFnProto(&buf, node)) |f| | 1145 | else if (tree.fullFnProto(&buf, node)) |f| |
| 1152 | f.ast.addrspace_expr | 1146 | f.ast.addrspace_expr.unwrap().? |
| 1153 | else | 1147 | else |
| 1154 | unreachable; | 1148 | unreachable; |
| 1155 | return tree.nodeToSpan(addrspace_node); | 1149 | return tree.nodeToSpan(addrspace_node); |
| 1156 | }, | 1150 | }, |
| 1157 | .node_offset_var_decl_init => |node_off| { | 1151 | .node_offset_var_decl_init => |node_off| { |
| 1158 | const tree = try src_loc.file_scope.getTree(gpa); | 1152 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1159 | const node = src_loc.relativeToNodeIndex(node_off); | 1153 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1160 | const full = tree.fullVarDecl(node).?; | 1154 | const init_node = switch (tree.nodeTag(node)) { |
| 1161 | return tree.nodeToSpan(full.ast.init_node); | 1155 | .global_var_decl, |
| 1156 | .local_var_decl, | ||
| 1157 | .aligned_var_decl, | ||
| 1158 | .simple_var_decl, | ||
| 1159 | => tree.fullVarDecl(node).?.ast.init_node.unwrap().?, | ||
| 1160 | .assign_destructure => tree.assignDestructure(node).ast.value_expr, | ||
| 1161 | else => unreachable, | ||
| 1162 | }; | ||
| 1163 | return tree.nodeToSpan(init_node); | ||
| 1162 | }, | 1164 | }, |
| 1163 | .node_offset_builtin_call_arg => |builtin_arg| { | 1165 | .node_offset_builtin_call_arg => |builtin_arg| { |
| 1164 | const tree = try src_loc.file_scope.getTree(gpa); | 1166 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1165 | const node = src_loc.relativeToNodeIndex(builtin_arg.builtin_call_node); | 1167 | const node = builtin_arg.builtin_call_node.toAbsolute(src_loc.base_node); |
| 1166 | var buf: [2]Ast.Node.Index = undefined; | 1168 | var buf: [2]Ast.Node.Index = undefined; |
| 1167 | const params = tree.builtinCallParams(&buf, node).?; | 1169 | const params = tree.builtinCallParams(&buf, node).?; |
| 1168 | return tree.nodeToSpan(params[builtin_arg.arg_index]); | 1170 | return tree.nodeToSpan(params[builtin_arg.arg_index]); |
| 1169 | }, | 1171 | }, |
| 1170 | .node_offset_ptrcast_operand => |node_off| { | 1172 | .node_offset_ptrcast_operand => |node_off| { |
| 1171 | const tree = try src_loc.file_scope.getTree(gpa); | 1173 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1172 | const main_tokens = tree.nodes.items(.main_token); | ||
| 1173 | const node_datas = tree.nodes.items(.data); | ||
| 1174 | const node_tags = tree.nodes.items(.tag); | ||
| 1175 | 1174 | ||
| 1176 | var node = src_loc.relativeToNodeIndex(node_off); | 1175 | var node = node_off.toAbsolute(src_loc.base_node); |
| 1177 | while (true) { | 1176 | while (true) { |
| 1178 | switch (node_tags[node]) { | 1177 | switch (tree.nodeTag(node)) { |
| 1179 | .builtin_call_two, .builtin_call_two_comma => {}, | 1178 | .builtin_call_two, .builtin_call_two_comma => {}, |
| 1180 | else => break, | 1179 | else => break, |
| 1181 | } | 1180 | } |
| 1182 | 1181 | ||
| 1183 | if (node_datas[node].lhs == 0) break; // 0 args | 1182 | const first_arg, const second_arg = tree.nodeData(node).opt_node_and_opt_node; |
| 1184 | if (node_datas[node].rhs != 0) break; // 2 args | 1183 | if (first_arg == .none) break; // 0 args |
| 1184 | if (second_arg != .none) break; // 2 args | ||
| 1185 | 1185 | ||
| 1186 | const builtin_token = main_tokens[node]; | 1186 | const builtin_token = tree.nodeMainToken(node); |
| 1187 | const builtin_name = tree.tokenSlice(builtin_token); | 1187 | const builtin_name = tree.tokenSlice(builtin_token); |
| 1188 | const info = BuiltinFn.list.get(builtin_name) orelse break; | 1188 | const info = BuiltinFn.list.get(builtin_name) orelse break; |
| 1189 | 1189 | ||
| ... | @@ -1197,16 +1197,15 @@ pub const SrcLoc = struct { | ... | @@ -1197,16 +1197,15 @@ pub const SrcLoc = struct { |
| 1197 | => {}, | 1197 | => {}, |
| 1198 | } | 1198 | } |
| 1199 | 1199 | ||
| 1200 | node = node_datas[node].lhs; | 1200 | node = first_arg.unwrap().?; |
| 1201 | } | 1201 | } |
| 1202 | 1202 | ||
| 1203 | return tree.nodeToSpan(node); | 1203 | return tree.nodeToSpan(node); |
| 1204 | }, | 1204 | }, |
| 1205 | .node_offset_array_access_index => |node_off| { | 1205 | .node_offset_array_access_index => |node_off| { |
| 1206 | const tree = try src_loc.file_scope.getTree(gpa); | 1206 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1207 | const node_datas = tree.nodes.items(.data); | 1207 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1208 | const node = src_loc.relativeToNodeIndex(node_off); | 1208 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[1]); |
| 1209 | return tree.nodeToSpan(node_datas[node].rhs); | ||
| 1210 | }, | 1209 | }, |
| 1211 | .node_offset_slice_ptr, | 1210 | .node_offset_slice_ptr, |
| 1212 | .node_offset_slice_start, | 1211 | .node_offset_slice_start, |
| ... | @@ -1214,32 +1213,30 @@ pub const SrcLoc = struct { | ... | @@ -1214,32 +1213,30 @@ pub const SrcLoc = struct { |
| 1214 | .node_offset_slice_sentinel, | 1213 | .node_offset_slice_sentinel, |
| 1215 | => |node_off| { | 1214 | => |node_off| { |
| 1216 | const tree = try src_loc.file_scope.getTree(gpa); | 1215 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1217 | const node = src_loc.relativeToNodeIndex(node_off); | 1216 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1218 | const full = tree.fullSlice(node).?; | 1217 | const full = tree.fullSlice(node).?; |
| 1219 | const part_node = switch (src_loc.lazy) { | 1218 | const part_node = switch (src_loc.lazy) { |
| 1220 | .node_offset_slice_ptr => full.ast.sliced, | 1219 | .node_offset_slice_ptr => full.ast.sliced, |
| 1221 | .node_offset_slice_start => full.ast.start, | 1220 | .node_offset_slice_start => full.ast.start, |
| 1222 | .node_offset_slice_end => full.ast.end, | 1221 | .node_offset_slice_end => full.ast.end.unwrap().?, |
| 1223 | .node_offset_slice_sentinel => full.ast.sentinel, | 1222 | .node_offset_slice_sentinel => full.ast.sentinel.unwrap().?, |
| 1224 | else => unreachable, | 1223 | else => unreachable, |
| 1225 | }; | 1224 | }; |
| 1226 | return tree.nodeToSpan(part_node); | 1225 | return tree.nodeToSpan(part_node); |
| 1227 | }, | 1226 | }, |
| 1228 | .node_offset_call_func => |node_off| { | 1227 | .node_offset_call_func => |node_off| { |
| 1229 | const tree = try src_loc.file_scope.getTree(gpa); | 1228 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1230 | const node = src_loc.relativeToNodeIndex(node_off); | 1229 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1231 | var buf: [1]Ast.Node.Index = undefined; | 1230 | var buf: [1]Ast.Node.Index = undefined; |
| 1232 | const full = tree.fullCall(&buf, node).?; | 1231 | const full = tree.fullCall(&buf, node).?; |
| 1233 | return tree.nodeToSpan(full.ast.fn_expr); | 1232 | return tree.nodeToSpan(full.ast.fn_expr); |
| 1234 | }, | 1233 | }, |
| 1235 | .node_offset_field_name => |node_off| { | 1234 | .node_offset_field_name => |node_off| { |
| 1236 | const tree = try src_loc.file_scope.getTree(gpa); | 1235 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1237 | const node_datas = tree.nodes.items(.data); | 1236 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1238 | const node_tags = tree.nodes.items(.tag); | ||
| 1239 | const node = src_loc.relativeToNodeIndex(node_off); | ||
| 1240 | var buf: [1]Ast.Node.Index = undefined; | 1237 | var buf: [1]Ast.Node.Index = undefined; |
| 1241 | const tok_index = switch (node_tags[node]) { | 1238 | const tok_index = switch (tree.nodeTag(node)) { |
| 1242 | .field_access => node_datas[node].rhs, | 1239 | .field_access => tree.nodeData(node).node_and_token[1], |
| 1243 | .call_one, | 1240 | .call_one, |
| 1244 | .call_one_comma, | 1241 | .call_one_comma, |
| 1245 | .async_call_one, | 1242 | .async_call_one, |
| ... | @@ -1254,43 +1251,41 @@ pub const SrcLoc = struct { | ... | @@ -1254,43 +1251,41 @@ pub const SrcLoc = struct { |
| 1254 | }, | 1251 | }, |
| 1255 | else => tree.firstToken(node) - 2, | 1252 | else => tree.firstToken(node) - 2, |
| 1256 | }; | 1253 | }; |
| 1257 | const start = tree.tokens.items(.start)[tok_index]; | 1254 | const start = tree.tokenStart(tok_index); |
| 1258 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1255 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1259 | return Span{ .start = start, .end = end, .main = start }; | 1256 | return Span{ .start = start, .end = end, .main = start }; |
| 1260 | }, | 1257 | }, |
| 1261 | .node_offset_field_name_init => |node_off| { | 1258 | .node_offset_field_name_init => |node_off| { |
| 1262 | const tree = try src_loc.file_scope.getTree(gpa); | 1259 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1263 | const node = src_loc.relativeToNodeIndex(node_off); | 1260 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1264 | const tok_index = tree.firstToken(node) - 2; | 1261 | const tok_index = tree.firstToken(node) - 2; |
| 1265 | const start = tree.tokens.items(.start)[tok_index]; | 1262 | const start = tree.tokenStart(tok_index); |
| 1266 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1263 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1267 | return Span{ .start = start, .end = end, .main = start }; | 1264 | return Span{ .start = start, .end = end, .main = start }; |
| 1268 | }, | 1265 | }, |
| 1269 | .node_offset_deref_ptr => |node_off| { | 1266 | .node_offset_deref_ptr => |node_off| { |
| 1270 | const tree = try src_loc.file_scope.getTree(gpa); | 1267 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1271 | const node = src_loc.relativeToNodeIndex(node_off); | 1268 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1272 | return tree.nodeToSpan(node); | 1269 | return tree.nodeToSpan(node); |
| 1273 | }, | 1270 | }, |
| 1274 | .node_offset_asm_source => |node_off| { | 1271 | .node_offset_asm_source => |node_off| { |
| 1275 | const tree = try src_loc.file_scope.getTree(gpa); | 1272 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1276 | const node = src_loc.relativeToNodeIndex(node_off); | 1273 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1277 | const full = tree.fullAsm(node).?; | 1274 | const full = tree.fullAsm(node).?; |
| 1278 | return tree.nodeToSpan(full.ast.template); | 1275 | return tree.nodeToSpan(full.ast.template); |
| 1279 | }, | 1276 | }, |
| 1280 | .node_offset_asm_ret_ty => |node_off| { | 1277 | .node_offset_asm_ret_ty => |node_off| { |
| 1281 | const tree = try src_loc.file_scope.getTree(gpa); | 1278 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1282 | const node = src_loc.relativeToNodeIndex(node_off); | 1279 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1283 | const full = tree.fullAsm(node).?; | 1280 | const full = tree.fullAsm(node).?; |
| 1284 | const asm_output = full.outputs[0]; | 1281 | const asm_output = full.outputs[0]; |
| 1285 | const node_datas = tree.nodes.items(.data); | 1282 | return tree.nodeToSpan(tree.nodeData(asm_output).opt_node_and_token[0].unwrap().?); |
| 1286 | return tree.nodeToSpan(node_datas[asm_output].lhs); | ||
| 1287 | }, | 1283 | }, |
| 1288 | 1284 | ||
| 1289 | .node_offset_if_cond => |node_off| { | 1285 | .node_offset_if_cond => |node_off| { |
| 1290 | const tree = try src_loc.file_scope.getTree(gpa); | 1286 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1291 | const node = src_loc.relativeToNodeIndex(node_off); | 1287 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1292 | const node_tags = tree.nodes.items(.tag); | 1288 | const src_node = switch (tree.nodeTag(node)) { |
| 1293 | const src_node = switch (node_tags[node]) { | ||
| 1294 | .if_simple, | 1289 | .if_simple, |
| 1295 | .@"if", | 1290 | .@"if", |
| 1296 | => tree.fullIf(node).?.ast.cond_expr, | 1291 | => tree.fullIf(node).?.ast.cond_expr, |
| ... | @@ -1317,20 +1312,19 @@ pub const SrcLoc = struct { | ... | @@ -1317,20 +1312,19 @@ pub const SrcLoc = struct { |
| 1317 | }, | 1312 | }, |
| 1318 | .for_input => |for_input| { | 1313 | .for_input => |for_input| { |
| 1319 | const tree = try src_loc.file_scope.getTree(gpa); | 1314 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1320 | const node = src_loc.relativeToNodeIndex(for_input.for_node_offset); | 1315 | const node = for_input.for_node_offset.toAbsolute(src_loc.base_node); |
| 1321 | const for_full = tree.fullFor(node).?; | 1316 | const for_full = tree.fullFor(node).?; |
| 1322 | const src_node = for_full.ast.inputs[for_input.input_index]; | 1317 | const src_node = for_full.ast.inputs[for_input.input_index]; |
| 1323 | return tree.nodeToSpan(src_node); | 1318 | return tree.nodeToSpan(src_node); |
| 1324 | }, | 1319 | }, |
| 1325 | .for_capture_from_input => |node_off| { | 1320 | .for_capture_from_input => |node_off| { |
| 1326 | const tree = try src_loc.file_scope.getTree(gpa); | 1321 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1327 | const token_tags = tree.tokens.items(.tag); | 1322 | const input_node = node_off.toAbsolute(src_loc.base_node); |
| 1328 | const input_node = src_loc.relativeToNodeIndex(node_off); | ||
| 1329 | // We have to actually linear scan the whole AST to find the for loop | 1323 | // We have to actually linear scan the whole AST to find the for loop |
| 1330 | // that contains this input. | 1324 | // that contains this input. |
| 1331 | const node_tags = tree.nodes.items(.tag); | 1325 | const node_tags = tree.nodes.items(.tag); |
| 1332 | for (node_tags, 0..) |node_tag, node_usize| { | 1326 | for (node_tags, 0..) |node_tag, node_usize| { |
| 1333 | const node = @as(Ast.Node.Index, @intCast(node_usize)); | 1327 | const node: Ast.Node.Index = @enumFromInt(node_usize); |
| 1334 | switch (node_tag) { | 1328 | switch (node_tag) { |
| 1335 | .for_simple, .@"for" => { | 1329 | .for_simple, .@"for" => { |
| 1336 | const for_full = tree.fullFor(node).?; | 1330 | const for_full = tree.fullFor(node).?; |
| ... | @@ -1339,7 +1333,7 @@ pub const SrcLoc = struct { | ... | @@ -1339,7 +1333,7 @@ pub const SrcLoc = struct { |
| 1339 | var count = input_index; | 1333 | var count = input_index; |
| 1340 | var tok = for_full.payload_token; | 1334 | var tok = for_full.payload_token; |
| 1341 | while (true) { | 1335 | while (true) { |
| 1342 | switch (token_tags[tok]) { | 1336 | switch (tree.tokenTag(tok)) { |
| 1343 | .comma => { | 1337 | .comma => { |
| 1344 | count -= 1; | 1338 | count -= 1; |
| 1345 | tok += 1; | 1339 | tok += 1; |
| ... | @@ -1366,13 +1360,12 @@ pub const SrcLoc = struct { | ... | @@ -1366,13 +1360,12 @@ pub const SrcLoc = struct { |
| 1366 | }, | 1360 | }, |
| 1367 | .call_arg => |call_arg| { | 1361 | .call_arg => |call_arg| { |
| 1368 | const tree = try src_loc.file_scope.getTree(gpa); | 1362 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1369 | const node = src_loc.relativeToNodeIndex(call_arg.call_node_offset); | 1363 | const node = call_arg.call_node_offset.toAbsolute(src_loc.base_node); |
| 1370 | var buf: [2]Ast.Node.Index = undefined; | 1364 | var buf: [2]Ast.Node.Index = undefined; |
| 1371 | const call_full = tree.fullCall(buf[0..1], node) orelse { | 1365 | const call_full = tree.fullCall(buf[0..1], node) orelse { |
| 1372 | const node_tags = tree.nodes.items(.tag); | 1366 | assert(tree.nodeTag(node) == .builtin_call); |
| 1373 | assert(node_tags[node] == .builtin_call); | 1367 | const call_args_node: Ast.Node.Index = @enumFromInt(tree.extra_data[@intFromEnum(tree.nodeData(node).extra_range.end) - 1]); |
| 1374 | const call_args_node = tree.extra_data[tree.nodes.items(.data)[node].rhs - 1]; | 1368 | switch (tree.nodeTag(call_args_node)) { |
| 1375 | switch (node_tags[call_args_node]) { | ||
| 1376 | .array_init_one, | 1369 | .array_init_one, |
| 1377 | .array_init_one_comma, | 1370 | .array_init_one_comma, |
| 1378 | .array_init_dot_two, | 1371 | .array_init_dot_two, |
| ... | @@ -1404,7 +1397,7 @@ pub const SrcLoc = struct { | ... | @@ -1404,7 +1397,7 @@ pub const SrcLoc = struct { |
| 1404 | }, | 1397 | }, |
| 1405 | .fn_proto_param, .fn_proto_param_type => |fn_proto_param| { | 1398 | .fn_proto_param, .fn_proto_param_type => |fn_proto_param| { |
| 1406 | const tree = try src_loc.file_scope.getTree(gpa); | 1399 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1407 | const node = src_loc.relativeToNodeIndex(fn_proto_param.fn_proto_node_offset); | 1400 | const node = fn_proto_param.fn_proto_node_offset.toAbsolute(src_loc.base_node); |
| 1408 | var buf: [1]Ast.Node.Index = undefined; | 1401 | var buf: [1]Ast.Node.Index = undefined; |
| 1409 | const full = tree.fullFnProto(&buf, node).?; | 1402 | const full = tree.fullFnProto(&buf, node).?; |
| 1410 | var it = full.iterate(tree); | 1403 | var it = full.iterate(tree); |
| ... | @@ -1416,14 +1409,14 @@ pub const SrcLoc = struct { | ... | @@ -1416,14 +1409,14 @@ pub const SrcLoc = struct { |
| 1416 | .fn_proto_param_type => if (param.anytype_ellipsis3) |tok| { | 1409 | .fn_proto_param_type => if (param.anytype_ellipsis3) |tok| { |
| 1417 | return tree.tokenToSpan(tok); | 1410 | return tree.tokenToSpan(tok); |
| 1418 | } else { | 1411 | } else { |
| 1419 | return tree.nodeToSpan(param.type_expr); | 1412 | return tree.nodeToSpan(param.type_expr.?); |
| 1420 | }, | 1413 | }, |
| 1421 | .fn_proto_param => if (param.anytype_ellipsis3) |tok| { | 1414 | .fn_proto_param => if (param.anytype_ellipsis3) |tok| { |
| 1422 | const first = param.comptime_noalias orelse param.name_token orelse tok; | 1415 | const first = param.comptime_noalias orelse param.name_token orelse tok; |
| 1423 | return tree.tokensToSpan(first, tok, first); | 1416 | return tree.tokensToSpan(first, tok, first); |
| 1424 | } else { | 1417 | } else { |
| 1425 | const first = param.comptime_noalias orelse param.name_token orelse tree.firstToken(param.type_expr); | 1418 | const first = param.comptime_noalias orelse param.name_token orelse tree.firstToken(param.type_expr.?); |
| 1426 | return tree.tokensToSpan(first, tree.lastToken(param.type_expr), first); | 1419 | return tree.tokensToSpan(first, tree.lastToken(param.type_expr.?), first); |
| 1427 | }, | 1420 | }, |
| 1428 | else => unreachable, | 1421 | else => unreachable, |
| 1429 | } | 1422 | } |
| ... | @@ -1432,28 +1425,24 @@ pub const SrcLoc = struct { | ... | @@ -1432,28 +1425,24 @@ pub const SrcLoc = struct { |
| 1432 | }, | 1425 | }, |
| 1433 | .node_offset_bin_lhs => |node_off| { | 1426 | .node_offset_bin_lhs => |node_off| { |
| 1434 | const tree = try src_loc.file_scope.getTree(gpa); | 1427 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1435 | const node = src_loc.relativeToNodeIndex(node_off); | 1428 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1436 | const node_datas = tree.nodes.items(.data); | 1429 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[0]); |
| 1437 | return tree.nodeToSpan(node_datas[node].lhs); | ||
| 1438 | }, | 1430 | }, |
| 1439 | .node_offset_bin_rhs => |node_off| { | 1431 | .node_offset_bin_rhs => |node_off| { |
| 1440 | const tree = try src_loc.file_scope.getTree(gpa); | 1432 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1441 | const node = src_loc.relativeToNodeIndex(node_off); | 1433 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1442 | const node_datas = tree.nodes.items(.data); | 1434 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[1]); |
| 1443 | return tree.nodeToSpan(node_datas[node].rhs); | ||
| 1444 | }, | 1435 | }, |
| 1445 | .array_cat_lhs, .array_cat_rhs => |cat| { | 1436 | .array_cat_lhs, .array_cat_rhs => |cat| { |
| 1446 | const tree = try src_loc.file_scope.getTree(gpa); | 1437 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1447 | const node = src_loc.relativeToNodeIndex(cat.array_cat_offset); | 1438 | const node = cat.array_cat_offset.toAbsolute(src_loc.base_node); |
| 1448 | const node_datas = tree.nodes.items(.data); | ||
| 1449 | const arr_node = if (src_loc.lazy == .array_cat_lhs) | 1439 | const arr_node = if (src_loc.lazy == .array_cat_lhs) |
| 1450 | node_datas[node].lhs | 1440 | tree.nodeData(node).node_and_node[0] |
| 1451 | else | 1441 | else |
| 1452 | node_datas[node].rhs; | 1442 | tree.nodeData(node).node_and_node[1]; |
| 1453 | 1443 | ||
| 1454 | const node_tags = tree.nodes.items(.tag); | ||
| 1455 | var buf: [2]Ast.Node.Index = undefined; | 1444 | var buf: [2]Ast.Node.Index = undefined; |
| 1456 | switch (node_tags[arr_node]) { | 1445 | switch (tree.nodeTag(arr_node)) { |
| 1457 | .array_init_one, | 1446 | .array_init_one, |
| 1458 | .array_init_one_comma, | 1447 | .array_init_one_comma, |
| 1459 | .array_init_dot_two, | 1448 | .array_init_dot_two, |
| ... | @@ -1470,27 +1459,30 @@ pub const SrcLoc = struct { | ... | @@ -1470,27 +1459,30 @@ pub const SrcLoc = struct { |
| 1470 | } | 1459 | } |
| 1471 | }, | 1460 | }, |
| 1472 | 1461 | ||
| 1462 | .node_offset_try_operand => |node_off| { | ||
| 1463 | const tree = try src_loc.file_scope.getTree(gpa); | ||
| 1464 | const node = node_off.toAbsolute(src_loc.base_node); | ||
| 1465 | return tree.nodeToSpan(tree.nodeData(node).node); | ||
| 1466 | }, | ||
| 1467 | |||
| 1473 | .node_offset_switch_operand => |node_off| { | 1468 | .node_offset_switch_operand => |node_off| { |
| 1474 | const tree = try src_loc.file_scope.getTree(gpa); | 1469 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1475 | const node = src_loc.relativeToNodeIndex(node_off); | 1470 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1476 | const node_datas = tree.nodes.items(.data); | 1471 | const condition, _ = tree.nodeData(node).node_and_extra; |
| 1477 | return tree.nodeToSpan(node_datas[node].lhs); | 1472 | return tree.nodeToSpan(condition); |
| 1478 | }, | 1473 | }, |
| 1479 | 1474 | ||
| 1480 | .node_offset_switch_special_prong => |node_off| { | 1475 | .node_offset_switch_special_prong => |node_off| { |
| 1481 | const tree = try src_loc.file_scope.getTree(gpa); | 1476 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1482 | const switch_node = src_loc.relativeToNodeIndex(node_off); | 1477 | const switch_node = node_off.toAbsolute(src_loc.base_node); |
| 1483 | const node_datas = tree.nodes.items(.data); | 1478 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; |
| 1484 | const node_tags = tree.nodes.items(.tag); | 1479 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); |
| 1485 | const main_tokens = tree.nodes.items(.main_token); | ||
| 1486 | const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange); | ||
| 1487 | const case_nodes = tree.extra_data[extra.start..extra.end]; | ||
| 1488 | for (case_nodes) |case_node| { | 1480 | for (case_nodes) |case_node| { |
| 1489 | const case = tree.fullSwitchCase(case_node).?; | 1481 | const case = tree.fullSwitchCase(case_node).?; |
| 1490 | const is_special = (case.ast.values.len == 0) or | 1482 | const is_special = (case.ast.values.len == 0) or |
| 1491 | (case.ast.values.len == 1 and | 1483 | (case.ast.values.len == 1 and |
| 1492 | node_tags[case.ast.values[0]] == .identifier and | 1484 | tree.nodeTag(case.ast.values[0]) == .identifier and |
| 1493 | mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_")); | 1485 | mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(case.ast.values[0])), "_")); |
| 1494 | if (!is_special) continue; | 1486 | if (!is_special) continue; |
| 1495 | 1487 | ||
| 1496 | return tree.nodeToSpan(case_node); | 1488 | return tree.nodeToSpan(case_node); |
| ... | @@ -1499,22 +1491,19 @@ pub const SrcLoc = struct { | ... | @@ -1499,22 +1491,19 @@ pub const SrcLoc = struct { |
| 1499 | 1491 | ||
| 1500 | .node_offset_switch_range => |node_off| { | 1492 | .node_offset_switch_range => |node_off| { |
| 1501 | const tree = try src_loc.file_scope.getTree(gpa); | 1493 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1502 | const switch_node = src_loc.relativeToNodeIndex(node_off); | 1494 | const switch_node = node_off.toAbsolute(src_loc.base_node); |
| 1503 | const node_datas = tree.nodes.items(.data); | 1495 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; |
| 1504 | const node_tags = tree.nodes.items(.tag); | 1496 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); |
| 1505 | const main_tokens = tree.nodes.items(.main_token); | ||
| 1506 | const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange); | ||
| 1507 | const case_nodes = tree.extra_data[extra.start..extra.end]; | ||
| 1508 | for (case_nodes) |case_node| { | 1497 | for (case_nodes) |case_node| { |
| 1509 | const case = tree.fullSwitchCase(case_node).?; | 1498 | const case = tree.fullSwitchCase(case_node).?; |
| 1510 | const is_special = (case.ast.values.len == 0) or | 1499 | const is_special = (case.ast.values.len == 0) or |
| 1511 | (case.ast.values.len == 1 and | 1500 | (case.ast.values.len == 1 and |
| 1512 | node_tags[case.ast.values[0]] == .identifier and | 1501 | tree.nodeTag(case.ast.values[0]) == .identifier and |
| 1513 | mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_")); | 1502 | mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(case.ast.values[0])), "_")); |
| 1514 | if (is_special) continue; | 1503 | if (is_special) continue; |
| 1515 | 1504 | ||
| 1516 | for (case.ast.values) |item_node| { | 1505 | for (case.ast.values) |item_node| { |
| 1517 | if (node_tags[item_node] == .switch_range) { | 1506 | if (tree.nodeTag(item_node) == .switch_range) { |
| 1518 | return tree.nodeToSpan(item_node); | 1507 | return tree.nodeToSpan(item_node); |
| 1519 | } | 1508 | } |
| 1520 | } | 1509 | } |
| ... | @@ -1522,47 +1511,46 @@ pub const SrcLoc = struct { | ... | @@ -1522,47 +1511,46 @@ pub const SrcLoc = struct { |
| 1522 | }, | 1511 | }, |
| 1523 | .node_offset_fn_type_align => |node_off| { | 1512 | .node_offset_fn_type_align => |node_off| { |
| 1524 | const tree = try src_loc.file_scope.getTree(gpa); | 1513 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1525 | const node = src_loc.relativeToNodeIndex(node_off); | 1514 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1526 | var buf: [1]Ast.Node.Index = undefined; | 1515 | var buf: [1]Ast.Node.Index = undefined; |
| 1527 | const full = tree.fullFnProto(&buf, node).?; | 1516 | const full = tree.fullFnProto(&buf, node).?; |
| 1528 | return tree.nodeToSpan(full.ast.align_expr); | 1517 | return tree.nodeToSpan(full.ast.align_expr.unwrap().?); |
| 1529 | }, | 1518 | }, |
| 1530 | .node_offset_fn_type_addrspace => |node_off| { | 1519 | .node_offset_fn_type_addrspace => |node_off| { |
| 1531 | const tree = try src_loc.file_scope.getTree(gpa); | 1520 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1532 | const node = src_loc.relativeToNodeIndex(node_off); | 1521 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1533 | var buf: [1]Ast.Node.Index = undefined; | 1522 | var buf: [1]Ast.Node.Index = undefined; |
| 1534 | const full = tree.fullFnProto(&buf, node).?; | 1523 | const full = tree.fullFnProto(&buf, node).?; |
| 1535 | return tree.nodeToSpan(full.ast.addrspace_expr); | 1524 | return tree.nodeToSpan(full.ast.addrspace_expr.unwrap().?); |
| 1536 | }, | 1525 | }, |
| 1537 | .node_offset_fn_type_section => |node_off| { | 1526 | .node_offset_fn_type_section => |node_off| { |
| 1538 | const tree = try src_loc.file_scope.getTree(gpa); | 1527 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1539 | const node = src_loc.relativeToNodeIndex(node_off); | 1528 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1540 | var buf: [1]Ast.Node.Index = undefined; | 1529 | var buf: [1]Ast.Node.Index = undefined; |
| 1541 | const full = tree.fullFnProto(&buf, node).?; | 1530 | const full = tree.fullFnProto(&buf, node).?; |
| 1542 | return tree.nodeToSpan(full.ast.section_expr); | 1531 | return tree.nodeToSpan(full.ast.section_expr.unwrap().?); |
| 1543 | }, | 1532 | }, |
| 1544 | .node_offset_fn_type_cc => |node_off| { | 1533 | .node_offset_fn_type_cc => |node_off| { |
| 1545 | const tree = try src_loc.file_scope.getTree(gpa); | 1534 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1546 | const node = src_loc.relativeToNodeIndex(node_off); | 1535 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1547 | var buf: [1]Ast.Node.Index = undefined; | 1536 | var buf: [1]Ast.Node.Index = undefined; |
| 1548 | const full = tree.fullFnProto(&buf, node).?; | 1537 | const full = tree.fullFnProto(&buf, node).?; |
| 1549 | return tree.nodeToSpan(full.ast.callconv_expr); | 1538 | return tree.nodeToSpan(full.ast.callconv_expr.unwrap().?); |
| 1550 | }, | 1539 | }, |
| 1551 | 1540 | ||
| 1552 | .node_offset_fn_type_ret_ty => |node_off| { | 1541 | .node_offset_fn_type_ret_ty => |node_off| { |
| 1553 | const tree = try src_loc.file_scope.getTree(gpa); | 1542 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1554 | const node = src_loc.relativeToNodeIndex(node_off); | 1543 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1555 | var buf: [1]Ast.Node.Index = undefined; | 1544 | var buf: [1]Ast.Node.Index = undefined; |
| 1556 | const full = tree.fullFnProto(&buf, node).?; | 1545 | const full = tree.fullFnProto(&buf, node).?; |
| 1557 | return tree.nodeToSpan(full.ast.return_type); | 1546 | return tree.nodeToSpan(full.ast.return_type.unwrap().?); |
| 1558 | }, | 1547 | }, |
| 1559 | .node_offset_param => |node_off| { | 1548 | .node_offset_param => |node_off| { |
| 1560 | const tree = try src_loc.file_scope.getTree(gpa); | 1549 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1561 | const token_tags = tree.tokens.items(.tag); | 1550 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1562 | const node = src_loc.relativeToNodeIndex(node_off); | ||
| 1563 | 1551 | ||
| 1564 | var first_tok = tree.firstToken(node); | 1552 | var first_tok = tree.firstToken(node); |
| 1565 | while (true) switch (token_tags[first_tok - 1]) { | 1553 | while (true) switch (tree.tokenTag(first_tok - 1)) { |
| 1566 | .colon, .identifier, .keyword_comptime, .keyword_noalias => first_tok -= 1, | 1554 | .colon, .identifier, .keyword_comptime, .keyword_noalias => first_tok -= 1, |
| 1567 | else => break, | 1555 | else => break, |
| 1568 | }; | 1556 | }; |
| ... | @@ -1574,12 +1562,11 @@ pub const SrcLoc = struct { | ... | @@ -1574,12 +1562,11 @@ pub const SrcLoc = struct { |
| 1574 | }, | 1562 | }, |
| 1575 | .token_offset_param => |token_off| { | 1563 | .token_offset_param => |token_off| { |
| 1576 | const tree = try src_loc.file_scope.getTree(gpa); | 1564 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1577 | const token_tags = tree.tokens.items(.tag); | 1565 | const main_token = tree.nodeMainToken(src_loc.base_node); |
| 1578 | const main_token = tree.nodes.items(.main_token)[src_loc.base_node]; | 1566 | const tok_index = token_off.toAbsolute(main_token); |
| 1579 | const tok_index = @as(Ast.TokenIndex, @bitCast(token_off + @as(i32, @bitCast(main_token)))); | ||
| 1580 | 1567 | ||
| 1581 | var first_tok = tok_index; | 1568 | var first_tok = tok_index; |
| 1582 | while (true) switch (token_tags[first_tok - 1]) { | 1569 | while (true) switch (tree.tokenTag(first_tok - 1)) { |
| 1583 | .colon, .identifier, .keyword_comptime, .keyword_noalias => first_tok -= 1, | 1570 | .colon, .identifier, .keyword_comptime, .keyword_noalias => first_tok -= 1, |
| 1584 | else => break, | 1571 | else => break, |
| 1585 | }; | 1572 | }; |
| ... | @@ -1592,109 +1579,108 @@ pub const SrcLoc = struct { | ... | @@ -1592,109 +1579,108 @@ pub const SrcLoc = struct { |
| 1592 | 1579 | ||
| 1593 | .node_offset_anyframe_type => |node_off| { | 1580 | .node_offset_anyframe_type => |node_off| { |
| 1594 | const tree = try src_loc.file_scope.getTree(gpa); | 1581 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1595 | const node_datas = tree.nodes.items(.data); | 1582 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1596 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1583 | _, const child_type = tree.nodeData(parent_node).token_and_node; |
| 1597 | return tree.nodeToSpan(node_datas[parent_node].rhs); | 1584 | return tree.nodeToSpan(child_type); |
| 1598 | }, | 1585 | }, |
| 1599 | 1586 | ||
| 1600 | .node_offset_lib_name => |node_off| { | 1587 | .node_offset_lib_name => |node_off| { |
| 1601 | const tree = try src_loc.file_scope.getTree(gpa); | 1588 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1602 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1589 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1603 | var buf: [1]Ast.Node.Index = undefined; | 1590 | var buf: [1]Ast.Node.Index = undefined; |
| 1604 | const full = tree.fullFnProto(&buf, parent_node).?; | 1591 | const full = tree.fullFnProto(&buf, parent_node).?; |
| 1605 | const tok_index = full.lib_name.?; | 1592 | const tok_index = full.lib_name.?; |
| 1606 | const start = tree.tokens.items(.start)[tok_index]; | 1593 | const start = tree.tokenStart(tok_index); |
| 1607 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1594 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1608 | return Span{ .start = start, .end = end, .main = start }; | 1595 | return Span{ .start = start, .end = end, .main = start }; |
| 1609 | }, | 1596 | }, |
| 1610 | 1597 | ||
| 1611 | .node_offset_array_type_len => |node_off| { | 1598 | .node_offset_array_type_len => |node_off| { |
| 1612 | const tree = try src_loc.file_scope.getTree(gpa); | 1599 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1613 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1600 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1614 | 1601 | ||
| 1615 | const full = tree.fullArrayType(parent_node).?; | 1602 | const full = tree.fullArrayType(parent_node).?; |
| 1616 | return tree.nodeToSpan(full.ast.elem_count); | 1603 | return tree.nodeToSpan(full.ast.elem_count); |
| 1617 | }, | 1604 | }, |
| 1618 | .node_offset_array_type_sentinel => |node_off| { | 1605 | .node_offset_array_type_sentinel => |node_off| { |
| 1619 | const tree = try src_loc.file_scope.getTree(gpa); | 1606 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1620 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1607 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1621 | 1608 | ||
| 1622 | const full = tree.fullArrayType(parent_node).?; | 1609 | const full = tree.fullArrayType(parent_node).?; |
| 1623 | return tree.nodeToSpan(full.ast.sentinel); | 1610 | return tree.nodeToSpan(full.ast.sentinel.unwrap().?); |
| 1624 | }, | 1611 | }, |
| 1625 | .node_offset_array_type_elem => |node_off| { | 1612 | .node_offset_array_type_elem => |node_off| { |
| 1626 | const tree = try src_loc.file_scope.getTree(gpa); | 1613 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1627 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1614 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1628 | 1615 | ||
| 1629 | const full = tree.fullArrayType(parent_node).?; | 1616 | const full = tree.fullArrayType(parent_node).?; |
| 1630 | return tree.nodeToSpan(full.ast.elem_type); | 1617 | return tree.nodeToSpan(full.ast.elem_type); |
| 1631 | }, | 1618 | }, |
| 1632 | .node_offset_un_op => |node_off| { | 1619 | .node_offset_un_op => |node_off| { |
| 1633 | const tree = try src_loc.file_scope.getTree(gpa); | 1620 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1634 | const node_datas = tree.nodes.items(.data); | 1621 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1635 | const node = src_loc.relativeToNodeIndex(node_off); | 1622 | return tree.nodeToSpan(tree.nodeData(node).node); |
| 1636 | |||
| 1637 | return tree.nodeToSpan(node_datas[node].lhs); | ||
| 1638 | }, | 1623 | }, |
| 1639 | .node_offset_ptr_elem => |node_off| { | 1624 | .node_offset_ptr_elem => |node_off| { |
| 1640 | const tree = try src_loc.file_scope.getTree(gpa); | 1625 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1641 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1626 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1642 | 1627 | ||
| 1643 | const full = tree.fullPtrType(parent_node).?; | 1628 | const full = tree.fullPtrType(parent_node).?; |
| 1644 | return tree.nodeToSpan(full.ast.child_type); | 1629 | return tree.nodeToSpan(full.ast.child_type); |
| 1645 | }, | 1630 | }, |
| 1646 | .node_offset_ptr_sentinel => |node_off| { | 1631 | .node_offset_ptr_sentinel => |node_off| { |
| 1647 | const tree = try src_loc.file_scope.getTree(gpa); | 1632 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1648 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1633 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1649 | 1634 | ||
| 1650 | const full = tree.fullPtrType(parent_node).?; | 1635 | const full = tree.fullPtrType(parent_node).?; |
| 1651 | return tree.nodeToSpan(full.ast.sentinel); | 1636 | return tree.nodeToSpan(full.ast.sentinel.unwrap().?); |
| 1652 | }, | 1637 | }, |
| 1653 | .node_offset_ptr_align => |node_off| { | 1638 | .node_offset_ptr_align => |node_off| { |
| 1654 | const tree = try src_loc.file_scope.getTree(gpa); | 1639 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1655 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1640 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1656 | 1641 | ||
| 1657 | const full = tree.fullPtrType(parent_node).?; | 1642 | const full = tree.fullPtrType(parent_node).?; |
| 1658 | return tree.nodeToSpan(full.ast.align_node); | 1643 | return tree.nodeToSpan(full.ast.align_node.unwrap().?); |
| 1659 | }, | 1644 | }, |
| 1660 | .node_offset_ptr_addrspace => |node_off| { | 1645 | .node_offset_ptr_addrspace => |node_off| { |
| 1661 | const tree = try src_loc.file_scope.getTree(gpa); | 1646 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1662 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1647 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1663 | 1648 | ||
| 1664 | const full = tree.fullPtrType(parent_node).?; | 1649 | const full = tree.fullPtrType(parent_node).?; |
| 1665 | return tree.nodeToSpan(full.ast.addrspace_node); | 1650 | return tree.nodeToSpan(full.ast.addrspace_node.unwrap().?); |
| 1666 | }, | 1651 | }, |
| 1667 | .node_offset_ptr_bitoffset => |node_off| { | 1652 | .node_offset_ptr_bitoffset => |node_off| { |
| 1668 | const tree = try src_loc.file_scope.getTree(gpa); | 1653 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1669 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1654 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1670 | 1655 | ||
| 1671 | const full = tree.fullPtrType(parent_node).?; | 1656 | const full = tree.fullPtrType(parent_node).?; |
| 1672 | return tree.nodeToSpan(full.ast.bit_range_start); | 1657 | return tree.nodeToSpan(full.ast.bit_range_start.unwrap().?); |
| 1673 | }, | 1658 | }, |
| 1674 | .node_offset_ptr_hostsize => |node_off| { | 1659 | .node_offset_ptr_hostsize => |node_off| { |
| 1675 | const tree = try src_loc.file_scope.getTree(gpa); | 1660 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1676 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1661 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1677 | 1662 | ||
| 1678 | const full = tree.fullPtrType(parent_node).?; | 1663 | const full = tree.fullPtrType(parent_node).?; |
| 1679 | return tree.nodeToSpan(full.ast.bit_range_end); | 1664 | return tree.nodeToSpan(full.ast.bit_range_end.unwrap().?); |
| 1680 | }, | 1665 | }, |
| 1681 | .node_offset_container_tag => |node_off| { | 1666 | .node_offset_container_tag => |node_off| { |
| 1682 | const tree = try src_loc.file_scope.getTree(gpa); | 1667 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1683 | const node_tags = tree.nodes.items(.tag); | 1668 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1684 | const parent_node = src_loc.relativeToNodeIndex(node_off); | ||
| 1685 | 1669 | ||
| 1686 | switch (node_tags[parent_node]) { | 1670 | switch (tree.nodeTag(parent_node)) { |
| 1687 | .container_decl_arg, .container_decl_arg_trailing => { | 1671 | .container_decl_arg, .container_decl_arg_trailing => { |
| 1688 | const full = tree.containerDeclArg(parent_node); | 1672 | const full = tree.containerDeclArg(parent_node); |
| 1689 | return tree.nodeToSpan(full.ast.arg); | 1673 | const arg_node = full.ast.arg.unwrap().?; |
| 1674 | return tree.nodeToSpan(arg_node); | ||
| 1690 | }, | 1675 | }, |
| 1691 | .tagged_union_enum_tag, .tagged_union_enum_tag_trailing => { | 1676 | .tagged_union_enum_tag, .tagged_union_enum_tag_trailing => { |
| 1692 | const full = tree.taggedUnionEnumTag(parent_node); | 1677 | const full = tree.taggedUnionEnumTag(parent_node); |
| 1678 | const arg_node = full.ast.arg.unwrap().?; | ||
| 1693 | 1679 | ||
| 1694 | return tree.tokensToSpan( | 1680 | return tree.tokensToSpan( |
| 1695 | tree.firstToken(full.ast.arg) - 2, | 1681 | tree.firstToken(arg_node) - 2, |
| 1696 | tree.lastToken(full.ast.arg) + 1, | 1682 | tree.lastToken(arg_node) + 1, |
| 1697 | tree.nodes.items(.main_token)[full.ast.arg], | 1683 | tree.nodeMainToken(arg_node), |
| 1698 | ); | 1684 | ); |
| 1699 | }, | 1685 | }, |
| 1700 | else => unreachable, | 1686 | else => unreachable, |
| ... | @@ -1702,60 +1688,55 @@ pub const SrcLoc = struct { | ... | @@ -1702,60 +1688,55 @@ pub const SrcLoc = struct { |
| 1702 | }, | 1688 | }, |
| 1703 | .node_offset_field_default => |node_off| { | 1689 | .node_offset_field_default => |node_off| { |
| 1704 | const tree = try src_loc.file_scope.getTree(gpa); | 1690 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1705 | const node_tags = tree.nodes.items(.tag); | 1691 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1706 | const parent_node = src_loc.relativeToNodeIndex(node_off); | ||
| 1707 | 1692 | ||
| 1708 | const full: Ast.full.ContainerField = switch (node_tags[parent_node]) { | 1693 | const full: Ast.full.ContainerField = switch (tree.nodeTag(parent_node)) { |
| 1709 | .container_field => tree.containerField(parent_node), | 1694 | .container_field => tree.containerField(parent_node), |
| 1710 | .container_field_init => tree.containerFieldInit(parent_node), | 1695 | .container_field_init => tree.containerFieldInit(parent_node), |
| 1711 | else => unreachable, | 1696 | else => unreachable, |
| 1712 | }; | 1697 | }; |
| 1713 | return tree.nodeToSpan(full.ast.value_expr); | 1698 | return tree.nodeToSpan(full.ast.value_expr.unwrap().?); |
| 1714 | }, | 1699 | }, |
| 1715 | .node_offset_init_ty => |node_off| { | 1700 | .node_offset_init_ty => |node_off| { |
| 1716 | const tree = try src_loc.file_scope.getTree(gpa); | 1701 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1717 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1702 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1718 | 1703 | ||
| 1719 | var buf: [2]Ast.Node.Index = undefined; | 1704 | var buf: [2]Ast.Node.Index = undefined; |
| 1720 | const type_expr = if (tree.fullArrayInit(&buf, parent_node)) |array_init| | 1705 | const type_expr = if (tree.fullArrayInit(&buf, parent_node)) |array_init| |
| 1721 | array_init.ast.type_expr | 1706 | array_init.ast.type_expr.unwrap().? |
| 1722 | else | 1707 | else |
| 1723 | tree.fullStructInit(&buf, parent_node).?.ast.type_expr; | 1708 | tree.fullStructInit(&buf, parent_node).?.ast.type_expr.unwrap().?; |
| 1724 | return tree.nodeToSpan(type_expr); | 1709 | return tree.nodeToSpan(type_expr); |
| 1725 | }, | 1710 | }, |
| 1726 | .node_offset_store_ptr => |node_off| { | 1711 | .node_offset_store_ptr => |node_off| { |
| 1727 | const tree = try src_loc.file_scope.getTree(gpa); | 1712 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1728 | const node_tags = tree.nodes.items(.tag); | 1713 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1729 | const node_datas = tree.nodes.items(.data); | ||
| 1730 | const node = src_loc.relativeToNodeIndex(node_off); | ||
| 1731 | 1714 | ||
| 1732 | switch (node_tags[node]) { | 1715 | switch (tree.nodeTag(node)) { |
| 1733 | .assign => { | 1716 | .assign => { |
| 1734 | return tree.nodeToSpan(node_datas[node].lhs); | 1717 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[0]); |
| 1735 | }, | 1718 | }, |
| 1736 | else => return tree.nodeToSpan(node), | 1719 | else => return tree.nodeToSpan(node), |
| 1737 | } | 1720 | } |
| 1738 | }, | 1721 | }, |
| 1739 | .node_offset_store_operand => |node_off| { | 1722 | .node_offset_store_operand => |node_off| { |
| 1740 | const tree = try src_loc.file_scope.getTree(gpa); | 1723 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1741 | const node_tags = tree.nodes.items(.tag); | 1724 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1742 | const node_datas = tree.nodes.items(.data); | ||
| 1743 | const node = src_loc.relativeToNodeIndex(node_off); | ||
| 1744 | 1725 | ||
| 1745 | switch (node_tags[node]) { | 1726 | switch (tree.nodeTag(node)) { |
| 1746 | .assign => { | 1727 | .assign => { |
| 1747 | return tree.nodeToSpan(node_datas[node].rhs); | 1728 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[1]); |
| 1748 | }, | 1729 | }, |
| 1749 | else => return tree.nodeToSpan(node), | 1730 | else => return tree.nodeToSpan(node), |
| 1750 | } | 1731 | } |
| 1751 | }, | 1732 | }, |
| 1752 | .node_offset_return_operand => |node_off| { | 1733 | .node_offset_return_operand => |node_off| { |
| 1753 | const tree = try src_loc.file_scope.getTree(gpa); | 1734 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1754 | const node = src_loc.relativeToNodeIndex(node_off); | 1735 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1755 | const node_tags = tree.nodes.items(.tag); | 1736 | if (tree.nodeTag(node) == .@"return") { |
| 1756 | const node_datas = tree.nodes.items(.data); | 1737 | if (tree.nodeData(node).opt_node.unwrap()) |lhs| { |
| 1757 | if (node_tags[node] == .@"return" and node_datas[node].lhs != 0) { | 1738 | return tree.nodeToSpan(lhs); |
| 1758 | return tree.nodeToSpan(node_datas[node].lhs); | 1739 | } |
| 1759 | } | 1740 | } |
| 1760 | return tree.nodeToSpan(node); | 1741 | return tree.nodeToSpan(node); |
| 1761 | }, | 1742 | }, |
| ... | @@ -1765,7 +1746,7 @@ pub const SrcLoc = struct { | ... | @@ -1765,7 +1746,7 @@ pub const SrcLoc = struct { |
| 1765 | .container_field_align, | 1746 | .container_field_align, |
| 1766 | => |field_idx| { | 1747 | => |field_idx| { |
| 1767 | const tree = try src_loc.file_scope.getTree(gpa); | 1748 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1768 | const node = src_loc.relativeToNodeIndex(0); | 1749 | const node = src_loc.base_node; |
| 1769 | var buf: [2]Ast.Node.Index = undefined; | 1750 | var buf: [2]Ast.Node.Index = undefined; |
| 1770 | const container_decl = tree.fullContainerDecl(&buf, node) orelse | 1751 | const container_decl = tree.fullContainerDecl(&buf, node) orelse |
| 1771 | return tree.nodeToSpan(node); | 1752 | return tree.nodeToSpan(node); |
| ... | @@ -1778,36 +1759,36 @@ pub const SrcLoc = struct { | ... | @@ -1778,36 +1759,36 @@ pub const SrcLoc = struct { |
| 1778 | continue; | 1759 | continue; |
| 1779 | } | 1760 | } |
| 1780 | const field_component_node = switch (src_loc.lazy) { | 1761 | const field_component_node = switch (src_loc.lazy) { |
| 1781 | .container_field_name => 0, | 1762 | .container_field_name => .none, |
| 1782 | .container_field_value => field.ast.value_expr, | 1763 | .container_field_value => field.ast.value_expr, |
| 1783 | .container_field_type => field.ast.type_expr, | 1764 | .container_field_type => field.ast.type_expr, |
| 1784 | .container_field_align => field.ast.align_expr, | 1765 | .container_field_align => field.ast.align_expr, |
| 1785 | else => unreachable, | 1766 | else => unreachable, |
| 1786 | }; | 1767 | }; |
| 1787 | if (field_component_node == 0) { | 1768 | if (field_component_node.unwrap()) |component_node| { |
| 1788 | return tree.tokenToSpan(field.ast.main_token); | 1769 | return tree.nodeToSpan(component_node); |
| 1789 | } else { | 1770 | } else { |
| 1790 | return tree.nodeToSpan(field_component_node); | 1771 | return tree.tokenToSpan(field.ast.main_token); |
| 1791 | } | 1772 | } |
| 1792 | } else unreachable; | 1773 | } else unreachable; |
| 1793 | }, | 1774 | }, |
| 1794 | .tuple_field_type, .tuple_field_init => |field_info| { | 1775 | .tuple_field_type, .tuple_field_init => |field_info| { |
| 1795 | const tree = try src_loc.file_scope.getTree(gpa); | 1776 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1796 | const node = src_loc.relativeToNodeIndex(0); | 1777 | const node = src_loc.base_node; |
| 1797 | var buf: [2]Ast.Node.Index = undefined; | 1778 | var buf: [2]Ast.Node.Index = undefined; |
| 1798 | const container_decl = tree.fullContainerDecl(&buf, node) orelse | 1779 | const container_decl = tree.fullContainerDecl(&buf, node) orelse |
| 1799 | return tree.nodeToSpan(node); | 1780 | return tree.nodeToSpan(node); |
| 1800 | 1781 | ||
| 1801 | const field = tree.fullContainerField(container_decl.ast.members[field_info.elem_index]).?; | 1782 | const field = tree.fullContainerField(container_decl.ast.members[field_info.elem_index]).?; |
| 1802 | return tree.nodeToSpan(switch (src_loc.lazy) { | 1783 | return tree.nodeToSpan(switch (src_loc.lazy) { |
| 1803 | .tuple_field_type => field.ast.type_expr, | 1784 | .tuple_field_type => field.ast.type_expr.unwrap().?, |
| 1804 | .tuple_field_init => field.ast.value_expr, | 1785 | .tuple_field_init => field.ast.value_expr.unwrap().?, |
| 1805 | else => unreachable, | 1786 | else => unreachable, |
| 1806 | }); | 1787 | }); |
| 1807 | }, | 1788 | }, |
| 1808 | .init_elem => |init_elem| { | 1789 | .init_elem => |init_elem| { |
| 1809 | const tree = try src_loc.file_scope.getTree(gpa); | 1790 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1810 | const init_node = src_loc.relativeToNodeIndex(init_elem.init_node_offset); | 1791 | const init_node = init_elem.init_node_offset.toAbsolute(src_loc.base_node); |
| 1811 | var buf: [2]Ast.Node.Index = undefined; | 1792 | var buf: [2]Ast.Node.Index = undefined; |
| 1812 | if (tree.fullArrayInit(&buf, init_node)) |full| { | 1793 | if (tree.fullArrayInit(&buf, init_node)) |full| { |
| 1813 | const elem_node = full.ast.elements[init_elem.elem_index]; | 1794 | const elem_node = full.ast.elements[init_elem.elem_index]; |
| ... | @@ -1817,7 +1798,7 @@ pub const SrcLoc = struct { | ... | @@ -1817,7 +1798,7 @@ pub const SrcLoc = struct { |
| 1817 | return tree.tokensToSpan( | 1798 | return tree.tokensToSpan( |
| 1818 | tree.firstToken(field_node) - 3, | 1799 | tree.firstToken(field_node) - 3, |
| 1819 | tree.lastToken(field_node), | 1800 | tree.lastToken(field_node), |
| 1820 | tree.nodes.items(.main_token)[field_node] - 2, | 1801 | tree.nodeMainToken(field_node) - 2, |
| 1821 | ); | 1802 | ); |
| 1822 | } else unreachable; | 1803 | } else unreachable; |
| 1823 | }, | 1804 | }, |
| ... | @@ -1846,7 +1827,7 @@ pub const SrcLoc = struct { | ... | @@ -1846,7 +1827,7 @@ pub const SrcLoc = struct { |
| 1846 | else => unreachable, | 1827 | else => unreachable, |
| 1847 | }; | 1828 | }; |
| 1848 | const tree = try src_loc.file_scope.getTree(gpa); | 1829 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1849 | const node = src_loc.relativeToNodeIndex(builtin_call_node); | 1830 | const node = builtin_call_node.toAbsolute(src_loc.base_node); |
| 1850 | var builtin_buf: [2]Ast.Node.Index = undefined; | 1831 | var builtin_buf: [2]Ast.Node.Index = undefined; |
| 1851 | const args = tree.builtinCallParams(&builtin_buf, node).?; | 1832 | const args = tree.builtinCallParams(&builtin_buf, node).?; |
| 1852 | const arg_node = args[1]; | 1833 | const arg_node = args[1]; |
| ... | @@ -1861,7 +1842,7 @@ pub const SrcLoc = struct { | ... | @@ -1861,7 +1842,7 @@ pub const SrcLoc = struct { |
| 1861 | return tree.tokensToSpan( | 1842 | return tree.tokensToSpan( |
| 1862 | name_token - 1, | 1843 | name_token - 1, |
| 1863 | tree.lastToken(field_node), | 1844 | tree.lastToken(field_node), |
| 1864 | tree.nodes.items(.main_token)[field_node] - 2, | 1845 | tree.nodeMainToken(field_node) - 2, |
| 1865 | ); | 1846 | ); |
| 1866 | } | 1847 | } |
| 1867 | } | 1848 | } |
| ... | @@ -1885,12 +1866,9 @@ pub const SrcLoc = struct { | ... | @@ -1885,12 +1866,9 @@ pub const SrcLoc = struct { |
| 1885 | }; | 1866 | }; |
| 1886 | 1867 | ||
| 1887 | const tree = try src_loc.file_scope.getTree(gpa); | 1868 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1888 | const node_datas = tree.nodes.items(.data); | 1869 | const switch_node = switch_node_offset.toAbsolute(src_loc.base_node); |
| 1889 | const node_tags = tree.nodes.items(.tag); | 1870 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; |
| 1890 | const main_tokens = tree.nodes.items(.main_token); | 1871 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); |
| 1891 | const switch_node = src_loc.relativeToNodeIndex(switch_node_offset); | ||
| 1892 | const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange); | ||
| 1893 | const case_nodes = tree.extra_data[extra.start..extra.end]; | ||
| 1894 | 1872 | ||
| 1895 | var multi_i: u32 = 0; | 1873 | var multi_i: u32 = 0; |
| 1896 | var scalar_i: u32 = 0; | 1874 | var scalar_i: u32 = 0; |
| ... | @@ -1898,8 +1876,8 @@ pub const SrcLoc = struct { | ... | @@ -1898,8 +1876,8 @@ pub const SrcLoc = struct { |
| 1898 | const case = tree.fullSwitchCase(case_node).?; | 1876 | const case = tree.fullSwitchCase(case_node).?; |
| 1899 | const is_special = special: { | 1877 | const is_special = special: { |
| 1900 | if (case.ast.values.len == 0) break :special true; | 1878 | if (case.ast.values.len == 0) break :special true; |
| 1901 | if (case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .identifier) { | 1879 | if (case.ast.values.len == 1 and tree.nodeTag(case.ast.values[0]) == .identifier) { |
| 1902 | break :special mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_"); | 1880 | break :special mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(case.ast.values[0])), "_"); |
| 1903 | } | 1881 | } |
| 1904 | break :special false; | 1882 | break :special false; |
| 1905 | }; | 1883 | }; |
| ... | @@ -1911,7 +1889,7 @@ pub const SrcLoc = struct { | ... | @@ -1911,7 +1889,7 @@ pub const SrcLoc = struct { |
| 1911 | } | 1889 | } |
| 1912 | 1890 | ||
| 1913 | const is_multi = case.ast.values.len != 1 or | 1891 | const is_multi = case.ast.values.len != 1 or |
| 1914 | node_tags[case.ast.values[0]] == .switch_range; | 1892 | tree.nodeTag(case.ast.values[0]) == .switch_range; |
| 1915 | 1893 | ||
| 1916 | switch (want_case_idx.kind) { | 1894 | switch (want_case_idx.kind) { |
| 1917 | .scalar => if (!is_multi and want_case_idx.index == scalar_i) break case, | 1895 | .scalar => if (!is_multi and want_case_idx.index == scalar_i) break case, |
| ... | @@ -1931,18 +1909,17 @@ pub const SrcLoc = struct { | ... | @@ -1931,18 +1909,17 @@ pub const SrcLoc = struct { |
| 1931 | .switch_case_item_range_last, | 1909 | .switch_case_item_range_last, |
| 1932 | => |x| x.item_idx, | 1910 | => |x| x.item_idx, |
| 1933 | .switch_capture, .switch_tag_capture => { | 1911 | .switch_capture, .switch_tag_capture => { |
| 1934 | const token_tags = tree.tokens.items(.tag); | ||
| 1935 | const start = switch (src_loc.lazy) { | 1912 | const start = switch (src_loc.lazy) { |
| 1936 | .switch_capture => case.payload_token.?, | 1913 | .switch_capture => case.payload_token.?, |
| 1937 | .switch_tag_capture => tok: { | 1914 | .switch_tag_capture => tok: { |
| 1938 | var tok = case.payload_token.?; | 1915 | var tok = case.payload_token.?; |
| 1939 | if (token_tags[tok] == .asterisk) tok += 1; | 1916 | if (tree.tokenTag(tok) == .asterisk) tok += 1; |
| 1940 | tok += 2; // skip over comma | 1917 | tok = tok + 2; // skip over comma |
| 1941 | break :tok tok; | 1918 | break :tok tok; |
| 1942 | }, | 1919 | }, |
| 1943 | else => unreachable, | 1920 | else => unreachable, |
| 1944 | }; | 1921 | }; |
| 1945 | const end = switch (token_tags[start]) { | 1922 | const end = switch (tree.tokenTag(start)) { |
| 1946 | .asterisk => start + 1, | 1923 | .asterisk => start + 1, |
| 1947 | else => start, | 1924 | else => start, |
| 1948 | }; | 1925 | }; |
| ... | @@ -1955,7 +1932,7 @@ pub const SrcLoc = struct { | ... | @@ -1955,7 +1932,7 @@ pub const SrcLoc = struct { |
| 1955 | .single => { | 1932 | .single => { |
| 1956 | var item_i: u32 = 0; | 1933 | var item_i: u32 = 0; |
| 1957 | for (case.ast.values) |item_node| { | 1934 | for (case.ast.values) |item_node| { |
| 1958 | if (node_tags[item_node] == .switch_range) continue; | 1935 | if (tree.nodeTag(item_node) == .switch_range) continue; |
| 1959 | if (item_i != want_item.index) { | 1936 | if (item_i != want_item.index) { |
| 1960 | item_i += 1; | 1937 | item_i += 1; |
| 1961 | continue; | 1938 | continue; |
| ... | @@ -1966,15 +1943,16 @@ pub const SrcLoc = struct { | ... | @@ -1966,15 +1943,16 @@ pub const SrcLoc = struct { |
| 1966 | .range => { | 1943 | .range => { |
| 1967 | var range_i: u32 = 0; | 1944 | var range_i: u32 = 0; |
| 1968 | for (case.ast.values) |item_node| { | 1945 | for (case.ast.values) |item_node| { |
| 1969 | if (node_tags[item_node] != .switch_range) continue; | 1946 | if (tree.nodeTag(item_node) != .switch_range) continue; |
| 1970 | if (range_i != want_item.index) { | 1947 | if (range_i != want_item.index) { |
| 1971 | range_i += 1; | 1948 | range_i += 1; |
| 1972 | continue; | 1949 | continue; |
| 1973 | } | 1950 | } |
| 1951 | const first, const last = tree.nodeData(item_node).node_and_node; | ||
| 1974 | return switch (src_loc.lazy) { | 1952 | return switch (src_loc.lazy) { |
| 1975 | .switch_case_item => tree.nodeToSpan(item_node), | 1953 | .switch_case_item => tree.nodeToSpan(item_node), |
| 1976 | .switch_case_item_range_first => tree.nodeToSpan(node_datas[item_node].lhs), | 1954 | .switch_case_item_range_first => tree.nodeToSpan(first), |
| 1977 | .switch_case_item_range_last => tree.nodeToSpan(node_datas[item_node].rhs), | 1955 | .switch_case_item_range_last => tree.nodeToSpan(last), |
| 1978 | else => unreachable, | 1956 | else => unreachable, |
| 1979 | }; | 1957 | }; |
| 1980 | } else unreachable; | 1958 | } else unreachable; |
| ... | @@ -1997,7 +1975,7 @@ pub const SrcLoc = struct { | ... | @@ -1997,7 +1975,7 @@ pub const SrcLoc = struct { |
| 1997 | var param_it = full.iterate(tree); | 1975 | var param_it = full.iterate(tree); |
| 1998 | for (0..param_idx) |_| assert(param_it.next() != null); | 1976 | for (0..param_idx) |_| assert(param_it.next() != null); |
| 1999 | const param = param_it.next().?; | 1977 | const param = param_it.next().?; |
| 2000 | return tree.nodeToSpan(param.type_expr); | 1978 | return tree.nodeToSpan(param.type_expr.?); |
| 2001 | }, | 1979 | }, |
| 2002 | } | 1980 | } |
| 2003 | } | 1981 | } |
| ... | @@ -2028,212 +2006,217 @@ pub const LazySrcLoc = struct { | ... | @@ -2028,212 +2006,217 @@ pub const LazySrcLoc = struct { |
| 2028 | byte_abs: u32, | 2006 | byte_abs: u32, |
| 2029 | /// The source location points to a token within a source file, | 2007 | /// The source location points to a token within a source file, |
| 2030 | /// offset from 0. The source file is determined contextually. | 2008 | /// offset from 0. The source file is determined contextually. |
| 2031 | token_abs: u32, | 2009 | token_abs: Ast.TokenIndex, |
| 2032 | /// The source location points to an AST node within a source file, | 2010 | /// The source location points to an AST node within a source file, |
| 2033 | /// offset from 0. The source file is determined contextually. | 2011 | /// offset from 0. The source file is determined contextually. |
| 2034 | node_abs: u32, | 2012 | node_abs: Ast.Node.Index, |
| 2035 | /// The source location points to a byte offset within a source file, | 2013 | /// The source location points to a byte offset within a source file, |
| 2036 | /// offset from the byte offset of the base node within the file. | 2014 | /// offset from the byte offset of the base node within the file. |
| 2037 | byte_offset: u32, | 2015 | byte_offset: u32, |
| 2038 | /// This data is the offset into the token list from the base node's first token. | 2016 | /// This data is the offset into the token list from the base node's first token. |
| 2039 | token_offset: u32, | 2017 | token_offset: Ast.TokenOffset, |
| 2040 | /// The source location points to an AST node, which is this value offset | 2018 | /// The source location points to an AST node, which is this value offset |
| 2041 | /// from its containing base node AST index. | 2019 | /// from its containing base node AST index. |
| 2042 | node_offset: TracedOffset, | 2020 | node_offset: TracedOffset, |
| 2043 | /// The source location points to the main token of an AST node, found | 2021 | /// The source location points to the main token of an AST node, found |
| 2044 | /// by taking this AST node index offset from the containing base node. | 2022 | /// by taking this AST node index offset from the containing base node. |
| 2045 | node_offset_main_token: i32, | 2023 | node_offset_main_token: Ast.Node.Offset, |
| 2046 | /// The source location points to the beginning of a struct initializer. | 2024 | /// The source location points to the beginning of a struct initializer. |
| 2047 | node_offset_initializer: i32, | 2025 | node_offset_initializer: Ast.Node.Offset, |
| 2048 | /// The source location points to a variable declaration type expression, | 2026 | /// The source location points to a variable declaration type expression, |
| 2049 | /// found by taking this AST node index offset from the containing | 2027 | /// found by taking this AST node index offset from the containing |
| 2050 | /// base node, which points to a variable declaration AST node. Next, navigate | 2028 | /// base node, which points to a variable declaration AST node. Next, navigate |
| 2051 | /// to the type expression. | 2029 | /// to the type expression. |
| 2052 | node_offset_var_decl_ty: i32, | 2030 | node_offset_var_decl_ty: Ast.Node.Offset, |
| 2053 | /// The source location points to the alignment expression of a var decl. | 2031 | /// The source location points to the alignment expression of a var decl. |
| 2054 | node_offset_var_decl_align: i32, | 2032 | node_offset_var_decl_align: Ast.Node.Offset, |
| 2055 | /// The source location points to the linksection expression of a var decl. | 2033 | /// The source location points to the linksection expression of a var decl. |
| 2056 | node_offset_var_decl_section: i32, | 2034 | node_offset_var_decl_section: Ast.Node.Offset, |
| 2057 | /// The source location points to the addrspace expression of a var decl. | 2035 | /// The source location points to the addrspace expression of a var decl. |
| 2058 | node_offset_var_decl_addrspace: i32, | 2036 | node_offset_var_decl_addrspace: Ast.Node.Offset, |
| 2059 | /// The source location points to the initializer of a var decl. | 2037 | /// The source location points to the initializer of a var decl. |
| 2060 | node_offset_var_decl_init: i32, | 2038 | node_offset_var_decl_init: Ast.Node.Offset, |
| 2061 | /// The source location points to the given argument of a builtin function call. | 2039 | /// The source location points to the given argument of a builtin function call. |
| 2062 | /// `builtin_call_node` points to the builtin call. | 2040 | /// `builtin_call_node` points to the builtin call. |
| 2063 | /// `arg_index` is the index of the argument which hte source location refers to. | 2041 | /// `arg_index` is the index of the argument which hte source location refers to. |
| 2064 | node_offset_builtin_call_arg: struct { | 2042 | node_offset_builtin_call_arg: struct { |
| 2065 | builtin_call_node: i32, | 2043 | builtin_call_node: Ast.Node.Offset, |
| 2066 | arg_index: u32, | 2044 | arg_index: u32, |
| 2067 | }, | 2045 | }, |
| 2068 | /// Like `node_offset_builtin_call_arg` but recurses through arbitrarily many calls | 2046 | /// Like `node_offset_builtin_call_arg` but recurses through arbitrarily many calls |
| 2069 | /// to pointer cast builtins (taking the first argument of the most nested). | 2047 | /// to pointer cast builtins (taking the first argument of the most nested). |
| 2070 | node_offset_ptrcast_operand: i32, | 2048 | node_offset_ptrcast_operand: Ast.Node.Offset, |
| 2071 | /// The source location points to the index expression of an array access | 2049 | /// The source location points to the index expression of an array access |
| 2072 | /// expression, found by taking this AST node index offset from the containing | 2050 | /// expression, found by taking this AST node index offset from the containing |
| 2073 | /// base node, which points to an array access AST node. Next, navigate | 2051 | /// base node, which points to an array access AST node. Next, navigate |
| 2074 | /// to the index expression. | 2052 | /// to the index expression. |
| 2075 | node_offset_array_access_index: i32, | 2053 | node_offset_array_access_index: Ast.Node.Offset, |
| 2076 | /// The source location points to the LHS of a slice expression | 2054 | /// The source location points to the LHS of a slice expression |
| 2077 | /// expression, found by taking this AST node index offset from the containing | 2055 | /// expression, found by taking this AST node index offset from the containing |
| 2078 | /// base node, which points to a slice AST node. Next, navigate | 2056 | /// base node, which points to a slice AST node. Next, navigate |
| 2079 | /// to the sentinel expression. | 2057 | /// to the sentinel expression. |
| 2080 | node_offset_slice_ptr: i32, | 2058 | node_offset_slice_ptr: Ast.Node.Offset, |
| 2081 | /// The source location points to start expression of a slice expression | 2059 | /// The source location points to start expression of a slice expression |
| 2082 | /// expression, found by taking this AST node index offset from the containing | 2060 | /// expression, found by taking this AST node index offset from the containing |
| 2083 | /// base node, which points to a slice AST node. Next, navigate | 2061 | /// base node, which points to a slice AST node. Next, navigate |
| 2084 | /// to the sentinel expression. | 2062 | /// to the sentinel expression. |
| 2085 | node_offset_slice_start: i32, | 2063 | node_offset_slice_start: Ast.Node.Offset, |
| 2086 | /// The source location points to the end expression of a slice | 2064 | /// The source location points to the end expression of a slice |
| 2087 | /// expression, found by taking this AST node index offset from the containing | 2065 | /// expression, found by taking this AST node index offset from the containing |
| 2088 | /// base node, which points to a slice AST node. Next, navigate | 2066 | /// base node, which points to a slice AST node. Next, navigate |
| 2089 | /// to the sentinel expression. | 2067 | /// to the sentinel expression. |
| 2090 | node_offset_slice_end: i32, | 2068 | node_offset_slice_end: Ast.Node.Offset, |
| 2091 | /// The source location points to the sentinel expression of a slice | 2069 | /// The source location points to the sentinel expression of a slice |
| 2092 | /// expression, found by taking this AST node index offset from the containing | 2070 | /// expression, found by taking this AST node index offset from the containing |
| 2093 | /// base node, which points to a slice AST node. Next, navigate | 2071 | /// base node, which points to a slice AST node. Next, navigate |
| 2094 | /// to the sentinel expression. | 2072 | /// to the sentinel expression. |
| 2095 | node_offset_slice_sentinel: i32, | 2073 | node_offset_slice_sentinel: Ast.Node.Offset, |
| 2096 | /// The source location points to the callee expression of a function | 2074 | /// The source location points to the callee expression of a function |
| 2097 | /// call expression, found by taking this AST node index offset from the containing | 2075 | /// call expression, found by taking this AST node index offset from the containing |
| 2098 | /// base node, which points to a function call AST node. Next, navigate | 2076 | /// base node, which points to a function call AST node. Next, navigate |
| 2099 | /// to the callee expression. | 2077 | /// to the callee expression. |
| 2100 | node_offset_call_func: i32, | 2078 | node_offset_call_func: Ast.Node.Offset, |
| 2101 | /// The payload is offset from the containing base node. | 2079 | /// The payload is offset from the containing base node. |
| 2102 | /// The source location points to the field name of: | 2080 | /// The source location points to the field name of: |
| 2103 | /// * a field access expression (`a.b`), or | 2081 | /// * a field access expression (`a.b`), or |
| 2104 | /// * the callee of a method call (`a.b()`) | 2082 | /// * the callee of a method call (`a.b()`) |
| 2105 | node_offset_field_name: i32, | 2083 | node_offset_field_name: Ast.Node.Offset, |
| 2106 | /// The payload is offset from the containing base node. | 2084 | /// The payload is offset from the containing base node. |
| 2107 | /// The source location points to the field name of the operand ("b" node) | 2085 | /// The source location points to the field name of the operand ("b" node) |
| 2108 | /// of a field initialization expression (`.a = b`) | 2086 | /// of a field initialization expression (`.a = b`) |
| 2109 | node_offset_field_name_init: i32, | 2087 | node_offset_field_name_init: Ast.Node.Offset, |
| 2110 | /// The source location points to the pointer of a pointer deref expression, | 2088 | /// The source location points to the pointer of a pointer deref expression, |
| 2111 | /// found by taking this AST node index offset from the containing | 2089 | /// found by taking this AST node index offset from the containing |
| 2112 | /// base node, which points to a pointer deref AST node. Next, navigate | 2090 | /// base node, which points to a pointer deref AST node. Next, navigate |
| 2113 | /// to the pointer expression. | 2091 | /// to the pointer expression. |
| 2114 | node_offset_deref_ptr: i32, | 2092 | node_offset_deref_ptr: Ast.Node.Offset, |
| 2115 | /// The source location points to the assembly source code of an inline assembly | 2093 | /// The source location points to the assembly source code of an inline assembly |
| 2116 | /// expression, found by taking this AST node index offset from the containing | 2094 | /// expression, found by taking this AST node index offset from the containing |
| 2117 | /// base node, which points to inline assembly AST node. Next, navigate | 2095 | /// base node, which points to inline assembly AST node. Next, navigate |
| 2118 | /// to the asm template source code. | 2096 | /// to the asm template source code. |
| 2119 | node_offset_asm_source: i32, | 2097 | node_offset_asm_source: Ast.Node.Offset, |
| 2120 | /// The source location points to the return type of an inline assembly | 2098 | /// The source location points to the return type of an inline assembly |
| 2121 | /// expression, found by taking this AST node index offset from the containing | 2099 | /// expression, found by taking this AST node index offset from the containing |
| 2122 | /// base node, which points to inline assembly AST node. Next, navigate | 2100 | /// base node, which points to inline assembly AST node. Next, navigate |
| 2123 | /// to the return type expression. | 2101 | /// to the return type expression. |
| 2124 | node_offset_asm_ret_ty: i32, | 2102 | node_offset_asm_ret_ty: Ast.Node.Offset, |
| 2125 | /// The source location points to the condition expression of an if | 2103 | /// The source location points to the condition expression of an if |
| 2126 | /// expression, found by taking this AST node index offset from the containing | 2104 | /// expression, found by taking this AST node index offset from the containing |
| 2127 | /// base node, which points to an if expression AST node. Next, navigate | 2105 | /// base node, which points to an if expression AST node. Next, navigate |
| 2128 | /// to the condition expression. | 2106 | /// to the condition expression. |
| 2129 | node_offset_if_cond: i32, | 2107 | node_offset_if_cond: Ast.Node.Offset, |
| 2130 | /// The source location points to a binary expression, such as `a + b`, found | 2108 | /// The source location points to a binary expression, such as `a + b`, found |
| 2131 | /// by taking this AST node index offset from the containing base node. | 2109 | /// by taking this AST node index offset from the containing base node. |
| 2132 | node_offset_bin_op: i32, | 2110 | node_offset_bin_op: Ast.Node.Offset, |
| 2133 | /// The source location points to the LHS of a binary expression, found | 2111 | /// The source location points to the LHS of a binary expression, found |
| 2134 | /// by taking this AST node index offset from the containing base node, | 2112 | /// by taking this AST node index offset from the containing base node, |
| 2135 | /// which points to a binary expression AST node. Next, navigate to the LHS. | 2113 | /// which points to a binary expression AST node. Next, navigate to the LHS. |
| 2136 | node_offset_bin_lhs: i32, | 2114 | node_offset_bin_lhs: Ast.Node.Offset, |
| 2137 | /// The source location points to the RHS of a binary expression, found | 2115 | /// The source location points to the RHS of a binary expression, found |
| 2138 | /// by taking this AST node index offset from the containing base node, | 2116 | /// by taking this AST node index offset from the containing base node, |
| 2139 | /// which points to a binary expression AST node. Next, navigate to the RHS. | 2117 | /// which points to a binary expression AST node. Next, navigate to the RHS. |
| 2140 | node_offset_bin_rhs: i32, | 2118 | node_offset_bin_rhs: Ast.Node.Offset, |
| 2119 | /// The source location points to the operand of a try expression, found | ||
| 2120 | /// by taking this AST node index offset from the containing base node, | ||
| 2121 | /// which points to a try expression AST node. Next, navigate to the | ||
| 2122 | /// operand expression. | ||
| 2123 | node_offset_try_operand: Ast.Node.Offset, | ||
| 2141 | /// The source location points to the operand of a switch expression, found | 2124 | /// The source location points to the operand of a switch expression, found |
| 2142 | /// by taking this AST node index offset from the containing base node, | 2125 | /// by taking this AST node index offset from the containing base node, |
| 2143 | /// which points to a switch expression AST node. Next, navigate to the operand. | 2126 | /// which points to a switch expression AST node. Next, navigate to the operand. |
| 2144 | node_offset_switch_operand: i32, | 2127 | node_offset_switch_operand: Ast.Node.Offset, |
| 2145 | /// The source location points to the else/`_` prong of a switch expression, found | 2128 | /// The source location points to the else/`_` prong of a switch expression, found |
| 2146 | /// by taking this AST node index offset from the containing base node, | 2129 | /// by taking this AST node index offset from the containing base node, |
| 2147 | /// which points to a switch expression AST node. Next, navigate to the else/`_` prong. | 2130 | /// which points to a switch expression AST node. Next, navigate to the else/`_` prong. |
| 2148 | node_offset_switch_special_prong: i32, | 2131 | node_offset_switch_special_prong: Ast.Node.Offset, |
| 2149 | /// The source location points to all the ranges of a switch expression, found | 2132 | /// The source location points to all the ranges of a switch expression, found |
| 2150 | /// by taking this AST node index offset from the containing base node, | 2133 | /// by taking this AST node index offset from the containing base node, |
| 2151 | /// which points to a switch expression AST node. Next, navigate to any of the | 2134 | /// which points to a switch expression AST node. Next, navigate to any of the |
| 2152 | /// range nodes. The error applies to all of them. | 2135 | /// range nodes. The error applies to all of them. |
| 2153 | node_offset_switch_range: i32, | 2136 | node_offset_switch_range: Ast.Node.Offset, |
| 2154 | /// The source location points to the align expr of a function type | 2137 | /// The source location points to the align expr of a function type |
| 2155 | /// expression, found by taking this AST node index offset from the containing | 2138 | /// expression, found by taking this AST node index offset from the containing |
| 2156 | /// base node, which points to a function type AST node. Next, navigate to | 2139 | /// base node, which points to a function type AST node. Next, navigate to |
| 2157 | /// the calling convention node. | 2140 | /// the calling convention node. |
| 2158 | node_offset_fn_type_align: i32, | 2141 | node_offset_fn_type_align: Ast.Node.Offset, |
| 2159 | /// The source location points to the addrspace expr of a function type | 2142 | /// The source location points to the addrspace expr of a function type |
| 2160 | /// expression, found by taking this AST node index offset from the containing | 2143 | /// expression, found by taking this AST node index offset from the containing |
| 2161 | /// base node, which points to a function type AST node. Next, navigate to | 2144 | /// base node, which points to a function type AST node. Next, navigate to |
| 2162 | /// the calling convention node. | 2145 | /// the calling convention node. |
| 2163 | node_offset_fn_type_addrspace: i32, | 2146 | node_offset_fn_type_addrspace: Ast.Node.Offset, |
| 2164 | /// The source location points to the linksection expr of a function type | 2147 | /// The source location points to the linksection expr of a function type |
| 2165 | /// expression, found by taking this AST node index offset from the containing | 2148 | /// expression, found by taking this AST node index offset from the containing |
| 2166 | /// base node, which points to a function type AST node. Next, navigate to | 2149 | /// base node, which points to a function type AST node. Next, navigate to |
| 2167 | /// the calling convention node. | 2150 | /// the calling convention node. |
| 2168 | node_offset_fn_type_section: i32, | 2151 | node_offset_fn_type_section: Ast.Node.Offset, |
| 2169 | /// The source location points to the calling convention of a function type | 2152 | /// The source location points to the calling convention of a function type |
| 2170 | /// expression, found by taking this AST node index offset from the containing | 2153 | /// expression, found by taking this AST node index offset from the containing |
| 2171 | /// base node, which points to a function type AST node. Next, navigate to | 2154 | /// base node, which points to a function type AST node. Next, navigate to |
| 2172 | /// the calling convention node. | 2155 | /// the calling convention node. |
| 2173 | node_offset_fn_type_cc: i32, | 2156 | node_offset_fn_type_cc: Ast.Node.Offset, |
| 2174 | /// The source location points to the return type of a function type | 2157 | /// The source location points to the return type of a function type |
| 2175 | /// expression, found by taking this AST node index offset from the containing | 2158 | /// expression, found by taking this AST node index offset from the containing |
| 2176 | /// base node, which points to a function type AST node. Next, navigate to | 2159 | /// base node, which points to a function type AST node. Next, navigate to |
| 2177 | /// the return type node. | 2160 | /// the return type node. |
| 2178 | node_offset_fn_type_ret_ty: i32, | 2161 | node_offset_fn_type_ret_ty: Ast.Node.Offset, |
| 2179 | node_offset_param: i32, | 2162 | node_offset_param: Ast.Node.Offset, |
| 2180 | token_offset_param: i32, | 2163 | token_offset_param: Ast.TokenOffset, |
| 2181 | /// The source location points to the type expression of an `anyframe->T` | 2164 | /// The source location points to the type expression of an `anyframe->T` |
| 2182 | /// expression, found by taking this AST node index offset from the containing | 2165 | /// expression, found by taking this AST node index offset from the containing |
| 2183 | /// base node, which points to a `anyframe->T` expression AST node. Next, navigate | 2166 | /// base node, which points to a `anyframe->T` expression AST node. Next, navigate |
| 2184 | /// to the type expression. | 2167 | /// to the type expression. |
| 2185 | node_offset_anyframe_type: i32, | 2168 | node_offset_anyframe_type: Ast.Node.Offset, |
| 2186 | /// The source location points to the string literal of `extern "foo"`, found | 2169 | /// The source location points to the string literal of `extern "foo"`, found |
| 2187 | /// by taking this AST node index offset from the containing | 2170 | /// by taking this AST node index offset from the containing |
| 2188 | /// base node, which points to a function prototype or variable declaration | 2171 | /// base node, which points to a function prototype or variable declaration |
| 2189 | /// expression AST node. Next, navigate to the string literal of the `extern "foo"`. | 2172 | /// expression AST node. Next, navigate to the string literal of the `extern "foo"`. |
| 2190 | node_offset_lib_name: i32, | 2173 | node_offset_lib_name: Ast.Node.Offset, |
| 2191 | /// The source location points to the len expression of an `[N:S]T` | 2174 | /// The source location points to the len expression of an `[N:S]T` |
| 2192 | /// expression, found by taking this AST node index offset from the containing | 2175 | /// expression, found by taking this AST node index offset from the containing |
| 2193 | /// base node, which points to an `[N:S]T` expression AST node. Next, navigate | 2176 | /// base node, which points to an `[N:S]T` expression AST node. Next, navigate |
| 2194 | /// to the len expression. | 2177 | /// to the len expression. |
| 2195 | node_offset_array_type_len: i32, | 2178 | node_offset_array_type_len: Ast.Node.Offset, |
| 2196 | /// The source location points to the sentinel expression of an `[N:S]T` | 2179 | /// The source location points to the sentinel expression of an `[N:S]T` |
| 2197 | /// expression, found by taking this AST node index offset from the containing | 2180 | /// expression, found by taking this AST node index offset from the containing |
| 2198 | /// base node, which points to an `[N:S]T` expression AST node. Next, navigate | 2181 | /// base node, which points to an `[N:S]T` expression AST node. Next, navigate |
| 2199 | /// to the sentinel expression. | 2182 | /// to the sentinel expression. |
| 2200 | node_offset_array_type_sentinel: i32, | 2183 | node_offset_array_type_sentinel: Ast.Node.Offset, |
| 2201 | /// The source location points to the elem expression of an `[N:S]T` | 2184 | /// The source location points to the elem expression of an `[N:S]T` |
| 2202 | /// expression, found by taking this AST node index offset from the containing | 2185 | /// expression, found by taking this AST node index offset from the containing |
| 2203 | /// base node, which points to an `[N:S]T` expression AST node. Next, navigate | 2186 | /// base node, which points to an `[N:S]T` expression AST node. Next, navigate |
| 2204 | /// to the elem expression. | 2187 | /// to the elem expression. |
| 2205 | node_offset_array_type_elem: i32, | 2188 | node_offset_array_type_elem: Ast.Node.Offset, |
| 2206 | /// The source location points to the operand of an unary expression. | 2189 | /// The source location points to the operand of an unary expression. |
| 2207 | node_offset_un_op: i32, | 2190 | node_offset_un_op: Ast.Node.Offset, |
| 2208 | /// The source location points to the elem type of a pointer. | 2191 | /// The source location points to the elem type of a pointer. |
| 2209 | node_offset_ptr_elem: i32, | 2192 | node_offset_ptr_elem: Ast.Node.Offset, |
| 2210 | /// The source location points to the sentinel of a pointer. | 2193 | /// The source location points to the sentinel of a pointer. |
| 2211 | node_offset_ptr_sentinel: i32, | 2194 | node_offset_ptr_sentinel: Ast.Node.Offset, |
| 2212 | /// The source location points to the align expr of a pointer. | 2195 | /// The source location points to the align expr of a pointer. |
| 2213 | node_offset_ptr_align: i32, | 2196 | node_offset_ptr_align: Ast.Node.Offset, |
| 2214 | /// The source location points to the addrspace expr of a pointer. | 2197 | /// The source location points to the addrspace expr of a pointer. |
| 2215 | node_offset_ptr_addrspace: i32, | 2198 | node_offset_ptr_addrspace: Ast.Node.Offset, |
| 2216 | /// The source location points to the bit-offset of a pointer. | 2199 | /// The source location points to the bit-offset of a pointer. |
| 2217 | node_offset_ptr_bitoffset: i32, | 2200 | node_offset_ptr_bitoffset: Ast.Node.Offset, |
| 2218 | /// The source location points to the host size of a pointer. | 2201 | /// The source location points to the host size of a pointer. |
| 2219 | node_offset_ptr_hostsize: i32, | 2202 | node_offset_ptr_hostsize: Ast.Node.Offset, |
| 2220 | /// The source location points to the tag type of an union or an enum. | 2203 | /// The source location points to the tag type of an union or an enum. |
| 2221 | node_offset_container_tag: i32, | 2204 | node_offset_container_tag: Ast.Node.Offset, |
| 2222 | /// The source location points to the default value of a field. | 2205 | /// The source location points to the default value of a field. |
| 2223 | node_offset_field_default: i32, | 2206 | node_offset_field_default: Ast.Node.Offset, |
| 2224 | /// The source location points to the type of an array or struct initializer. | 2207 | /// The source location points to the type of an array or struct initializer. |
| 2225 | node_offset_init_ty: i32, | 2208 | node_offset_init_ty: Ast.Node.Offset, |
| 2226 | /// The source location points to the LHS of an assignment. | 2209 | /// The source location points to the LHS of an assignment. |
| 2227 | node_offset_store_ptr: i32, | 2210 | node_offset_store_ptr: Ast.Node.Offset, |
| 2228 | /// The source location points to the RHS of an assignment. | 2211 | /// The source location points to the RHS of an assignment. |
| 2229 | node_offset_store_operand: i32, | 2212 | node_offset_store_operand: Ast.Node.Offset, |
| 2230 | /// The source location points to the operand of a `return` statement, or | 2213 | /// The source location points to the operand of a `return` statement, or |
| 2231 | /// the `return` itself if there is no explicit operand. | 2214 | /// the `return` itself if there is no explicit operand. |
| 2232 | node_offset_return_operand: i32, | 2215 | node_offset_return_operand: Ast.Node.Offset, |
| 2233 | /// The source location points to a for loop input. | 2216 | /// The source location points to a for loop input. |
| 2234 | for_input: struct { | 2217 | for_input: struct { |
| 2235 | /// Points to the for loop AST node. | 2218 | /// Points to the for loop AST node. |
| 2236 | for_node_offset: i32, | 2219 | for_node_offset: Ast.Node.Offset, |
| 2237 | /// Picks one of the inputs from the condition. | 2220 | /// Picks one of the inputs from the condition. |
| 2238 | input_index: u32, | 2221 | input_index: u32, |
| 2239 | }, | 2222 | }, |
| ... | @@ -2241,11 +2224,11 @@ pub const LazySrcLoc = struct { | ... | @@ -2241,11 +2224,11 @@ pub const LazySrcLoc = struct { |
| 2241 | /// by taking this AST node index offset from the containing | 2224 | /// by taking this AST node index offset from the containing |
| 2242 | /// base node, which points to one of the input nodes of a for loop. | 2225 | /// base node, which points to one of the input nodes of a for loop. |
| 2243 | /// Next, navigate to the corresponding capture. | 2226 | /// Next, navigate to the corresponding capture. |
| 2244 | for_capture_from_input: i32, | 2227 | for_capture_from_input: Ast.Node.Offset, |
| 2245 | /// The source location points to the argument node of a function call. | 2228 | /// The source location points to the argument node of a function call. |
| 2246 | call_arg: struct { | 2229 | call_arg: struct { |
| 2247 | /// Points to the function call AST node. | 2230 | /// Points to the function call AST node. |
| 2248 | call_node_offset: i32, | 2231 | call_node_offset: Ast.Node.Offset, |
| 2249 | /// The index of the argument the source location points to. | 2232 | /// The index of the argument the source location points to. |
| 2250 | arg_index: u32, | 2233 | arg_index: u32, |
| 2251 | }, | 2234 | }, |
| ... | @@ -2272,25 +2255,25 @@ pub const LazySrcLoc = struct { | ... | @@ -2272,25 +2255,25 @@ pub const LazySrcLoc = struct { |
| 2272 | /// array initialization expression. | 2255 | /// array initialization expression. |
| 2273 | init_elem: struct { | 2256 | init_elem: struct { |
| 2274 | /// Points to the AST node of the initialization expression. | 2257 | /// Points to the AST node of the initialization expression. |
| 2275 | init_node_offset: i32, | 2258 | init_node_offset: Ast.Node.Offset, |
| 2276 | /// The index of the field/element the source location points to. | 2259 | /// The index of the field/element the source location points to. |
| 2277 | elem_index: u32, | 2260 | elem_index: u32, |
| 2278 | }, | 2261 | }, |
| 2279 | // The following source locations are like `init_elem`, but refer to a | 2262 | // The following source locations are like `init_elem`, but refer to a |
| 2280 | // field with a specific name. If such a field is not given, the entire | 2263 | // field with a specific name. If such a field is not given, the entire |
| 2281 | // initialization expression is used instead. | 2264 | // initialization expression is used instead. |
| 2282 | // The `i32` points to the AST node of a builtin call, whose *second* | 2265 | // The `Ast.Node.Offset` points to the AST node of a builtin call, whose *second* |
| 2283 | // argument is the init expression. | 2266 | // argument is the init expression. |
| 2284 | init_field_name: i32, | 2267 | init_field_name: Ast.Node.Offset, |
| 2285 | init_field_linkage: i32, | 2268 | init_field_linkage: Ast.Node.Offset, |
| 2286 | init_field_section: i32, | 2269 | init_field_section: Ast.Node.Offset, |
| 2287 | init_field_visibility: i32, | 2270 | init_field_visibility: Ast.Node.Offset, |
| 2288 | init_field_rw: i32, | 2271 | init_field_rw: Ast.Node.Offset, |
| 2289 | init_field_locality: i32, | 2272 | init_field_locality: Ast.Node.Offset, |
| 2290 | init_field_cache: i32, | 2273 | init_field_cache: Ast.Node.Offset, |
| 2291 | init_field_library: i32, | 2274 | init_field_library: Ast.Node.Offset, |
| 2292 | init_field_thread_local: i32, | 2275 | init_field_thread_local: Ast.Node.Offset, |
| 2293 | init_field_dll_import: i32, | 2276 | init_field_dll_import: Ast.Node.Offset, |
| 2294 | /// The source location points to the value of an item in a specific | 2277 | /// The source location points to the value of an item in a specific |
| 2295 | /// case of a `switch`. | 2278 | /// case of a `switch`. |
| 2296 | switch_case_item: SwitchItem, | 2279 | switch_case_item: SwitchItem, |
| ... | @@ -2315,14 +2298,14 @@ pub const LazySrcLoc = struct { | ... | @@ -2315,14 +2298,14 @@ pub const LazySrcLoc = struct { |
| 2315 | 2298 | ||
| 2316 | pub const FnProtoParam = struct { | 2299 | pub const FnProtoParam = struct { |
| 2317 | /// The offset of the function prototype AST node. | 2300 | /// The offset of the function prototype AST node. |
| 2318 | fn_proto_node_offset: i32, | 2301 | fn_proto_node_offset: Ast.Node.Offset, |
| 2319 | /// The index of the parameter the source location points to. | 2302 | /// The index of the parameter the source location points to. |
| 2320 | param_index: u32, | 2303 | param_index: u32, |
| 2321 | }; | 2304 | }; |
| 2322 | 2305 | ||
| 2323 | pub const SwitchItem = struct { | 2306 | pub const SwitchItem = struct { |
| 2324 | /// The offset of the switch AST node. | 2307 | /// The offset of the switch AST node. |
| 2325 | switch_node_offset: i32, | 2308 | switch_node_offset: Ast.Node.Offset, |
| 2326 | /// The index of the case to point to within this switch. | 2309 | /// The index of the case to point to within this switch. |
| 2327 | case_idx: SwitchCaseIndex, | 2310 | case_idx: SwitchCaseIndex, |
| 2328 | /// The index of the item to point to within this case. | 2311 | /// The index of the item to point to within this case. |
| ... | @@ -2331,7 +2314,7 @@ pub const LazySrcLoc = struct { | ... | @@ -2331,7 +2314,7 @@ pub const LazySrcLoc = struct { |
| 2331 | 2314 | ||
| 2332 | pub const SwitchCapture = struct { | 2315 | pub const SwitchCapture = struct { |
| 2333 | /// The offset of the switch AST node. | 2316 | /// The offset of the switch AST node. |
| 2334 | switch_node_offset: i32, | 2317 | switch_node_offset: Ast.Node.Offset, |
| 2335 | /// The index of the case whose capture to point to. | 2318 | /// The index of the case whose capture to point to. |
| 2336 | case_idx: SwitchCaseIndex, | 2319 | case_idx: SwitchCaseIndex, |
| 2337 | }; | 2320 | }; |
| ... | @@ -2353,34 +2336,34 @@ pub const LazySrcLoc = struct { | ... | @@ -2353,34 +2336,34 @@ pub const LazySrcLoc = struct { |
| 2353 | 2336 | ||
| 2354 | pub const ArrayCat = struct { | 2337 | pub const ArrayCat = struct { |
| 2355 | /// Points to the array concat AST node. | 2338 | /// Points to the array concat AST node. |
| 2356 | array_cat_offset: i32, | 2339 | array_cat_offset: Ast.Node.Offset, |
| 2357 | /// The index of the element the source location points to. | 2340 | /// The index of the element the source location points to. |
| 2358 | elem_index: u32, | 2341 | elem_index: u32, |
| 2359 | }; | 2342 | }; |
| 2360 | 2343 | ||
| 2361 | pub const TupleField = struct { | 2344 | pub const TupleField = struct { |
| 2362 | /// Points to the AST node of the tuple type decaration. | 2345 | /// Points to the AST node of the tuple type decaration. |
| 2363 | tuple_decl_node_offset: i32, | 2346 | tuple_decl_node_offset: Ast.Node.Offset, |
| 2364 | /// The index of the tuple field the source location points to. | 2347 | /// The index of the tuple field the source location points to. |
| 2365 | elem_index: u32, | 2348 | elem_index: u32, |
| 2366 | }; | 2349 | }; |
| 2367 | 2350 | ||
| 2368 | pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease; | 2351 | pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease; |
| 2369 | 2352 | ||
| 2370 | noinline fn nodeOffsetDebug(node_offset: i32) Offset { | 2353 | noinline fn nodeOffsetDebug(node_offset: Ast.Node.Offset) Offset { |
| 2371 | var result: LazySrcLoc = .{ .node_offset = .{ .x = node_offset } }; | 2354 | var result: LazySrcLoc = .{ .node_offset = .{ .x = node_offset } }; |
| 2372 | result.node_offset.trace.addAddr(@returnAddress(), "init"); | 2355 | result.node_offset.trace.addAddr(@returnAddress(), "init"); |
| 2373 | return result; | 2356 | return result; |
| 2374 | } | 2357 | } |
| 2375 | 2358 | ||
| 2376 | fn nodeOffsetRelease(node_offset: i32) Offset { | 2359 | fn nodeOffsetRelease(node_offset: Ast.Node.Offset) Offset { |
| 2377 | return .{ .node_offset = .{ .x = node_offset } }; | 2360 | return .{ .node_offset = .{ .x = node_offset } }; |
| 2378 | } | 2361 | } |
| 2379 | 2362 | ||
| 2380 | /// This wraps a simple integer in debug builds so that later on we can find out | 2363 | /// This wraps a simple integer in debug builds so that later on we can find out |
| 2381 | /// where in semantic analysis the value got set. | 2364 | /// where in semantic analysis the value got set. |
| 2382 | pub const TracedOffset = struct { | 2365 | pub const TracedOffset = struct { |
| 2383 | x: i32, | 2366 | x: Ast.Node.Offset, |
| 2384 | trace: std.debug.Trace = std.debug.Trace.init, | 2367 | trace: std.debug.Trace = std.debug.Trace.init, |
| 2385 | 2368 | ||
| 2386 | const want_tracing = false; | 2369 | const want_tracing = false; |
| ... | @@ -2405,7 +2388,7 @@ pub const LazySrcLoc = struct { | ... | @@ -2405,7 +2388,7 @@ pub const LazySrcLoc = struct { |
| 2405 | 2388 | ||
| 2406 | // If we're relative to .main_struct_inst, we know the ast node is the root and don't need to resolve the ZIR, | 2389 | // If we're relative to .main_struct_inst, we know the ast node is the root and don't need to resolve the ZIR, |
| 2407 | // which may not exist e.g. in the case of errors in ZON files. | 2390 | // which may not exist e.g. in the case of errors in ZON files. |
| 2408 | if (zir_inst == .main_struct_inst) return .{ file, 0 }; | 2391 | if (zir_inst == .main_struct_inst) return .{ file, .root }; |
| 2409 | 2392 | ||
| 2410 | // Otherwise, make sure ZIR is loaded. | 2393 | // Otherwise, make sure ZIR is loaded. |
| 2411 | const zir = file.zir.?; | 2394 | const zir = file.zir.?; |
| ... | @@ -2438,7 +2421,7 @@ pub const LazySrcLoc = struct { | ... | @@ -2438,7 +2421,7 @@ pub const LazySrcLoc = struct { |
| 2438 | pub fn upgradeOrLost(lazy: LazySrcLoc, zcu: *Zcu) ?SrcLoc { | 2421 | pub fn upgradeOrLost(lazy: LazySrcLoc, zcu: *Zcu) ?SrcLoc { |
| 2439 | const file, const base_node: Ast.Node.Index = if (lazy.offset == .entire_file) .{ | 2422 | const file, const base_node: Ast.Node.Index = if (lazy.offset == .entire_file) .{ |
| 2440 | zcu.fileByIndex(lazy.base_node_inst.resolveFile(&zcu.intern_pool)), | 2423 | zcu.fileByIndex(lazy.base_node_inst.resolveFile(&zcu.intern_pool)), |
| 2441 | 0, | 2424 | .root, |
| 2442 | } else resolveBaseNode(lazy.base_node_inst, zcu) orelse return null; | 2425 | } else resolveBaseNode(lazy.base_node_inst, zcu) orelse return null; |
| 2443 | return .{ | 2426 | return .{ |
| 2444 | .file_scope = file, | 2427 | .file_scope = file, |
| ... | @@ -4007,7 +3990,7 @@ pub fn navSrcLoc(zcu: *const Zcu, nav_index: InternPool.Nav.Index) LazySrcLoc { | ... | @@ -4007,7 +3990,7 @@ pub fn navSrcLoc(zcu: *const Zcu, nav_index: InternPool.Nav.Index) LazySrcLoc { |
| 4007 | const ip = &zcu.intern_pool; | 3990 | const ip = &zcu.intern_pool; |
| 4008 | return .{ | 3991 | return .{ |
| 4009 | .base_node_inst = ip.getNav(nav_index).srcInst(ip), | 3992 | .base_node_inst = ip.getNav(nav_index).srcInst(ip), |
| 4010 | .offset = LazySrcLoc.Offset.nodeOffset(0), | 3993 | .offset = LazySrcLoc.Offset.nodeOffset(.zero), |
| 4011 | }; | 3994 | }; |
| 4012 | } | 3995 | } |
| 4013 | 3996 |
src/Zcu/PerThread.zig+11-11| ... | @@ -841,7 +841,7 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu | ... | @@ -841,7 +841,7 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu |
| 841 | .comptime_reason = .{ .reason = .{ | 841 | .comptime_reason = .{ .reason = .{ |
| 842 | .src = .{ | 842 | .src = .{ |
| 843 | .base_node_inst = comptime_unit.zir_index, | 843 | .base_node_inst = comptime_unit.zir_index, |
| 844 | .offset = .{ .token_offset = 0 }, | 844 | .offset = .{ .token_offset = .zero }, |
| 845 | }, | 845 | }, |
| 846 | .r = .{ .simple = .comptime_keyword }, | 846 | .r = .{ .simple = .comptime_keyword }, |
| 847 | } }, | 847 | } }, |
| ... | @@ -1042,11 +1042,11 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr | ... | @@ -1042,11 +1042,11 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr |
| 1042 | const zir_decl = zir.getDeclaration(inst_resolved.inst); | 1042 | const zir_decl = zir.getDeclaration(inst_resolved.inst); |
| 1043 | assert(old_nav.is_usingnamespace == (zir_decl.kind == .@"usingnamespace")); | 1043 | assert(old_nav.is_usingnamespace == (zir_decl.kind == .@"usingnamespace")); |
| 1044 | 1044 | ||
| 1045 | const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 }); | 1045 | const ty_src = block.src(.{ .node_offset_var_decl_ty = .zero }); |
| 1046 | const init_src = block.src(.{ .node_offset_var_decl_init = 0 }); | 1046 | const init_src = block.src(.{ .node_offset_var_decl_init = .zero }); |
| 1047 | const align_src = block.src(.{ .node_offset_var_decl_align = 0 }); | 1047 | const align_src = block.src(.{ .node_offset_var_decl_align = .zero }); |
| 1048 | const section_src = block.src(.{ .node_offset_var_decl_section = 0 }); | 1048 | const section_src = block.src(.{ .node_offset_var_decl_section = .zero }); |
| 1049 | const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = 0 }); | 1049 | const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = .zero }); |
| 1050 | 1050 | ||
| 1051 | block.comptime_reason = .{ .reason = .{ | 1051 | block.comptime_reason = .{ .reason = .{ |
| 1052 | .src = init_src, | 1052 | .src = init_src, |
| ... | @@ -1135,7 +1135,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr | ... | @@ -1135,7 +1135,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr |
| 1135 | break :l zir.nullTerminatedString(zir_decl.lib_name); | 1135 | break :l zir.nullTerminatedString(zir_decl.lib_name); |
| 1136 | } else null; | 1136 | } else null; |
| 1137 | if (lib_name) |l| { | 1137 | if (lib_name) |l| { |
| 1138 | const lib_name_src = block.src(.{ .node_offset_lib_name = 0 }); | 1138 | const lib_name_src = block.src(.{ .node_offset_lib_name = .zero }); |
| 1139 | try sema.handleExternLibName(&block, lib_name_src, l); | 1139 | try sema.handleExternLibName(&block, lib_name_src, l); |
| 1140 | } | 1140 | } |
| 1141 | break :val .fromInterned(try pt.getExtern(.{ | 1141 | break :val .fromInterned(try pt.getExtern(.{ |
| ... | @@ -1233,7 +1233,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr | ... | @@ -1233,7 +1233,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr |
| 1233 | } | 1233 | } |
| 1234 | 1234 | ||
| 1235 | if (zir_decl.linkage == .@"export") { | 1235 | if (zir_decl.linkage == .@"export") { |
| 1236 | const export_src = block.src(.{ .token_offset = @intFromBool(zir_decl.is_pub) }); | 1236 | const export_src = block.src(.{ .token_offset = @enumFromInt(@intFromBool(zir_decl.is_pub)) }); |
| 1237 | const name_slice = zir.nullTerminatedString(zir_decl.name); | 1237 | const name_slice = zir.nullTerminatedString(zir_decl.name); |
| 1238 | const name_ip = try ip.getOrPutString(gpa, pt.tid, name_slice, .no_embedded_nulls); | 1238 | const name_ip = try ip.getOrPutString(gpa, pt.tid, name_slice, .no_embedded_nulls); |
| 1239 | try sema.analyzeExport(&block, export_src, .{ .name = name_ip }, nav_id); | 1239 | try sema.analyzeExport(&block, export_src, .{ .name = name_ip }, nav_id); |
| ... | @@ -1414,7 +1414,7 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr | ... | @@ -1414,7 +1414,7 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr |
| 1414 | const zir_decl = zir.getDeclaration(inst_resolved.inst); | 1414 | const zir_decl = zir.getDeclaration(inst_resolved.inst); |
| 1415 | assert(old_nav.is_usingnamespace == (zir_decl.kind == .@"usingnamespace")); | 1415 | assert(old_nav.is_usingnamespace == (zir_decl.kind == .@"usingnamespace")); |
| 1416 | 1416 | ||
| 1417 | const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 }); | 1417 | const ty_src = block.src(.{ .node_offset_var_decl_ty = .zero }); |
| 1418 | 1418 | ||
| 1419 | block.comptime_reason = .{ .reason = .{ | 1419 | block.comptime_reason = .{ .reason = .{ |
| 1420 | .src = ty_src, | 1420 | .src = ty_src, |
| ... | @@ -2743,7 +2743,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE | ... | @@ -2743,7 +2743,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE |
| 2743 | if (sema.fn_ret_ty_ies) |ies| { | 2743 | if (sema.fn_ret_ty_ies) |ies| { |
| 2744 | sema.resolveInferredErrorSetPtr(&inner_block, .{ | 2744 | sema.resolveInferredErrorSetPtr(&inner_block, .{ |
| 2745 | .base_node_inst = inner_block.src_base_inst, | 2745 | .base_node_inst = inner_block.src_base_inst, |
| 2746 | .offset = Zcu.LazySrcLoc.Offset.nodeOffset(0), | 2746 | .offset = Zcu.LazySrcLoc.Offset.nodeOffset(.zero), |
| 2747 | }, ies) catch |err| switch (err) { | 2747 | }, ies) catch |err| switch (err) { |
| 2748 | error.ComptimeReturn => unreachable, | 2748 | error.ComptimeReturn => unreachable, |
| 2749 | error.ComptimeBreak => unreachable, | 2749 | error.ComptimeBreak => unreachable, |
| ... | @@ -2762,7 +2762,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE | ... | @@ -2762,7 +2762,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE |
| 2762 | // result in circular dependency errors. | 2762 | // result in circular dependency errors. |
| 2763 | // TODO: this can go away once we fix backends having to resolve `StackTrace`. | 2763 | // TODO: this can go away once we fix backends having to resolve `StackTrace`. |
| 2764 | // The codegen timing guarantees that the parameter types will be populated. | 2764 | // The codegen timing guarantees that the parameter types will be populated. |
| 2765 | sema.resolveFnTypes(fn_ty, inner_block.nodeOffset(0)) catch |err| switch (err) { | 2765 | sema.resolveFnTypes(fn_ty, inner_block.nodeOffset(.zero)) catch |err| switch (err) { |
| 2766 | error.ComptimeReturn => unreachable, | 2766 | error.ComptimeReturn => unreachable, |
| 2767 | error.ComptimeBreak => unreachable, | 2767 | error.ComptimeBreak => unreachable, |
| 2768 | else => |e| return e, | 2768 | else => |e| return e, |
src/main.zig+10-8| ... | @@ -5224,7 +5224,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5224,7 +5224,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5224 | .arena = std.heap.ArenaAllocator.init(gpa), | 5224 | .arena = std.heap.ArenaAllocator.init(gpa), |
| 5225 | .location = .{ .relative_path = build_mod.root }, | 5225 | .location = .{ .relative_path = build_mod.root }, |
| 5226 | .location_tok = 0, | 5226 | .location_tok = 0, |
| 5227 | .hash_tok = 0, | 5227 | .hash_tok = .none, |
| 5228 | .name_tok = 0, | 5228 | .name_tok = 0, |
| 5229 | .lazy_status = .eager, | 5229 | .lazy_status = .eager, |
| 5230 | .parent_package_root = build_mod.root, | 5230 | .parent_package_root = build_mod.root, |
| ... | @@ -6285,8 +6285,10 @@ fn cmdAstCheck( | ... | @@ -6285,8 +6285,10 @@ fn cmdAstCheck( |
| 6285 | file.tree.?.tokens.len * (@sizeOf(std.zig.Token.Tag) + @sizeOf(Ast.ByteOffset)); | 6285 | file.tree.?.tokens.len * (@sizeOf(std.zig.Token.Tag) + @sizeOf(Ast.ByteOffset)); |
| 6286 | const tree_bytes = @sizeOf(Ast) + file.tree.?.nodes.len * | 6286 | const tree_bytes = @sizeOf(Ast) + file.tree.?.nodes.len * |
| 6287 | (@sizeOf(Ast.Node.Tag) + | 6287 | (@sizeOf(Ast.Node.Tag) + |
| 6288 | @sizeOf(Ast.Node.Data) + | 6288 | @sizeOf(Ast.TokenIndex) + |
| 6289 | @sizeOf(Ast.TokenIndex)); | 6289 | // Here we don't use @sizeOf(Ast.Node.Data) because it would include |
| 6290 | // the debug safety tag but we want to measure release size. | ||
| 6291 | 8); | ||
| 6290 | const instruction_bytes = file.zir.?.instructions.len * | 6292 | const instruction_bytes = file.zir.?.instructions.len * |
| 6291 | // Here we don't use @sizeOf(Zir.Inst.Data) because it would include | 6293 | // Here we don't use @sizeOf(Zir.Inst.Data) because it would include |
| 6292 | // the debug safety tag but we want to measure release size. | 6294 | // the debug safety tag but we want to measure release size. |
| ... | @@ -7126,7 +7128,7 @@ fn cmdFetch( | ... | @@ -7126,7 +7128,7 @@ fn cmdFetch( |
| 7126 | .arena = std.heap.ArenaAllocator.init(gpa), | 7128 | .arena = std.heap.ArenaAllocator.init(gpa), |
| 7127 | .location = .{ .path_or_url = path_or_url }, | 7129 | .location = .{ .path_or_url = path_or_url }, |
| 7128 | .location_tok = 0, | 7130 | .location_tok = 0, |
| 7129 | .hash_tok = 0, | 7131 | .hash_tok = .none, |
| 7130 | .name_tok = 0, | 7132 | .name_tok = 0, |
| 7131 | .lazy_status = .eager, | 7133 | .lazy_status = .eager, |
| 7132 | .parent_package_root = undefined, | 7134 | .parent_package_root = undefined, |
| ... | @@ -7282,8 +7284,8 @@ fn cmdFetch( | ... | @@ -7282,8 +7284,8 @@ fn cmdFetch( |
| 7282 | 7284 | ||
| 7283 | warn("overwriting existing dependency named '{s}'", .{name}); | 7285 | warn("overwriting existing dependency named '{s}'", .{name}); |
| 7284 | try fixups.replace_nodes_with_string.put(gpa, dep.location_node, location_replace); | 7286 | try fixups.replace_nodes_with_string.put(gpa, dep.location_node, location_replace); |
| 7285 | if (dep.hash_node != 0) { | 7287 | if (dep.hash_node.unwrap()) |hash_node| { |
| 7286 | try fixups.replace_nodes_with_string.put(gpa, dep.hash_node, hash_replace); | 7288 | try fixups.replace_nodes_with_string.put(gpa, hash_node, hash_replace); |
| 7287 | } else { | 7289 | } else { |
| 7288 | // https://github.com/ziglang/zig/issues/21690 | 7290 | // https://github.com/ziglang/zig/issues/21690 |
| 7289 | } | 7291 | } |
| ... | @@ -7292,9 +7294,9 @@ fn cmdFetch( | ... | @@ -7292,9 +7294,9 @@ fn cmdFetch( |
| 7292 | const deps = manifest.dependencies.values(); | 7294 | const deps = manifest.dependencies.values(); |
| 7293 | const last_dep_node = deps[deps.len - 1].node; | 7295 | const last_dep_node = deps[deps.len - 1].node; |
| 7294 | try fixups.append_string_after_node.put(gpa, last_dep_node, new_node_text); | 7296 | try fixups.append_string_after_node.put(gpa, last_dep_node, new_node_text); |
| 7295 | } else if (manifest.dependencies_node != 0) { | 7297 | } else if (manifest.dependencies_node.unwrap()) |dependencies_node| { |
| 7296 | // Add fixup for replacing the entire dependencies struct. | 7298 | // Add fixup for replacing the entire dependencies struct. |
| 7297 | try fixups.replace_nodes_with_string.put(gpa, manifest.dependencies_node, dependencies_init); | 7299 | try fixups.replace_nodes_with_string.put(gpa, dependencies_node, dependencies_init); |
| 7298 | } else { | 7300 | } else { |
| 7299 | // Add fixup for adding dependencies struct. | 7301 | // Add fixup for adding dependencies struct. |
| 7300 | try fixups.append_string_after_node.put(gpa, manifest.version_node, dependencies_text); | 7302 | try fixups.append_string_after_node.put(gpa, manifest.version_node, dependencies_text); |
src/print_zir.zig+22-23| ... | @@ -24,7 +24,7 @@ pub fn renderAsTextToFile( | ... | @@ -24,7 +24,7 @@ pub fn renderAsTextToFile( |
| 24 | .file = scope_file, | 24 | .file = scope_file, |
| 25 | .code = scope_file.zir.?, | 25 | .code = scope_file.zir.?, |
| 26 | .indent = 0, | 26 | .indent = 0, |
| 27 | .parent_decl_node = 0, | 27 | .parent_decl_node = .root, |
| 28 | .recurse_decls = true, | 28 | .recurse_decls = true, |
| 29 | .recurse_blocks = true, | 29 | .recurse_blocks = true, |
| 30 | }; | 30 | }; |
| ... | @@ -185,10 +185,6 @@ const Writer = struct { | ... | @@ -185,10 +185,6 @@ const Writer = struct { |
| 185 | } | 185 | } |
| 186 | } = .{}, | 186 | } = .{}, |
| 187 | 187 | ||
| 188 | fn relativeToNodeIndex(self: *Writer, offset: i32) Ast.Node.Index { | ||
| 189 | return @bitCast(offset + @as(i32, @bitCast(self.parent_decl_node))); | ||
| 190 | } | ||
| 191 | |||
| 192 | fn writeInstToStream( | 188 | fn writeInstToStream( |
| 193 | self: *Writer, | 189 | self: *Writer, |
| 194 | stream: anytype, | 190 | stream: anytype, |
| ... | @@ -595,7 +591,7 @@ const Writer = struct { | ... | @@ -595,7 +591,7 @@ const Writer = struct { |
| 595 | const prev_parent_decl_node = self.parent_decl_node; | 591 | const prev_parent_decl_node = self.parent_decl_node; |
| 596 | self.parent_decl_node = inst_data.node; | 592 | self.parent_decl_node = inst_data.node; |
| 597 | defer self.parent_decl_node = prev_parent_decl_node; | 593 | defer self.parent_decl_node = prev_parent_decl_node; |
| 598 | try self.writeSrcNode(stream, 0); | 594 | try self.writeSrcNode(stream, .zero); |
| 599 | }, | 595 | }, |
| 600 | 596 | ||
| 601 | .builtin_extern, | 597 | .builtin_extern, |
| ... | @@ -631,7 +627,8 @@ const Writer = struct { | ... | @@ -631,7 +627,8 @@ const Writer = struct { |
| 631 | 627 | ||
| 632 | fn writeExtNode(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { | 628 | fn writeExtNode(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { |
| 633 | try stream.writeAll(")) "); | 629 | try stream.writeAll(")) "); |
| 634 | try self.writeSrcNode(stream, @bitCast(extended.operand)); | 630 | const src_node: Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand))); |
| 631 | try self.writeSrcNode(stream, src_node); | ||
| 635 | } | 632 | } |
| 636 | 633 | ||
| 637 | fn writeArrayInitElemType(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { | 634 | fn writeArrayInitElemType(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { |
| ... | @@ -1579,7 +1576,7 @@ const Writer = struct { | ... | @@ -1579,7 +1576,7 @@ const Writer = struct { |
| 1579 | try stream.writeByteNTimes(' ', self.indent); | 1576 | try stream.writeByteNTimes(' ', self.indent); |
| 1580 | try stream.writeAll("}) "); | 1577 | try stream.writeAll("}) "); |
| 1581 | } | 1578 | } |
| 1582 | try self.writeSrcNode(stream, 0); | 1579 | try self.writeSrcNode(stream, .zero); |
| 1583 | } | 1580 | } |
| 1584 | 1581 | ||
| 1585 | fn writeUnionDecl(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { | 1582 | fn writeUnionDecl(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { |
| ... | @@ -1659,7 +1656,7 @@ const Writer = struct { | ... | @@ -1659,7 +1656,7 @@ const Writer = struct { |
| 1659 | 1656 | ||
| 1660 | if (fields_len == 0) { | 1657 | if (fields_len == 0) { |
| 1661 | try stream.writeAll("}) "); | 1658 | try stream.writeAll("}) "); |
| 1662 | try self.writeSrcNode(stream, 0); | 1659 | try self.writeSrcNode(stream, .zero); |
| 1663 | return; | 1660 | return; |
| 1664 | } | 1661 | } |
| 1665 | try stream.writeAll(", "); | 1662 | try stream.writeAll(", "); |
| ... | @@ -1730,7 +1727,7 @@ const Writer = struct { | ... | @@ -1730,7 +1727,7 @@ const Writer = struct { |
| 1730 | self.indent -= 2; | 1727 | self.indent -= 2; |
| 1731 | try stream.writeByteNTimes(' ', self.indent); | 1728 | try stream.writeByteNTimes(' ', self.indent); |
| 1732 | try stream.writeAll("}) "); | 1729 | try stream.writeAll("}) "); |
| 1733 | try self.writeSrcNode(stream, 0); | 1730 | try self.writeSrcNode(stream, .zero); |
| 1734 | } | 1731 | } |
| 1735 | 1732 | ||
| 1736 | fn writeEnumDecl(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { | 1733 | fn writeEnumDecl(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { |
| ... | @@ -1849,7 +1846,7 @@ const Writer = struct { | ... | @@ -1849,7 +1846,7 @@ const Writer = struct { |
| 1849 | try stream.writeByteNTimes(' ', self.indent); | 1846 | try stream.writeByteNTimes(' ', self.indent); |
| 1850 | try stream.writeAll("}) "); | 1847 | try stream.writeAll("}) "); |
| 1851 | } | 1848 | } |
| 1852 | try self.writeSrcNode(stream, 0); | 1849 | try self.writeSrcNode(stream, .zero); |
| 1853 | } | 1850 | } |
| 1854 | 1851 | ||
| 1855 | fn writeOpaqueDecl( | 1852 | fn writeOpaqueDecl( |
| ... | @@ -1893,7 +1890,7 @@ const Writer = struct { | ... | @@ -1893,7 +1890,7 @@ const Writer = struct { |
| 1893 | try stream.writeByteNTimes(' ', self.indent); | 1890 | try stream.writeByteNTimes(' ', self.indent); |
| 1894 | try stream.writeAll("}) "); | 1891 | try stream.writeAll("}) "); |
| 1895 | } | 1892 | } |
| 1896 | try self.writeSrcNode(stream, 0); | 1893 | try self.writeSrcNode(stream, .zero); |
| 1897 | } | 1894 | } |
| 1898 | 1895 | ||
| 1899 | fn writeTupleDecl(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { | 1896 | fn writeTupleDecl(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { |
| ... | @@ -2539,7 +2536,7 @@ const Writer = struct { | ... | @@ -2539,7 +2536,7 @@ const Writer = struct { |
| 2539 | ret_ty_body: []const Zir.Inst.Index, | 2536 | ret_ty_body: []const Zir.Inst.Index, |
| 2540 | ret_ty_is_generic: bool, | 2537 | ret_ty_is_generic: bool, |
| 2541 | body: []const Zir.Inst.Index, | 2538 | body: []const Zir.Inst.Index, |
| 2542 | src_node: i32, | 2539 | src_node: Ast.Node.Offset, |
| 2543 | src_locs: Zir.Inst.Func.SrcLocs, | 2540 | src_locs: Zir.Inst.Func.SrcLocs, |
| 2544 | noalias_bits: u32, | 2541 | noalias_bits: u32, |
| 2545 | ) !void { | 2542 | ) !void { |
| ... | @@ -2647,18 +2644,20 @@ const Writer = struct { | ... | @@ -2647,18 +2644,20 @@ const Writer = struct { |
| 2647 | } | 2644 | } |
| 2648 | 2645 | ||
| 2649 | try stream.writeAll(") "); | 2646 | try stream.writeAll(") "); |
| 2650 | try self.writeSrcNode(stream, 0); | 2647 | try self.writeSrcNode(stream, .zero); |
| 2651 | } | 2648 | } |
| 2652 | 2649 | ||
| 2653 | fn writeClosureGet(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { | 2650 | fn writeClosureGet(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { |
| 2654 | try stream.print("{d})) ", .{extended.small}); | 2651 | try stream.print("{d})) ", .{extended.small}); |
| 2655 | try self.writeSrcNode(stream, @bitCast(extended.operand)); | 2652 | const src_node: Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand))); |
| 2653 | try self.writeSrcNode(stream, src_node); | ||
| 2656 | } | 2654 | } |
| 2657 | 2655 | ||
| 2658 | fn writeBuiltinValue(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { | 2656 | fn writeBuiltinValue(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { |
| 2659 | const val: Zir.Inst.BuiltinValue = @enumFromInt(extended.small); | 2657 | const val: Zir.Inst.BuiltinValue = @enumFromInt(extended.small); |
| 2660 | try stream.print("{s})) ", .{@tagName(val)}); | 2658 | try stream.print("{s})) ", .{@tagName(val)}); |
| 2661 | try self.writeSrcNode(stream, @bitCast(extended.operand)); | 2659 | const src_node: Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand))); |
| 2660 | try self.writeSrcNode(stream, src_node); | ||
| 2662 | } | 2661 | } |
| 2663 | 2662 | ||
| 2664 | fn writeInplaceArithResultTy(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { | 2663 | fn writeInplaceArithResultTy(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { |
| ... | @@ -2760,9 +2759,9 @@ const Writer = struct { | ... | @@ -2760,9 +2759,9 @@ const Writer = struct { |
| 2760 | try stream.writeAll(name); | 2759 | try stream.writeAll(name); |
| 2761 | } | 2760 | } |
| 2762 | 2761 | ||
| 2763 | fn writeSrcNode(self: *Writer, stream: anytype, src_node: i32) !void { | 2762 | fn writeSrcNode(self: *Writer, stream: anytype, src_node: Ast.Node.Offset) !void { |
| 2764 | const tree = self.file.tree orelse return; | 2763 | const tree = self.file.tree orelse return; |
| 2765 | const abs_node = self.relativeToNodeIndex(src_node); | 2764 | const abs_node = src_node.toAbsolute(self.parent_decl_node); |
| 2766 | const src_span = tree.nodeToSpan(abs_node); | 2765 | const src_span = tree.nodeToSpan(abs_node); |
| 2767 | const start = self.line_col_cursor.find(tree.source, src_span.start); | 2766 | const start = self.line_col_cursor.find(tree.source, src_span.start); |
| 2768 | const end = self.line_col_cursor.find(tree.source, src_span.end); | 2767 | const end = self.line_col_cursor.find(tree.source, src_span.end); |
| ... | @@ -2772,10 +2771,10 @@ const Writer = struct { | ... | @@ -2772,10 +2771,10 @@ const Writer = struct { |
| 2772 | }); | 2771 | }); |
| 2773 | } | 2772 | } |
| 2774 | 2773 | ||
| 2775 | fn writeSrcTok(self: *Writer, stream: anytype, src_tok: u32) !void { | 2774 | fn writeSrcTok(self: *Writer, stream: anytype, src_tok: Ast.TokenOffset) !void { |
| 2776 | const tree = self.file.tree orelse return; | 2775 | const tree = self.file.tree orelse return; |
| 2777 | const abs_tok = tree.firstToken(self.parent_decl_node) + src_tok; | 2776 | const abs_tok = src_tok.toAbsolute(tree.firstToken(self.parent_decl_node)); |
| 2778 | const span_start = tree.tokens.items(.start)[abs_tok]; | 2777 | const span_start = tree.tokenStart(abs_tok); |
| 2779 | const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(abs_tok).len)); | 2778 | const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(abs_tok).len)); |
| 2780 | const start = self.line_col_cursor.find(tree.source, span_start); | 2779 | const start = self.line_col_cursor.find(tree.source, span_start); |
| 2781 | const end = self.line_col_cursor.find(tree.source, span_end); | 2780 | const end = self.line_col_cursor.find(tree.source, span_end); |
| ... | @@ -2785,9 +2784,9 @@ const Writer = struct { | ... | @@ -2785,9 +2784,9 @@ const Writer = struct { |
| 2785 | }); | 2784 | }); |
| 2786 | } | 2785 | } |
| 2787 | 2786 | ||
| 2788 | fn writeSrcTokAbs(self: *Writer, stream: anytype, src_tok: u32) !void { | 2787 | fn writeSrcTokAbs(self: *Writer, stream: anytype, src_tok: Ast.TokenIndex) !void { |
| 2789 | const tree = self.file.tree orelse return; | 2788 | const tree = self.file.tree orelse return; |
| 2790 | const span_start = tree.tokens.items(.start)[src_tok]; | 2789 | const span_start = tree.tokenStart(src_tok); |
| 2791 | const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(src_tok).len)); | 2790 | const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(src_tok).len)); |
| 2792 | const start = self.line_col_cursor.find(tree.source, span_start); | 2791 | const start = self.line_col_cursor.find(tree.source, span_start); |
| 2793 | const end = self.line_col_cursor.find(tree.source, span_end); | 2792 | const end = self.line_col_cursor.find(tree.source, span_end); |