| author | |
| committer | |
| log | d0911786c95dfa7a63ec348bb4a9870da12f62e4 |
| tree | c2ee731b2fcb53504dbade8077084bf935197c06 |
| parent | a0401cf3e4aed014abc1189890f4c1c756a12737 |
| parent | 4129f7ff5a03cb3cd85a3ad5e3360098ab8ed796 |
| signature |
improve type safety of std.zig.Ast26 files changed, 5404 insertions(+), 5704 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 = undefined, | ||
| 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+160-253| ... | @@ -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| { |
| ... | @@ -230,64 +221,36 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -230,64 +221,36 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 230 | 221 | ||
| 231 | .block_two, | 222 | .block_two, |
| 232 | .block_two_semicolon, | 223 | .block_two_semicolon, |
| 233 | => { | ||
| 234 | const statements = [2]Ast.Node.Index{ datas[node].lhs, datas[node].rhs }; | ||
| 235 | if (datas[node].lhs == 0) { | ||
| 236 | return walkBlock(w, node, statements[0..0]); | ||
| 237 | } else if (datas[node].rhs == 0) { | ||
| 238 | return walkBlock(w, node, statements[0..1]); | ||
| 239 | } else { | ||
| 240 | return walkBlock(w, node, statements[0..2]); | ||
| 241 | } | ||
| 242 | }, | ||
| 243 | .block, | 224 | .block, |
| 244 | .block_semicolon, | 225 | .block_semicolon, |
| 245 | => { | 226 | => { |
| 246 | const statements = ast.extra_data[datas[node].lhs..datas[node].rhs]; | 227 | var buf: [2]Ast.Node.Index = undefined; |
| 228 | const statements = ast.blockStatements(&buf, node).?; | ||
| 247 | return walkBlock(w, node, statements); | 229 | return walkBlock(w, node, statements); |
| 248 | }, | 230 | }, |
| 249 | 231 | ||
| 250 | .@"errdefer" => { | 232 | .@"errdefer" => { |
| 251 | const expr = datas[node].rhs; | 233 | const expr = ast.nodeData(node).opt_token_and_node[1]; |
| 252 | return walkExpression(w, expr); | 234 | return walkExpression(w, expr); |
| 253 | }, | 235 | }, |
| 254 | 236 | ||
| 255 | .@"defer" => { | 237 | .@"defer", |
| 256 | const expr = datas[node].rhs; | 238 | .@"comptime", |
| 257 | return walkExpression(w, expr); | 239 | .@"nosuspend", |
| 258 | }, | 240 | .@"suspend", |
| 259 | .@"comptime", .@"nosuspend" => { | 241 | => { |
| 260 | const block = datas[node].lhs; | 242 | return walkExpression(w, ast.nodeData(node).node); |
| 261 | return walkExpression(w, block); | ||
| 262 | }, | ||
| 263 | |||
| 264 | .@"suspend" => { | ||
| 265 | const body = datas[node].lhs; | ||
| 266 | return walkExpression(w, body); | ||
| 267 | }, | ||
| 268 | |||
| 269 | .@"catch" => { | ||
| 270 | try walkExpression(w, datas[node].lhs); // target | ||
| 271 | try walkExpression(w, datas[node].rhs); // fallback | ||
| 272 | }, | 243 | }, |
| 273 | 244 | ||
| 274 | .field_access => { | 245 | .field_access => { |
| 275 | const field_access = datas[node]; | 246 | try walkExpression(w, ast.nodeData(node).node_and_token[0]); |
| 276 | try walkExpression(w, field_access.lhs); | ||
| 277 | }, | 247 | }, |
| 278 | 248 | ||
| 279 | .error_union, | ||
| 280 | .switch_range, | ||
| 281 | => { | ||
| 282 | const infix = datas[node]; | ||
| 283 | try walkExpression(w, infix.lhs); | ||
| 284 | return walkExpression(w, infix.rhs); | ||
| 285 | }, | ||
| 286 | .for_range => { | 249 | .for_range => { |
| 287 | const infix = datas[node]; | 250 | const start, const opt_end = ast.nodeData(node).node_and_opt_node; |
| 288 | try walkExpression(w, infix.lhs); | 251 | try walkExpression(w, start); |
| 289 | if (infix.rhs != 0) { | 252 | if (opt_end.unwrap()) |end| { |
| 290 | return walkExpression(w, infix.rhs); | 253 | return walkExpression(w, end); |
| 291 | } | 254 | } |
| 292 | }, | 255 | }, |
| 293 | 256 | ||
| ... | @@ -337,17 +300,21 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -337,17 +300,21 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 337 | .sub, | 300 | .sub, |
| 338 | .sub_wrap, | 301 | .sub_wrap, |
| 339 | .sub_sat, | 302 | .sub_sat, |
| 303 | .@"catch", | ||
| 304 | .error_union, | ||
| 305 | .switch_range, | ||
| 340 | .@"orelse", | 306 | .@"orelse", |
| 307 | .array_access, | ||
| 341 | => { | 308 | => { |
| 342 | const infix = datas[node]; | 309 | const lhs, const rhs = ast.nodeData(node).node_and_node; |
| 343 | try walkExpression(w, infix.lhs); | 310 | try walkExpression(w, lhs); |
| 344 | try walkExpression(w, infix.rhs); | 311 | try walkExpression(w, rhs); |
| 345 | }, | 312 | }, |
| 346 | 313 | ||
| 347 | .assign_destructure => { | 314 | .assign_destructure => { |
| 348 | const full = ast.assignDestructure(node); | 315 | const full = ast.assignDestructure(node); |
| 349 | for (full.ast.variables) |variable_node| { | 316 | for (full.ast.variables) |variable_node| { |
| 350 | switch (node_tags[variable_node]) { | 317 | switch (ast.nodeTag(variable_node)) { |
| 351 | .global_var_decl, | 318 | .global_var_decl, |
| 352 | .local_var_decl, | 319 | .local_var_decl, |
| 353 | .simple_var_decl, | 320 | .simple_var_decl, |
| ... | @@ -366,15 +333,12 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -366,15 +333,12 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 366 | .negation_wrap, | 333 | .negation_wrap, |
| 367 | .optional_type, | 334 | .optional_type, |
| 368 | .address_of, | 335 | .address_of, |
| 369 | => { | ||
| 370 | return walkExpression(w, datas[node].lhs); | ||
| 371 | }, | ||
| 372 | |||
| 373 | .@"try", | 336 | .@"try", |
| 374 | .@"resume", | 337 | .@"resume", |
| 375 | .@"await", | 338 | .@"await", |
| 339 | .deref, | ||
| 376 | => { | 340 | => { |
| 377 | return walkExpression(w, datas[node].lhs); | 341 | return walkExpression(w, ast.nodeData(node).node); |
| 378 | }, | 342 | }, |
| 379 | 343 | ||
| 380 | .array_type, | 344 | .array_type, |
| ... | @@ -426,51 +390,40 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -426,51 +390,40 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 426 | return walkCall(w, ast.fullCall(&buf, node).?); | 390 | return walkCall(w, ast.fullCall(&buf, node).?); |
| 427 | }, | 391 | }, |
| 428 | 392 | ||
| 429 | .array_access => { | ||
| 430 | const suffix = datas[node]; | ||
| 431 | try walkExpression(w, suffix.lhs); | ||
| 432 | try walkExpression(w, suffix.rhs); | ||
| 433 | }, | ||
| 434 | |||
| 435 | .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).?), |
| 436 | 394 | ||
| 437 | .deref => { | ||
| 438 | try walkExpression(w, datas[node].lhs); | ||
| 439 | }, | ||
| 440 | |||
| 441 | .unwrap_optional => { | 395 | .unwrap_optional => { |
| 442 | try walkExpression(w, datas[node].lhs); | 396 | try walkExpression(w, ast.nodeData(node).node_and_token[0]); |
| 443 | }, | 397 | }, |
| 444 | 398 | ||
| 445 | .@"break" => { | 399 | .@"break" => { |
| 446 | const label_token = datas[node].lhs; | 400 | const label_token, const target = ast.nodeData(node).opt_token_and_opt_node; |
| 447 | const target = datas[node].rhs; | 401 | if (label_token == .none and target == .none) { |
| 448 | if (label_token == 0 and target == 0) { | ||
| 449 | // no expressions | 402 | // no expressions |
| 450 | } else if (label_token == 0 and target != 0) { | 403 | } else if (label_token == .none and target != .none) { |
| 451 | try walkExpression(w, target); | 404 | try walkExpression(w, target.unwrap().?); |
| 452 | } else if (label_token != 0 and target == 0) { | 405 | } else if (label_token != .none and target == .none) { |
| 453 | try walkIdentifier(w, label_token); | 406 | try walkIdentifier(w, label_token.unwrap().?); |
| 454 | } else if (label_token != 0 and target != 0) { | 407 | } else if (label_token != .none and target != .none) { |
| 455 | try walkExpression(w, target); | 408 | try walkExpression(w, target.unwrap().?); |
| 456 | } | 409 | } |
| 457 | }, | 410 | }, |
| 458 | 411 | ||
| 459 | .@"continue" => { | 412 | .@"continue" => { |
| 460 | const label = datas[node].lhs; | 413 | const opt_label = ast.nodeData(node).opt_token_and_opt_node[0]; |
| 461 | if (label != 0) { | 414 | if (opt_label.unwrap()) |label| { |
| 462 | return walkIdentifier(w, label); // label | 415 | return walkIdentifier(w, label); |
| 463 | } | 416 | } |
| 464 | }, | 417 | }, |
| 465 | 418 | ||
| 466 | .@"return" => { | 419 | .@"return" => { |
| 467 | if (datas[node].lhs != 0) { | 420 | if (ast.nodeData(node).opt_node.unwrap()) |lhs| { |
| 468 | try walkExpression(w, datas[node].lhs); | 421 | try walkExpression(w, lhs); |
| 469 | } | 422 | } |
| 470 | }, | 423 | }, |
| 471 | 424 | ||
| 472 | .grouped_expression => { | 425 | .grouped_expression => { |
| 473 | try walkExpression(w, datas[node].lhs); | 426 | try walkExpression(w, ast.nodeData(node).node_and_token[0]); |
| 474 | }, | 427 | }, |
| 475 | 428 | ||
| 476 | .container_decl, | 429 | .container_decl, |
| ... | @@ -491,13 +444,11 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -491,13 +444,11 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 491 | }, | 444 | }, |
| 492 | 445 | ||
| 493 | .error_set_decl => { | 446 | .error_set_decl => { |
| 494 | const error_token = main_tokens[node]; | 447 | const lbrace, const rbrace = ast.nodeData(node).token_and_token; |
| 495 | const lbrace = error_token + 1; | ||
| 496 | const rbrace = datas[node].rhs; | ||
| 497 | 448 | ||
| 498 | var i = lbrace + 1; | 449 | var i = lbrace + 1; |
| 499 | while (i < rbrace) : (i += 1) { | 450 | while (i < rbrace) : (i += 1) { |
| 500 | switch (token_tags[i]) { | 451 | switch (ast.tokenTag(i)) { |
| 501 | .doc_comment => unreachable, // TODO | 452 | .doc_comment => unreachable, // TODO |
| 502 | .identifier => try walkIdentifier(w, i), | 453 | .identifier => try walkIdentifier(w, i), |
| 503 | .comma => {}, | 454 | .comma => {}, |
| ... | @@ -506,17 +457,13 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -506,17 +457,13 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 506 | } | 457 | } |
| 507 | }, | 458 | }, |
| 508 | 459 | ||
| 509 | .builtin_call_two, .builtin_call_two_comma => { | 460 | .builtin_call_two, |
| 510 | if (datas[node].lhs == 0) { | 461 | .builtin_call_two_comma, |
| 511 | return walkBuiltinCall(w, node, &.{}); | 462 | .builtin_call, |
| 512 | } else if (datas[node].rhs == 0) { | 463 | .builtin_call_comma, |
| 513 | return walkBuiltinCall(w, node, &.{datas[node].lhs}); | 464 | => { |
| 514 | } else { | 465 | var buf: [2]Ast.Node.Index = undefined; |
| 515 | return walkBuiltinCall(w, node, &.{ datas[node].lhs, datas[node].rhs }); | 466 | const params = ast.builtinCallParams(&buf, node).?; |
| 516 | } | ||
| 517 | }, | ||
| 518 | .builtin_call, .builtin_call_comma => { | ||
| 519 | const params = ast.extra_data[datas[node].lhs..datas[node].rhs]; | ||
| 520 | return walkBuiltinCall(w, node, params); | 467 | return walkBuiltinCall(w, node, params); |
| 521 | }, | 468 | }, |
| 522 | 469 | ||
| ... | @@ -530,20 +477,16 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -530,20 +477,16 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 530 | }, | 477 | }, |
| 531 | 478 | ||
| 532 | .anyframe_type => { | 479 | .anyframe_type => { |
| 533 | if (datas[node].rhs != 0) { | 480 | _, const child_type = ast.nodeData(node).token_and_node; |
| 534 | return walkExpression(w, datas[node].rhs); | 481 | return walkExpression(w, child_type); |
| 535 | } | ||
| 536 | }, | 482 | }, |
| 537 | 483 | ||
| 538 | .@"switch", | 484 | .@"switch", |
| 539 | .switch_comma, | 485 | .switch_comma, |
| 540 | => { | 486 | => { |
| 541 | const condition = datas[node].lhs; | 487 | const full = ast.fullSwitch(node).?; |
| 542 | const extra = ast.extraData(datas[node].rhs, Ast.Node.SubRange); | 488 | try walkExpression(w, full.ast.condition); // condition expression |
| 543 | const cases = ast.extra_data[extra.start..extra.end]; | 489 | try walkExpressions(w, full.ast.cases); |
| 544 | |||
| 545 | try walkExpression(w, condition); // condition expression | ||
| 546 | try walkExpressions(w, cases); | ||
| 547 | }, | 490 | }, |
| 548 | 491 | ||
| 549 | .switch_case_one, | 492 | .switch_case_one, |
| ... | @@ -570,7 +513,7 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -570,7 +513,7 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 570 | => return walkAsm(w, ast.fullAsm(node).?), | 513 | => return walkAsm(w, ast.fullAsm(node).?), |
| 571 | 514 | ||
| 572 | .enum_literal => { | 515 | .enum_literal => { |
| 573 | return walkIdentifier(w, main_tokens[node]); // name | 516 | return walkIdentifier(w, ast.nodeMainToken(node)); // name |
| 574 | }, | 517 | }, |
| 575 | 518 | ||
| 576 | .fn_decl => unreachable, | 519 | .fn_decl => unreachable, |
| ... | @@ -592,66 +535,66 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { | ... | @@ -592,66 +535,66 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void { |
| 592 | fn walkGlobalVarDecl(w: *Walk, decl_node: Ast.Node.Index, var_decl: Ast.full.VarDecl) Error!void { | 535 | fn walkGlobalVarDecl(w: *Walk, decl_node: Ast.Node.Index, var_decl: Ast.full.VarDecl) Error!void { |
| 593 | _ = decl_node; | 536 | _ = decl_node; |
| 594 | 537 | ||
| 595 | if (var_decl.ast.type_node != 0) { | 538 | if (var_decl.ast.type_node.unwrap()) |type_node| { |
| 596 | try walkExpression(w, var_decl.ast.type_node); | 539 | try walkExpression(w, type_node); |
| 597 | } | 540 | } |
| 598 | 541 | ||
| 599 | if (var_decl.ast.align_node != 0) { | 542 | if (var_decl.ast.align_node.unwrap()) |align_node| { |
| 600 | try walkExpression(w, var_decl.ast.align_node); | 543 | try walkExpression(w, align_node); |
| 601 | } | 544 | } |
| 602 | 545 | ||
| 603 | if (var_decl.ast.addrspace_node != 0) { | 546 | if (var_decl.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 604 | try walkExpression(w, var_decl.ast.addrspace_node); | 547 | try walkExpression(w, addrspace_node); |
| 605 | } | 548 | } |
| 606 | 549 | ||
| 607 | if (var_decl.ast.section_node != 0) { | 550 | if (var_decl.ast.section_node.unwrap()) |section_node| { |
| 608 | try walkExpression(w, var_decl.ast.section_node); | 551 | try walkExpression(w, section_node); |
| 609 | } | 552 | } |
| 610 | 553 | ||
| 611 | if (var_decl.ast.init_node != 0) { | 554 | if (var_decl.ast.init_node.unwrap()) |init_node| { |
| 612 | if (!isUndefinedIdent(w.ast, var_decl.ast.init_node)) { | 555 | if (!isUndefinedIdent(w.ast, init_node)) { |
| 613 | try w.transformations.append(.{ .replace_with_undef = var_decl.ast.init_node }); | 556 | try w.transformations.append(.{ .replace_with_undef = init_node }); |
| 614 | } | 557 | } |
| 615 | try walkExpression(w, var_decl.ast.init_node); | 558 | try walkExpression(w, init_node); |
| 616 | } | 559 | } |
| 617 | } | 560 | } |
| 618 | 561 | ||
| 619 | fn walkLocalVarDecl(w: *Walk, var_decl: Ast.full.VarDecl) Error!void { | 562 | fn walkLocalVarDecl(w: *Walk, var_decl: Ast.full.VarDecl) Error!void { |
| 620 | try walkIdentifierNew(w, var_decl.ast.mut_token + 1); // name | 563 | try walkIdentifierNew(w, var_decl.ast.mut_token + 1); // name |
| 621 | 564 | ||
| 622 | if (var_decl.ast.type_node != 0) { | 565 | if (var_decl.ast.type_node.unwrap()) |type_node| { |
| 623 | try walkExpression(w, var_decl.ast.type_node); | 566 | try walkExpression(w, type_node); |
| 624 | } | 567 | } |
| 625 | 568 | ||
| 626 | if (var_decl.ast.align_node != 0) { | 569 | if (var_decl.ast.align_node.unwrap()) |align_node| { |
| 627 | try walkExpression(w, var_decl.ast.align_node); | 570 | try walkExpression(w, align_node); |
| 628 | } | 571 | } |
| 629 | 572 | ||
| 630 | if (var_decl.ast.addrspace_node != 0) { | 573 | if (var_decl.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 631 | try walkExpression(w, var_decl.ast.addrspace_node); | 574 | try walkExpression(w, addrspace_node); |
| 632 | } | 575 | } |
| 633 | 576 | ||
| 634 | if (var_decl.ast.section_node != 0) { | 577 | if (var_decl.ast.section_node.unwrap()) |section_node| { |
| 635 | try walkExpression(w, var_decl.ast.section_node); | 578 | try walkExpression(w, section_node); |
| 636 | } | 579 | } |
| 637 | 580 | ||
| 638 | if (var_decl.ast.init_node != 0) { | 581 | if (var_decl.ast.init_node.unwrap()) |init_node| { |
| 639 | if (!isUndefinedIdent(w.ast, var_decl.ast.init_node)) { | 582 | if (!isUndefinedIdent(w.ast, init_node)) { |
| 640 | try w.transformations.append(.{ .replace_with_undef = var_decl.ast.init_node }); | 583 | try w.transformations.append(.{ .replace_with_undef = init_node }); |
| 641 | } | 584 | } |
| 642 | try walkExpression(w, var_decl.ast.init_node); | 585 | try walkExpression(w, init_node); |
| 643 | } | 586 | } |
| 644 | } | 587 | } |
| 645 | 588 | ||
| 646 | fn walkContainerField(w: *Walk, field: Ast.full.ContainerField) Error!void { | 589 | fn walkContainerField(w: *Walk, field: Ast.full.ContainerField) Error!void { |
| 647 | if (field.ast.type_expr != 0) { | 590 | if (field.ast.type_expr.unwrap()) |type_expr| { |
| 648 | try walkExpression(w, field.ast.type_expr); // type | 591 | try walkExpression(w, type_expr); // type |
| 649 | } | 592 | } |
| 650 | if (field.ast.align_expr != 0) { | 593 | if (field.ast.align_expr.unwrap()) |align_expr| { |
| 651 | try walkExpression(w, field.ast.align_expr); // alignment | 594 | try walkExpression(w, align_expr); // alignment |
| 652 | } | 595 | } |
| 653 | if (field.ast.value_expr != 0) { | 596 | if (field.ast.value_expr.unwrap()) |value_expr| { |
| 654 | try walkExpression(w, field.ast.value_expr); // value | 597 | try walkExpression(w, value_expr); // value |
| 655 | } | 598 | } |
| 656 | } | 599 | } |
| 657 | 600 | ||
| ... | @@ -662,18 +605,17 @@ fn walkBlock( | ... | @@ -662,18 +605,17 @@ fn walkBlock( |
| 662 | ) Error!void { | 605 | ) Error!void { |
| 663 | _ = block_node; | 606 | _ = block_node; |
| 664 | const ast = w.ast; | 607 | const ast = w.ast; |
| 665 | const node_tags = ast.nodes.items(.tag); | ||
| 666 | 608 | ||
| 667 | for (statements) |stmt| { | 609 | for (statements) |stmt| { |
| 668 | switch (node_tags[stmt]) { | 610 | switch (ast.nodeTag(stmt)) { |
| 669 | .global_var_decl, | 611 | .global_var_decl, |
| 670 | .local_var_decl, | 612 | .local_var_decl, |
| 671 | .simple_var_decl, | 613 | .simple_var_decl, |
| 672 | .aligned_var_decl, | 614 | .aligned_var_decl, |
| 673 | => { | 615 | => { |
| 674 | const var_decl = ast.fullVarDecl(stmt).?; | 616 | const var_decl = ast.fullVarDecl(stmt).?; |
| 675 | if (var_decl.ast.init_node != 0 and | 617 | if (var_decl.ast.init_node != .none and |
| 676 | isUndefinedIdent(w.ast, var_decl.ast.init_node)) | 618 | isUndefinedIdent(w.ast, var_decl.ast.init_node.unwrap().?)) |
| 677 | { | 619 | { |
| 678 | try w.transformations.append(.{ .delete_var_decl = .{ | 620 | try w.transformations.append(.{ .delete_var_decl = .{ |
| 679 | .var_decl_node = stmt, | 621 | .var_decl_node = stmt, |
| ... | @@ -704,15 +646,15 @@ fn walkBlock( | ... | @@ -704,15 +646,15 @@ fn walkBlock( |
| 704 | 646 | ||
| 705 | fn walkArrayType(w: *Walk, array_type: Ast.full.ArrayType) Error!void { | 647 | fn walkArrayType(w: *Walk, array_type: Ast.full.ArrayType) Error!void { |
| 706 | try walkExpression(w, array_type.ast.elem_count); | 648 | try walkExpression(w, array_type.ast.elem_count); |
| 707 | if (array_type.ast.sentinel != 0) { | 649 | if (array_type.ast.sentinel.unwrap()) |sentinel| { |
| 708 | try walkExpression(w, array_type.ast.sentinel); | 650 | try walkExpression(w, sentinel); |
| 709 | } | 651 | } |
| 710 | return walkExpression(w, array_type.ast.elem_type); | 652 | return walkExpression(w, array_type.ast.elem_type); |
| 711 | } | 653 | } |
| 712 | 654 | ||
| 713 | fn walkArrayInit(w: *Walk, array_init: Ast.full.ArrayInit) Error!void { | 655 | fn walkArrayInit(w: *Walk, array_init: Ast.full.ArrayInit) Error!void { |
| 714 | if (array_init.ast.type_expr != 0) { | 656 | if (array_init.ast.type_expr.unwrap()) |type_expr| { |
| 715 | try walkExpression(w, array_init.ast.type_expr); // T | 657 | try walkExpression(w, type_expr); // T |
| 716 | } | 658 | } |
| 717 | for (array_init.ast.elements) |elem_init| { | 659 | for (array_init.ast.elements) |elem_init| { |
| 718 | try walkExpression(w, elem_init); | 660 | try walkExpression(w, elem_init); |
| ... | @@ -725,8 +667,8 @@ fn walkStructInit( | ... | @@ -725,8 +667,8 @@ fn walkStructInit( |
| 725 | struct_init: Ast.full.StructInit, | 667 | struct_init: Ast.full.StructInit, |
| 726 | ) Error!void { | 668 | ) Error!void { |
| 727 | _ = struct_node; | 669 | _ = struct_node; |
| 728 | if (struct_init.ast.type_expr != 0) { | 670 | if (struct_init.ast.type_expr.unwrap()) |type_expr| { |
| 729 | try walkExpression(w, struct_init.ast.type_expr); // T | 671 | try walkExpression(w, type_expr); // T |
| 730 | } | 672 | } |
| 731 | for (struct_init.ast.fields) |field_init| { | 673 | for (struct_init.ast.fields) |field_init| { |
| 732 | try walkExpression(w, field_init); | 674 | try walkExpression(w, field_init); |
| ... | @@ -746,18 +688,17 @@ fn walkSlice( | ... | @@ -746,18 +688,17 @@ fn walkSlice( |
| 746 | _ = slice_node; | 688 | _ = slice_node; |
| 747 | try walkExpression(w, slice.ast.sliced); | 689 | try walkExpression(w, slice.ast.sliced); |
| 748 | try walkExpression(w, slice.ast.start); | 690 | try walkExpression(w, slice.ast.start); |
| 749 | if (slice.ast.end != 0) { | 691 | if (slice.ast.end.unwrap()) |end| { |
| 750 | try walkExpression(w, slice.ast.end); | 692 | try walkExpression(w, end); |
| 751 | } | 693 | } |
| 752 | if (slice.ast.sentinel != 0) { | 694 | if (slice.ast.sentinel.unwrap()) |sentinel| { |
| 753 | try walkExpression(w, slice.ast.sentinel); | 695 | try walkExpression(w, sentinel); |
| 754 | } | 696 | } |
| 755 | } | 697 | } |
| 756 | 698 | ||
| 757 | fn walkIdentifier(w: *Walk, name_ident: Ast.TokenIndex) Error!void { | 699 | fn walkIdentifier(w: *Walk, name_ident: Ast.TokenIndex) Error!void { |
| 758 | const ast = w.ast; | 700 | const ast = w.ast; |
| 759 | const token_tags = ast.tokens.items(.tag); | 701 | assert(ast.tokenTag(name_ident) == .identifier); |
| 760 | assert(token_tags[name_ident] == .identifier); | ||
| 761 | const name_bytes = ast.tokenSlice(name_ident); | 702 | const name_bytes = ast.tokenSlice(name_ident); |
| 762 | _ = w.unreferenced_globals.swapRemove(name_bytes); | 703 | _ = w.unreferenced_globals.swapRemove(name_bytes); |
| 763 | } | 704 | } |
| ... | @@ -773,8 +714,8 @@ fn walkContainerDecl( | ... | @@ -773,8 +714,8 @@ fn walkContainerDecl( |
| 773 | container_decl: Ast.full.ContainerDecl, | 714 | container_decl: Ast.full.ContainerDecl, |
| 774 | ) Error!void { | 715 | ) Error!void { |
| 775 | _ = container_decl_node; | 716 | _ = container_decl_node; |
| 776 | if (container_decl.ast.arg != 0) { | 717 | if (container_decl.ast.arg.unwrap()) |arg| { |
| 777 | try walkExpression(w, container_decl.ast.arg); | 718 | try walkExpression(w, arg); |
| 778 | } | 719 | } |
| 779 | try walkMembers(w, container_decl.ast.members); | 720 | try walkMembers(w, container_decl.ast.members); |
| 780 | } | 721 | } |
| ... | @@ -785,14 +726,13 @@ fn walkBuiltinCall( | ... | @@ -785,14 +726,13 @@ fn walkBuiltinCall( |
| 785 | params: []const Ast.Node.Index, | 726 | params: []const Ast.Node.Index, |
| 786 | ) Error!void { | 727 | ) Error!void { |
| 787 | const ast = w.ast; | 728 | const ast = w.ast; |
| 788 | const main_tokens = ast.nodes.items(.main_token); | 729 | const builtin_token = ast.nodeMainToken(call_node); |
| 789 | const builtin_token = main_tokens[call_node]; | ||
| 790 | const builtin_name = ast.tokenSlice(builtin_token); | 730 | const builtin_name = ast.tokenSlice(builtin_token); |
| 791 | const info = BuiltinFn.list.get(builtin_name).?; | 731 | const info = BuiltinFn.list.get(builtin_name).?; |
| 792 | switch (info.tag) { | 732 | switch (info.tag) { |
| 793 | .import => { | 733 | .import => { |
| 794 | const operand_node = params[0]; | 734 | const operand_node = params[0]; |
| 795 | const str_lit_token = main_tokens[operand_node]; | 735 | const str_lit_token = ast.nodeMainToken(operand_node); |
| 796 | const token_bytes = ast.tokenSlice(str_lit_token); | 736 | const token_bytes = ast.tokenSlice(str_lit_token); |
| 797 | if (std.mem.endsWith(u8, token_bytes, ".zig\"")) { | 737 | if (std.mem.endsWith(u8, token_bytes, ".zig\"")) { |
| 798 | const imported_string = std.zig.string_literal.parseAlloc(w.arena, token_bytes) catch | 738 | const imported_string = std.zig.string_literal.parseAlloc(w.arena, token_bytes) catch |
| ... | @@ -821,29 +761,30 @@ fn walkFnProto(w: *Walk, fn_proto: Ast.full.FnProto) Error!void { | ... | @@ -821,29 +761,30 @@ fn walkFnProto(w: *Walk, fn_proto: Ast.full.FnProto) Error!void { |
| 821 | { | 761 | { |
| 822 | var it = fn_proto.iterate(ast); | 762 | var it = fn_proto.iterate(ast); |
| 823 | while (it.next()) |param| { | 763 | while (it.next()) |param| { |
| 824 | if (param.type_expr != 0) { | 764 | if (param.type_expr) |type_expr| { |
| 825 | try walkExpression(w, param.type_expr); | 765 | try walkExpression(w, type_expr); |
| 826 | } | 766 | } |
| 827 | } | 767 | } |
| 828 | } | 768 | } |
| 829 | 769 | ||
| 830 | if (fn_proto.ast.align_expr != 0) { | 770 | if (fn_proto.ast.align_expr.unwrap()) |align_expr| { |
| 831 | try walkExpression(w, fn_proto.ast.align_expr); | 771 | try walkExpression(w, align_expr); |
| 832 | } | 772 | } |
| 833 | 773 | ||
| 834 | if (fn_proto.ast.addrspace_expr != 0) { | 774 | if (fn_proto.ast.addrspace_expr.unwrap()) |addrspace_expr| { |
| 835 | try walkExpression(w, fn_proto.ast.addrspace_expr); | 775 | try walkExpression(w, addrspace_expr); |
| 836 | } | 776 | } |
| 837 | 777 | ||
| 838 | if (fn_proto.ast.section_expr != 0) { | 778 | if (fn_proto.ast.section_expr.unwrap()) |section_expr| { |
| 839 | try walkExpression(w, fn_proto.ast.section_expr); | 779 | try walkExpression(w, section_expr); |
| 840 | } | 780 | } |
| 841 | 781 | ||
| 842 | if (fn_proto.ast.callconv_expr != 0) { | 782 | if (fn_proto.ast.callconv_expr.unwrap()) |callconv_expr| { |
| 843 | try walkExpression(w, fn_proto.ast.callconv_expr); | 783 | try walkExpression(w, callconv_expr); |
| 844 | } | 784 | } |
| 845 | 785 | ||
| 846 | try walkExpression(w, fn_proto.ast.return_type); | 786 | const return_type = fn_proto.ast.return_type.unwrap().?; |
| 787 | try walkExpression(w, return_type); | ||
| 847 | } | 788 | } |
| 848 | 789 | ||
| 849 | fn walkExpressions(w: *Walk, expressions: []const Ast.Node.Index) Error!void { | 790 | fn walkExpressions(w: *Walk, expressions: []const Ast.Node.Index) Error!void { |
| ... | @@ -860,16 +801,13 @@ fn walkSwitchCase(w: *Walk, switch_case: Ast.full.SwitchCase) Error!void { | ... | @@ -860,16 +801,13 @@ fn walkSwitchCase(w: *Walk, switch_case: Ast.full.SwitchCase) Error!void { |
| 860 | } | 801 | } |
| 861 | 802 | ||
| 862 | fn walkWhile(w: *Walk, node_index: Ast.Node.Index, while_node: Ast.full.While) Error!void { | 803 | fn walkWhile(w: *Walk, node_index: Ast.Node.Index, while_node: Ast.full.While) Error!void { |
| 863 | assert(while_node.ast.cond_expr != 0); | ||
| 864 | assert(while_node.ast.then_expr != 0); | ||
| 865 | |||
| 866 | // Perform these transformations in this priority order: | 804 | // Perform these transformations in this priority order: |
| 867 | // 1. If the `else` expression is missing or an empty block, replace the condition with `if (true)` if it is not already. | 805 | // 1. If the `else` expression is missing or an empty block, replace the condition with `if (true)` if it is not already. |
| 868 | // 2. If the `then` block is empty, replace the condition with `if (false)` if it is not already. | 806 | // 2. If the `then` block is empty, replace the condition with `if (false)` if it is not already. |
| 869 | // 3. If the condition is `if (true)`, replace the `if` expression with the contents of the `then` expression. | 807 | // 3. If the condition is `if (true)`, replace the `if` expression with the contents of the `then` expression. |
| 870 | // 4. If the condition is `if (false)`, replace the `if` expression with the contents of the `else` expression. | 808 | // 4. If the condition is `if (false)`, replace the `if` expression with the contents of the `else` expression. |
| 871 | if (!isTrueIdent(w.ast, while_node.ast.cond_expr) and | 809 | if (!isTrueIdent(w.ast, while_node.ast.cond_expr) and |
| 872 | (while_node.ast.else_expr == 0 or isEmptyBlock(w.ast, while_node.ast.else_expr))) | 810 | (while_node.ast.else_expr == .none or isEmptyBlock(w.ast, while_node.ast.else_expr.unwrap().?))) |
| 873 | { | 811 | { |
| 874 | try w.transformations.ensureUnusedCapacity(1); | 812 | try w.transformations.ensureUnusedCapacity(1); |
| 875 | w.transformations.appendAssumeCapacity(.{ .replace_with_true = while_node.ast.cond_expr }); | 813 | w.transformations.appendAssumeCapacity(.{ .replace_with_true = while_node.ast.cond_expr }); |
| ... | @@ -886,45 +824,39 @@ fn walkWhile(w: *Walk, node_index: Ast.Node.Index, while_node: Ast.full.While) E | ... | @@ -886,45 +824,39 @@ fn walkWhile(w: *Walk, node_index: Ast.Node.Index, while_node: Ast.full.While) E |
| 886 | try w.transformations.ensureUnusedCapacity(1); | 824 | try w.transformations.ensureUnusedCapacity(1); |
| 887 | w.transformations.appendAssumeCapacity(.{ .replace_node = .{ | 825 | w.transformations.appendAssumeCapacity(.{ .replace_node = .{ |
| 888 | .to_replace = node_index, | 826 | .to_replace = node_index, |
| 889 | .replacement = while_node.ast.else_expr, | 827 | .replacement = while_node.ast.else_expr.unwrap().?, |
| 890 | } }); | 828 | } }); |
| 891 | } | 829 | } |
| 892 | 830 | ||
| 893 | try walkExpression(w, while_node.ast.cond_expr); // condition | 831 | try walkExpression(w, while_node.ast.cond_expr); // condition |
| 894 | 832 | ||
| 895 | if (while_node.ast.cont_expr != 0) { | 833 | if (while_node.ast.cont_expr.unwrap()) |cont_expr| { |
| 896 | try walkExpression(w, while_node.ast.cont_expr); | 834 | try walkExpression(w, cont_expr); |
| 897 | } | 835 | } |
| 898 | 836 | ||
| 899 | if (while_node.ast.then_expr != 0) { | 837 | try walkExpression(w, while_node.ast.then_expr); |
| 900 | try walkExpression(w, while_node.ast.then_expr); | 838 | |
| 901 | } | 839 | if (while_node.ast.else_expr.unwrap()) |else_expr| { |
| 902 | if (while_node.ast.else_expr != 0) { | 840 | try walkExpression(w, else_expr); |
| 903 | try walkExpression(w, while_node.ast.else_expr); | ||
| 904 | } | 841 | } |
| 905 | } | 842 | } |
| 906 | 843 | ||
| 907 | fn walkFor(w: *Walk, for_node: Ast.full.For) Error!void { | 844 | fn walkFor(w: *Walk, for_node: Ast.full.For) Error!void { |
| 908 | try walkParamList(w, for_node.ast.inputs); | 845 | try walkParamList(w, for_node.ast.inputs); |
| 909 | if (for_node.ast.then_expr != 0) { | 846 | try walkExpression(w, for_node.ast.then_expr); |
| 910 | try walkExpression(w, for_node.ast.then_expr); | 847 | if (for_node.ast.else_expr.unwrap()) |else_expr| { |
| 911 | } | 848 | try walkExpression(w, else_expr); |
| 912 | if (for_node.ast.else_expr != 0) { | ||
| 913 | try walkExpression(w, for_node.ast.else_expr); | ||
| 914 | } | 849 | } |
| 915 | } | 850 | } |
| 916 | 851 | ||
| 917 | fn walkIf(w: *Walk, node_index: Ast.Node.Index, if_node: Ast.full.If) Error!void { | 852 | fn walkIf(w: *Walk, node_index: Ast.Node.Index, if_node: Ast.full.If) Error!void { |
| 918 | assert(if_node.ast.cond_expr != 0); | ||
| 919 | assert(if_node.ast.then_expr != 0); | ||
| 920 | |||
| 921 | // Perform these transformations in this priority order: | 853 | // Perform these transformations in this priority order: |
| 922 | // 1. If the `else` expression is missing or an empty block, replace the condition with `if (true)` if it is not already. | 854 | // 1. If the `else` expression is missing or an empty block, replace the condition with `if (true)` if it is not already. |
| 923 | // 2. If the `then` block is empty, replace the condition with `if (false)` if it is not already. | 855 | // 2. If the `then` block is empty, replace the condition with `if (false)` if it is not already. |
| 924 | // 3. If the condition is `if (true)`, replace the `if` expression with the contents of the `then` expression. | 856 | // 3. If the condition is `if (true)`, replace the `if` expression with the contents of the `then` expression. |
| 925 | // 4. If the condition is `if (false)`, replace the `if` expression with the contents of the `else` expression. | 857 | // 4. If the condition is `if (false)`, replace the `if` expression with the contents of the `else` expression. |
| 926 | if (!isTrueIdent(w.ast, if_node.ast.cond_expr) and | 858 | if (!isTrueIdent(w.ast, if_node.ast.cond_expr) and |
| 927 | (if_node.ast.else_expr == 0 or isEmptyBlock(w.ast, if_node.ast.else_expr))) | 859 | (if_node.ast.else_expr == .none or isEmptyBlock(w.ast, if_node.ast.else_expr.unwrap().?))) |
| 928 | { | 860 | { |
| 929 | try w.transformations.ensureUnusedCapacity(1); | 861 | try w.transformations.ensureUnusedCapacity(1); |
| 930 | w.transformations.appendAssumeCapacity(.{ .replace_with_true = if_node.ast.cond_expr }); | 862 | w.transformations.appendAssumeCapacity(.{ .replace_with_true = if_node.ast.cond_expr }); |
| ... | @@ -941,17 +873,14 @@ fn walkIf(w: *Walk, node_index: Ast.Node.Index, if_node: Ast.full.If) Error!void | ... | @@ -941,17 +873,14 @@ fn walkIf(w: *Walk, node_index: Ast.Node.Index, if_node: Ast.full.If) Error!void |
| 941 | try w.transformations.ensureUnusedCapacity(1); | 873 | try w.transformations.ensureUnusedCapacity(1); |
| 942 | w.transformations.appendAssumeCapacity(.{ .replace_node = .{ | 874 | w.transformations.appendAssumeCapacity(.{ .replace_node = .{ |
| 943 | .to_replace = node_index, | 875 | .to_replace = node_index, |
| 944 | .replacement = if_node.ast.else_expr, | 876 | .replacement = if_node.ast.else_expr.unwrap().?, |
| 945 | } }); | 877 | } }); |
| 946 | } | 878 | } |
| 947 | 879 | ||
| 948 | try walkExpression(w, if_node.ast.cond_expr); // condition | 880 | try walkExpression(w, if_node.ast.cond_expr); // condition |
| 949 | 881 | try walkExpression(w, if_node.ast.then_expr); | |
| 950 | if (if_node.ast.then_expr != 0) { | 882 | if (if_node.ast.else_expr.unwrap()) |else_expr| { |
| 951 | try walkExpression(w, if_node.ast.then_expr); | 883 | try walkExpression(w, else_expr); |
| 952 | } | ||
| 953 | if (if_node.ast.else_expr != 0) { | ||
| 954 | try walkExpression(w, if_node.ast.else_expr); | ||
| 955 | } | 884 | } |
| 956 | } | 885 | } |
| 957 | 886 | ||
| ... | @@ -971,25 +900,13 @@ fn walkParamList(w: *Walk, params: []const Ast.Node.Index) Error!void { | ... | @@ -971,25 +900,13 @@ fn walkParamList(w: *Walk, params: []const Ast.Node.Index) Error!void { |
| 971 | /// Check if it is already gutted (i.e. its body replaced with `@trap()`). | 900 | /// Check if it is already gutted (i.e. its body replaced with `@trap()`). |
| 972 | fn isFnBodyGutted(ast: *const Ast, body_node: Ast.Node.Index) bool { | 901 | fn isFnBodyGutted(ast: *const Ast, body_node: Ast.Node.Index) bool { |
| 973 | // skip over discards | 902 | // skip over discards |
| 974 | const node_tags = ast.nodes.items(.tag); | ||
| 975 | const datas = ast.nodes.items(.data); | ||
| 976 | var statements_buf: [2]Ast.Node.Index = undefined; | 903 | var statements_buf: [2]Ast.Node.Index = undefined; |
| 977 | const statements = switch (node_tags[body_node]) { | 904 | const statements = switch (ast.nodeTag(body_node)) { |
| 978 | .block_two, | 905 | .block_two, |
| 979 | .block_two_semicolon, | 906 | .block_two_semicolon, |
| 980 | => blk: { | ||
| 981 | statements_buf[0..2].* = .{ datas[body_node].lhs, datas[body_node].rhs }; | ||
| 982 | break :blk if (datas[body_node].lhs == 0) | ||
| 983 | statements_buf[0..0] | ||
| 984 | else if (datas[body_node].rhs == 0) | ||
| 985 | statements_buf[0..1] | ||
| 986 | else | ||
| 987 | statements_buf[0..2]; | ||
| 988 | }, | ||
| 989 | |||
| 990 | .block, | 907 | .block, |
| 991 | .block_semicolon, | 908 | .block_semicolon, |
| 992 | => ast.extra_data[datas[body_node].lhs..datas[body_node].rhs], | 909 | => ast.blockStatements(&statements_buf, body_node).?, |
| 993 | 910 | ||
| 994 | else => return false, | 911 | else => return false, |
| 995 | }; | 912 | }; |
| ... | @@ -1012,27 +929,20 @@ const StmtCategory = enum { | ... | @@ -1012,27 +929,20 @@ const StmtCategory = enum { |
| 1012 | }; | 929 | }; |
| 1013 | 930 | ||
| 1014 | fn categorizeStmt(ast: *const Ast, stmt: Ast.Node.Index) StmtCategory { | 931 | fn categorizeStmt(ast: *const Ast, stmt: Ast.Node.Index) StmtCategory { |
| 1015 | const node_tags = ast.nodes.items(.tag); | 932 | switch (ast.nodeTag(stmt)) { |
| 1016 | const datas = ast.nodes.items(.data); | 933 | .builtin_call_two, |
| 1017 | const main_tokens = ast.nodes.items(.main_token); | 934 | .builtin_call_two_comma, |
| 1018 | switch (node_tags[stmt]) { | 935 | .builtin_call, |
| 1019 | .builtin_call_two, .builtin_call_two_comma => { | 936 | .builtin_call_comma, |
| 1020 | if (datas[stmt].lhs == 0) { | 937 | => { |
| 1021 | return categorizeBuiltinCall(ast, main_tokens[stmt], &.{}); | 938 | var buf: [2]Ast.Node.Index = undefined; |
| 1022 | } else if (datas[stmt].rhs == 0) { | 939 | const params = ast.builtinCallParams(&buf, stmt).?; |
| 1023 | return categorizeBuiltinCall(ast, main_tokens[stmt], &.{datas[stmt].lhs}); | 940 | return categorizeBuiltinCall(ast, ast.nodeMainToken(stmt), params); |
| 1024 | } else { | ||
| 1025 | return categorizeBuiltinCall(ast, main_tokens[stmt], &.{ datas[stmt].lhs, datas[stmt].rhs }); | ||
| 1026 | } | ||
| 1027 | }, | ||
| 1028 | .builtin_call, .builtin_call_comma => { | ||
| 1029 | const params = ast.extra_data[datas[stmt].lhs..datas[stmt].rhs]; | ||
| 1030 | return categorizeBuiltinCall(ast, main_tokens[stmt], params); | ||
| 1031 | }, | 941 | }, |
| 1032 | .assign => { | 942 | .assign => { |
| 1033 | const infix = datas[stmt]; | 943 | const lhs, const rhs = ast.nodeData(stmt).node_and_node; |
| 1034 | if (isDiscardIdent(ast, infix.lhs) and node_tags[infix.rhs] == .identifier) { | 944 | if (isDiscardIdent(ast, lhs) and ast.nodeTag(rhs) == .identifier) { |
| 1035 | const name_bytes = ast.tokenSlice(main_tokens[infix.rhs]); | 945 | const name_bytes = ast.tokenSlice(ast.nodeMainToken(rhs)); |
| 1036 | if (std.mem.eql(u8, name_bytes, "undefined")) { | 946 | if (std.mem.eql(u8, name_bytes, "undefined")) { |
| 1037 | return .discard_undefined; | 947 | return .discard_undefined; |
| 1038 | } else { | 948 | } else { |
| ... | @@ -1074,11 +984,9 @@ fn isFalseIdent(ast: *const Ast, node: Ast.Node.Index) bool { | ... | @@ -1074,11 +984,9 @@ fn isFalseIdent(ast: *const Ast, node: Ast.Node.Index) bool { |
| 1074 | } | 984 | } |
| 1075 | 985 | ||
| 1076 | fn isMatchingIdent(ast: *const Ast, node: Ast.Node.Index, string: []const u8) bool { | 986 | fn isMatchingIdent(ast: *const Ast, node: Ast.Node.Index, string: []const u8) bool { |
| 1077 | const node_tags = ast.nodes.items(.tag); | 987 | switch (ast.nodeTag(node)) { |
| 1078 | const main_tokens = ast.nodes.items(.main_token); | ||
| 1079 | switch (node_tags[node]) { | ||
| 1080 | .identifier => { | 988 | .identifier => { |
| 1081 | const token_index = main_tokens[node]; | 989 | const token_index = ast.nodeMainToken(node); |
| 1082 | const name_bytes = ast.tokenSlice(token_index); | 990 | const name_bytes = ast.tokenSlice(token_index); |
| 1083 | return std.mem.eql(u8, name_bytes, string); | 991 | return std.mem.eql(u8, name_bytes, string); |
| 1084 | }, | 992 | }, |
| ... | @@ -1087,11 +995,10 @@ fn isMatchingIdent(ast: *const Ast, node: Ast.Node.Index, string: []const u8) bo | ... | @@ -1087,11 +995,10 @@ fn isMatchingIdent(ast: *const Ast, node: Ast.Node.Index, string: []const u8) bo |
| 1087 | } | 995 | } |
| 1088 | 996 | ||
| 1089 | fn isEmptyBlock(ast: *const Ast, node: Ast.Node.Index) bool { | 997 | fn isEmptyBlock(ast: *const Ast, node: Ast.Node.Index) bool { |
| 1090 | const node_tags = ast.nodes.items(.tag); | 998 | switch (ast.nodeTag(node)) { |
| 1091 | const node_data = ast.nodes.items(.data); | ||
| 1092 | switch (node_tags[node]) { | ||
| 1093 | .block_two => { | 999 | .block_two => { |
| 1094 | return node_data[node].lhs == 0 and node_data[node].rhs == 0; | 1000 | const opt_lhs, const opt_rhs = ast.nodeData(node).opt_node_and_opt_node; |
| 1001 | return opt_lhs == .none and opt_rhs == .none; | ||
| 1095 | }, | 1002 | }, |
| 1096 | else => return false, | 1003 | else => return false, |
| 1097 | } | 1004 | } |
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+92-134| ... | @@ -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)) { |
| ... | @@ -232,20 +226,13 @@ pub const File = struct { | ... | @@ -232,20 +226,13 @@ pub const File = struct { |
| 232 | return .{ .global_const = node }; | 226 | return .{ .global_const = node }; |
| 233 | }, | 227 | }, |
| 234 | 228 | ||
| 235 | .builtin_call_two, .builtin_call_two_comma => { | 229 | .builtin_call_two, |
| 236 | if (node_datas[node].lhs == 0) { | 230 | .builtin_call_two_comma, |
| 237 | const params = [_]Ast.Node.Index{}; | 231 | .builtin_call, |
| 238 | return categorize_builtin_call(file_index, node, &params); | 232 | .builtin_call_comma, |
| 239 | } else if (node_datas[node].rhs == 0) { | 233 | => { |
| 240 | const params = [_]Ast.Node.Index{node_datas[node].lhs}; | 234 | var buf: [2]Ast.Node.Index = undefined; |
| 241 | return categorize_builtin_call(file_index, node, &params); | 235 | const params = ast.builtinCallParams(&buf, node).?; |
| 242 | } else { | ||
| 243 | const params = [_]Ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs }; | ||
| 244 | return categorize_builtin_call(file_index, node, &params); | ||
| 245 | } | ||
| 246 | }, | ||
| 247 | .builtin_call, .builtin_call_comma => { | ||
| 248 | const params = ast.extra_data[node_datas[node].lhs..node_datas[node].rhs]; | ||
| 249 | return categorize_builtin_call(file_index, node, params); | 236 | return categorize_builtin_call(file_index, node, params); |
| 250 | }, | 237 | }, |
| 251 | 238 | ||
| ... | @@ -266,9 +253,9 @@ pub const File = struct { | ... | @@ -266,9 +253,9 @@ pub const File = struct { |
| 266 | .@"if", | 253 | .@"if", |
| 267 | => { | 254 | => { |
| 268 | const if_full = ast.fullIf(node).?; | 255 | const if_full = ast.fullIf(node).?; |
| 269 | if (if_full.ast.else_expr != 0) { | 256 | if (if_full.ast.else_expr.unwrap()) |else_expr| { |
| 270 | 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); |
| 271 | const else_cat = categorize_expr_deep(file_index, if_full.ast.else_expr); | 258 | const else_cat = categorize_expr_deep(file_index, else_expr); |
| 272 | if (then_cat == .type_type and else_cat == .type_type) { | 259 | if (then_cat == .type_type and else_cat == .type_type) { |
| 273 | return .type_type; | 260 | return .type_type; |
| 274 | } else if (then_cat == .error_set and else_cat == .error_set) { | 261 | } else if (then_cat == .error_set and else_cat == .error_set) { |
| ... | @@ -327,11 +314,10 @@ pub const File = struct { | ... | @@ -327,11 +314,10 @@ pub const File = struct { |
| 327 | params: []const Ast.Node.Index, | 314 | params: []const Ast.Node.Index, |
| 328 | ) Category { | 315 | ) Category { |
| 329 | const ast = file_index.get_ast(); | 316 | const ast = file_index.get_ast(); |
| 330 | const main_tokens = ast.nodes.items(.main_token); | 317 | const builtin_token = ast.nodeMainToken(node); |
| 331 | const builtin_token = main_tokens[node]; | ||
| 332 | const builtin_name = ast.tokenSlice(builtin_token); | 318 | const builtin_name = ast.tokenSlice(builtin_token); |
| 333 | if (std.mem.eql(u8, builtin_name, "@import")) { | 319 | if (std.mem.eql(u8, builtin_name, "@import")) { |
| 334 | const str_lit_token = main_tokens[params[0]]; | 320 | const str_lit_token = ast.nodeMainToken(params[0]); |
| 335 | const str_bytes = ast.tokenSlice(str_lit_token); | 321 | const str_bytes = ast.tokenSlice(str_lit_token); |
| 336 | 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"); |
| 337 | defer gpa.free(file_path); | 323 | defer gpa.free(file_path); |
| ... | @@ -364,14 +350,12 @@ pub const File = struct { | ... | @@ -364,14 +350,12 @@ pub const File = struct { |
| 364 | 350 | ||
| 365 | 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 { |
| 366 | const ast = file_index.get_ast(); | 352 | const ast = file_index.get_ast(); |
| 367 | const node_datas = ast.nodes.items(.data); | 353 | const full = ast.fullSwitch(node).?; |
| 368 | const extra = ast.extraData(node_datas[node].rhs, Ast.Node.SubRange); | ||
| 369 | const case_nodes = ast.extra_data[extra.start..extra.end]; | ||
| 370 | var all_type_type = true; | 354 | var all_type_type = true; |
| 371 | var all_error_set = true; | 355 | var all_error_set = true; |
| 372 | var any_type = false; | 356 | var any_type = false; |
| 373 | if (case_nodes.len == 0) return .{ .global_const = node }; | 357 | if (full.ast.cases.len == 0) return .{ .global_const = node }; |
| 374 | for (case_nodes) |case_node| { | 358 | for (full.ast.cases) |case_node| { |
| 375 | const case = ast.fullSwitchCase(case_node).?; | 359 | const case = ast.fullSwitchCase(case_node).?; |
| 376 | switch (categorize_expr_deep(file_index, case.ast.target_expr)) { | 360 | switch (categorize_expr_deep(file_index, case.ast.target_expr)) { |
| 377 | .type_type => { | 361 | .type_type => { |
| ... | @@ -417,8 +401,8 @@ pub fn add_file(file_name: []const u8, bytes: []u8) !File.Index { | ... | @@ -417,8 +401,8 @@ pub fn add_file(file_name: []const u8, bytes: []u8) !File.Index { |
| 417 | const scope = try gpa.create(Scope); | 401 | const scope = try gpa.create(Scope); |
| 418 | scope.* = .{ .tag = .top }; | 402 | scope.* = .{ .tag = .top }; |
| 419 | 403 | ||
| 420 | const decl_index = try file_index.add_decl(0, .none); | 404 | const decl_index = try file_index.add_decl(.root, .none); |
| 421 | try struct_decl(&w, scope, decl_index, 0, ast.containerDeclRoot()); | 405 | try struct_decl(&w, scope, decl_index, .root, ast.containerDeclRoot()); |
| 422 | 406 | ||
| 423 | const file = file_index.get(); | 407 | const file = file_index.get(); |
| 424 | shrinkToFit(&file.ident_decls); | 408 | shrinkToFit(&file.ident_decls); |
| ... | @@ -512,13 +496,12 @@ pub const Scope = struct { | ... | @@ -512,13 +496,12 @@ pub const Scope = struct { |
| 512 | } | 496 | } |
| 513 | 497 | ||
| 514 | 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 { |
| 515 | const main_tokens = ast.nodes.items(.main_token); | ||
| 516 | var it: *Scope = start_scope; | 499 | var it: *Scope = start_scope; |
| 517 | while (true) switch (it.tag) { | 500 | while (true) switch (it.tag) { |
| 518 | .top => break, | 501 | .top => break, |
| 519 | .local => { | 502 | .local => { |
| 520 | const local: *Local = @alignCast(@fieldParentPtr("base", it)); | 503 | const local: *Local = @alignCast(@fieldParentPtr("base", it)); |
| 521 | const name_token = main_tokens[local.var_node] + 1; | 504 | const name_token = ast.nodeMainToken(local.var_node) + 1; |
| 522 | const ident_name = ast.tokenSlice(name_token); | 505 | const ident_name = ast.tokenSlice(name_token); |
| 523 | if (std.mem.eql(u8, ident_name, name)) { | 506 | if (std.mem.eql(u8, ident_name, name)) { |
| 524 | return local.var_node; | 507 | return local.var_node; |
| ... | @@ -545,8 +528,6 @@ fn struct_decl( | ... | @@ -545,8 +528,6 @@ fn struct_decl( |
| 545 | container_decl: Ast.full.ContainerDecl, | 528 | container_decl: Ast.full.ContainerDecl, |
| 546 | ) Oom!void { | 529 | ) Oom!void { |
| 547 | const ast = w.file.get_ast(); | 530 | const ast = w.file.get_ast(); |
| 548 | const node_tags = ast.nodes.items(.tag); | ||
| 549 | const node_datas = ast.nodes.items(.data); | ||
| 550 | 531 | ||
| 551 | const namespace = try gpa.create(Scope.Namespace); | 532 | const namespace = try gpa.create(Scope.Namespace); |
| 552 | namespace.* = .{ | 533 | namespace.* = .{ |
| ... | @@ -556,7 +537,7 @@ fn struct_decl( | ... | @@ -556,7 +537,7 @@ fn struct_decl( |
| 556 | try w.file.get().scopes.putNoClobber(gpa, node, &namespace.base); | 537 | try w.file.get().scopes.putNoClobber(gpa, node, &namespace.base); |
| 557 | try w.scanDecls(namespace, container_decl.ast.members); | 538 | try w.scanDecls(namespace, container_decl.ast.members); |
| 558 | 539 | ||
| 559 | for (container_decl.ast.members) |member| switch (node_tags[member]) { | 540 | for (container_decl.ast.members) |member| switch (ast.nodeTag(member)) { |
| 560 | .container_field_init, | 541 | .container_field_init, |
| 561 | .container_field_align, | 542 | .container_field_align, |
| 562 | .container_field, | 543 | .container_field, |
| ... | @@ -576,7 +557,7 @@ fn struct_decl( | ... | @@ -576,7 +557,7 @@ fn struct_decl( |
| 576 | try w.file.get().doctests.put(gpa, member, doctest_node); | 557 | try w.file.get().doctests.put(gpa, member, doctest_node); |
| 577 | } | 558 | } |
| 578 | const decl_index = try w.file.add_decl(member, parent_decl); | 559 | const decl_index = try w.file.add_decl(member, parent_decl); |
| 579 | 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; |
| 580 | try w.fn_decl(&namespace.base, decl_index, body, full); | 561 | try w.fn_decl(&namespace.base, decl_index, body, full); |
| 581 | }, | 562 | }, |
| 582 | 563 | ||
| ... | @@ -591,9 +572,9 @@ fn struct_decl( | ... | @@ -591,9 +572,9 @@ fn struct_decl( |
| 591 | 572 | ||
| 592 | .@"comptime", | 573 | .@"comptime", |
| 593 | .@"usingnamespace", | 574 | .@"usingnamespace", |
| 594 | => try w.expr(&namespace.base, parent_decl, node_datas[member].lhs), | 575 | => try w.expr(&namespace.base, parent_decl, ast.nodeData(member).node), |
| 595 | 576 | ||
| 596 | .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]), |
| 597 | 578 | ||
| 598 | else => unreachable, | 579 | else => unreachable, |
| 599 | }; | 580 | }; |
| ... | @@ -640,13 +621,13 @@ fn fn_decl( | ... | @@ -640,13 +621,13 @@ fn fn_decl( |
| 640 | w: *Walk, | 621 | w: *Walk, |
| 641 | scope: *Scope, | 622 | scope: *Scope, |
| 642 | parent_decl: Decl.Index, | 623 | parent_decl: Decl.Index, |
| 643 | body: Ast.Node.Index, | 624 | body: Ast.Node.OptionalIndex, |
| 644 | full: Ast.full.FnProto, | 625 | full: Ast.full.FnProto, |
| 645 | ) Oom!void { | 626 | ) Oom!void { |
| 646 | for (full.ast.params) |param| { | 627 | for (full.ast.params) |param| { |
| 647 | try expr(w, scope, parent_decl, param); | 628 | try expr(w, scope, parent_decl, param); |
| 648 | } | 629 | } |
| 649 | try expr(w, scope, parent_decl, full.ast.return_type); | 630 | try expr(w, scope, parent_decl, full.ast.return_type.unwrap().?); |
| 650 | try maybe_expr(w, scope, parent_decl, full.ast.align_expr); | 631 | try maybe_expr(w, scope, parent_decl, full.ast.align_expr); |
| 651 | try maybe_expr(w, scope, parent_decl, full.ast.addrspace_expr); | 632 | try maybe_expr(w, scope, parent_decl, full.ast.addrspace_expr); |
| 652 | try maybe_expr(w, scope, parent_decl, full.ast.section_expr); | 633 | try maybe_expr(w, scope, parent_decl, full.ast.section_expr); |
| ... | @@ -654,17 +635,13 @@ fn fn_decl( | ... | @@ -654,17 +635,13 @@ fn fn_decl( |
| 654 | try maybe_expr(w, scope, parent_decl, body); | 635 | try maybe_expr(w, scope, parent_decl, body); |
| 655 | } | 636 | } |
| 656 | 637 | ||
| 657 | 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 { |
| 658 | if (node != 0) return expr(w, scope, parent_decl, node); | 639 | if (node.unwrap()) |n| return expr(w, scope, parent_decl, n); |
| 659 | } | 640 | } |
| 660 | 641 | ||
| 661 | 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 { |
| 662 | assert(node != 0); | ||
| 663 | const ast = w.file.get_ast(); | 643 | const ast = w.file.get_ast(); |
| 664 | const node_tags = ast.nodes.items(.tag); | 644 | switch (ast.nodeTag(node)) { |
| 665 | const node_datas = ast.nodes.items(.data); | ||
| 666 | const main_tokens = ast.nodes.items(.main_token); | ||
| 667 | switch (node_tags[node]) { | ||
| 668 | .root => unreachable, // Top-level declaration. | 645 | .root => unreachable, // Top-level declaration. |
| 669 | .@"usingnamespace" => unreachable, // Top-level declaration. | 646 | .@"usingnamespace" => unreachable, // Top-level declaration. |
| 670 | .test_decl => unreachable, // Top-level declaration. | 647 | .test_decl => unreachable, // Top-level declaration. |
| ... | @@ -745,8 +722,9 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) | ... | @@ -745,8 +722,9 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) |
| 745 | .array_access, | 722 | .array_access, |
| 746 | .switch_range, | 723 | .switch_range, |
| 747 | => { | 724 | => { |
| 748 | try expr(w, scope, parent_decl, node_datas[node].lhs); | 725 | const lhs, const rhs = ast.nodeData(node).node_and_node; |
| 749 | 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); | ||
| 750 | }, | 728 | }, |
| 751 | 729 | ||
| 752 | .assign_destructure => { | 730 | .assign_destructure => { |
| ... | @@ -759,35 +737,33 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) | ... | @@ -759,35 +737,33 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) |
| 759 | .bit_not, | 737 | .bit_not, |
| 760 | .negation, | 738 | .negation, |
| 761 | .negation_wrap, | 739 | .negation_wrap, |
| 762 | .@"return", | ||
| 763 | .deref, | 740 | .deref, |
| 764 | .address_of, | 741 | .address_of, |
| 765 | .optional_type, | 742 | .optional_type, |
| 766 | .unwrap_optional, | ||
| 767 | .grouped_expression, | ||
| 768 | .@"comptime", | 743 | .@"comptime", |
| 769 | .@"nosuspend", | 744 | .@"nosuspend", |
| 770 | .@"suspend", | 745 | .@"suspend", |
| 771 | .@"await", | 746 | .@"await", |
| 772 | .@"resume", | 747 | .@"resume", |
| 773 | .@"try", | 748 | .@"try", |
| 774 | => 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), | ||
| 775 | 754 | ||
| 776 | .anyframe_type, | 755 | .anyframe_type => try expr(w, scope, parent_decl, ast.nodeData(node).token_and_node[1]), |
| 777 | .@"break", | 756 | .@"break" => try maybe_expr(w, scope, parent_decl, ast.nodeData(node).opt_token_and_opt_node[1]), |
| 778 | => try maybe_expr(w, scope, parent_decl, node_datas[node].rhs), | ||
| 779 | 757 | ||
| 780 | .identifier => { | 758 | .identifier => { |
| 781 | const ident_token = main_tokens[node]; | 759 | const ident_token = ast.nodeMainToken(node); |
| 782 | const ident_name = ast.tokenSlice(ident_token); | 760 | const ident_name = ast.tokenSlice(ident_token); |
| 783 | if (scope.lookup(ast, ident_name)) |var_node| { | 761 | if (scope.lookup(ast, ident_name)) |var_node| { |
| 784 | 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); |
| 785 | } | 763 | } |
| 786 | }, | 764 | }, |
| 787 | .field_access => { | 765 | .field_access => { |
| 788 | const object_node = node_datas[node].lhs; | 766 | const object_node, const field_ident = ast.nodeData(node).node_and_token; |
| 789 | const dot_token = main_tokens[node]; | ||
| 790 | const field_ident = dot_token + 1; | ||
| 791 | try w.file.get().token_parents.put(gpa, field_ident, node); | 767 | try w.file.get().token_parents.put(gpa, field_ident, node); |
| 792 | // 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 |
| 793 | // identifier, allowing rendering code to piece together the link. | 769 | // identifier, allowing rendering code to piece together the link. |
| ... | @@ -818,20 +794,13 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) | ... | @@ -818,20 +794,13 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) |
| 818 | try expr(w, scope, parent_decl, full.ast.template); | 794 | try expr(w, scope, parent_decl, full.ast.template); |
| 819 | }, | 795 | }, |
| 820 | 796 | ||
| 821 | .builtin_call_two, .builtin_call_two_comma => { | 797 | .builtin_call_two, |
| 822 | if (node_datas[node].lhs == 0) { | 798 | .builtin_call_two_comma, |
| 823 | const params = [_]Ast.Node.Index{}; | 799 | .builtin_call, |
| 824 | return builtin_call(w, scope, parent_decl, node, &params); | 800 | .builtin_call_comma, |
| 825 | } else if (node_datas[node].rhs == 0) { | 801 | => { |
| 826 | const params = [_]Ast.Node.Index{node_datas[node].lhs}; | 802 | var buf: [2]Ast.Node.Index = undefined; |
| 827 | return builtin_call(w, scope, parent_decl, node, &params); | 803 | const params = ast.builtinCallParams(&buf, node).?; |
| 828 | } else { | ||
| 829 | const params = [_]Ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs }; | ||
| 830 | return builtin_call(w, scope, parent_decl, node, &params); | ||
| 831 | } | ||
| 832 | }, | ||
| 833 | .builtin_call, .builtin_call_comma => { | ||
| 834 | const params = ast.extra_data[node_datas[node].lhs..node_datas[node].rhs]; | ||
| 835 | return builtin_call(w, scope, parent_decl, node, params); | 804 | return builtin_call(w, scope, parent_decl, node, params); |
| 836 | }, | 805 | }, |
| 837 | 806 | ||
| ... | @@ -871,9 +840,10 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) | ... | @@ -871,9 +840,10 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) |
| 871 | .for_simple, .@"for" => { | 840 | .for_simple, .@"for" => { |
| 872 | const full = ast.fullFor(node).?; | 841 | const full = ast.fullFor(node).?; |
| 873 | for (full.ast.inputs) |input| { | 842 | for (full.ast.inputs) |input| { |
| 874 | if (node_tags[input] == .for_range) { | 843 | if (ast.nodeTag(input) == .for_range) { |
| 875 | try expr(w, scope, parent_decl, node_datas[input].lhs); | 844 | const start, const end = ast.nodeData(input).node_and_opt_node; |
| 876 | 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); | ||
| 877 | } else { | 847 | } else { |
| 878 | try expr(w, scope, parent_decl, input); | 848 | try expr(w, scope, parent_decl, input); |
| 879 | } | 849 | } |
| ... | @@ -886,18 +856,13 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) | ... | @@ -886,18 +856,13 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) |
| 886 | .slice_open => return slice(w, scope, parent_decl, ast.sliceOpen(node)), | 856 | .slice_open => return slice(w, scope, parent_decl, ast.sliceOpen(node)), |
| 887 | .slice_sentinel => return slice(w, scope, parent_decl, ast.sliceSentinel(node)), | 857 | .slice_sentinel => return slice(w, scope, parent_decl, ast.sliceSentinel(node)), |
| 888 | 858 | ||
| 889 | .block_two, .block_two_semicolon => { | 859 | .block_two, |
| 890 | const statements = [2]Ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs }; | 860 | .block_two_semicolon, |
| 891 | if (node_datas[node].lhs == 0) { | 861 | .block, |
| 892 | return block(w, scope, parent_decl, statements[0..0]); | 862 | .block_semicolon, |
| 893 | } else if (node_datas[node].rhs == 0) { | 863 | => { |
| 894 | return block(w, scope, parent_decl, statements[0..1]); | 864 | var buf: [2]Ast.Node.Index = undefined; |
| 895 | } else { | 865 | const statements = ast.blockStatements(&buf, node).?; |
| 896 | return block(w, scope, parent_decl, statements[0..2]); | ||
| 897 | } | ||
| 898 | }, | ||
| 899 | .block, .block_semicolon => { | ||
| 900 | const statements = ast.extra_data[node_datas[node].lhs..node_datas[node].rhs]; | ||
| 901 | return block(w, scope, parent_decl, statements); | 866 | return block(w, scope, parent_decl, statements); |
| 902 | }, | 867 | }, |
| 903 | 868 | ||
| ... | @@ -933,17 +898,16 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) | ... | @@ -933,17 +898,16 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) |
| 933 | }, | 898 | }, |
| 934 | 899 | ||
| 935 | .array_type_sentinel => { | 900 | .array_type_sentinel => { |
| 936 | const extra = ast.extraData(node_datas[node].rhs, Ast.Node.ArrayTypeSentinel); | 901 | const len_expr, const extra_index = ast.nodeData(node).node_and_extra; |
| 937 | 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); | ||
| 938 | try expr(w, scope, parent_decl, extra.elem_type); | 904 | try expr(w, scope, parent_decl, extra.elem_type); |
| 939 | try expr(w, scope, parent_decl, extra.sentinel); | 905 | try expr(w, scope, parent_decl, extra.sentinel); |
| 940 | }, | 906 | }, |
| 941 | .@"switch", .switch_comma => { | 907 | .@"switch", .switch_comma => { |
| 942 | const operand_node = node_datas[node].lhs; | 908 | const full = ast.fullSwitch(node).?; |
| 943 | try expr(w, scope, parent_decl, operand_node); | 909 | try expr(w, scope, parent_decl, full.ast.condition); |
| 944 | const extra = ast.extraData(node_datas[node].rhs, Ast.Node.SubRange); | 910 | for (full.ast.cases) |case_node| { |
| 945 | const case_nodes = ast.extra_data[extra.start..extra.end]; | ||
| 946 | for (case_nodes) |case_node| { | ||
| 947 | const case = ast.fullSwitchCase(case_node).?; | 911 | const case = ast.fullSwitchCase(case_node).?; |
| 948 | for (case.ast.values) |value_node| { | 912 | for (case.ast.values) |value_node| { |
| 949 | try expr(w, scope, parent_decl, value_node); | 913 | try expr(w, scope, parent_decl, value_node); |
| ... | @@ -992,7 +956,7 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) | ... | @@ -992,7 +956,7 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index) |
| 992 | .fn_proto, | 956 | .fn_proto, |
| 993 | => { | 957 | => { |
| 994 | var buf: [1]Ast.Node.Index = undefined; | 958 | var buf: [1]Ast.Node.Index = undefined; |
| 995 | 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).?); |
| 996 | }, | 960 | }, |
| 997 | } | 961 | } |
| 998 | } | 962 | } |
| ... | @@ -1012,8 +976,7 @@ fn builtin_call( | ... | @@ -1012,8 +976,7 @@ fn builtin_call( |
| 1012 | params: []const Ast.Node.Index, | 976 | params: []const Ast.Node.Index, |
| 1013 | ) Oom!void { | 977 | ) Oom!void { |
| 1014 | const ast = w.file.get_ast(); | 978 | const ast = w.file.get_ast(); |
| 1015 | const main_tokens = ast.nodes.items(.main_token); | 979 | const builtin_token = ast.nodeMainToken(node); |
| 1016 | const builtin_token = main_tokens[node]; | ||
| 1017 | const builtin_name = ast.tokenSlice(builtin_token); | 980 | const builtin_name = ast.tokenSlice(builtin_token); |
| 1018 | if (std.mem.eql(u8, builtin_name, "@This")) { | 981 | if (std.mem.eql(u8, builtin_name, "@This")) { |
| 1019 | try w.file.get().node_decls.put(gpa, node, scope.getNamespaceDecl()); | 982 | try w.file.get().node_decls.put(gpa, node, scope.getNamespaceDecl()); |
| ... | @@ -1031,13 +994,11 @@ fn block( | ... | @@ -1031,13 +994,11 @@ fn block( |
| 1031 | statements: []const Ast.Node.Index, | 994 | statements: []const Ast.Node.Index, |
| 1032 | ) Oom!void { | 995 | ) Oom!void { |
| 1033 | const ast = w.file.get_ast(); | 996 | const ast = w.file.get_ast(); |
| 1034 | const node_tags = ast.nodes.items(.tag); | ||
| 1035 | const node_datas = ast.nodes.items(.data); | ||
| 1036 | 997 | ||
| 1037 | var scope = parent_scope; | 998 | var scope = parent_scope; |
| 1038 | 999 | ||
| 1039 | for (statements) |node| { | 1000 | for (statements) |node| { |
| 1040 | switch (node_tags[node]) { | 1001 | switch (ast.nodeTag(node)) { |
| 1041 | .global_var_decl, | 1002 | .global_var_decl, |
| 1042 | .local_var_decl, | 1003 | .local_var_decl, |
| 1043 | .simple_var_decl, | 1004 | .simple_var_decl, |
| ... | @@ -1058,11 +1019,10 @@ fn block( | ... | @@ -1058,11 +1019,10 @@ fn block( |
| 1058 | log.debug("walk assign_destructure not implemented yet", .{}); | 1019 | log.debug("walk assign_destructure not implemented yet", .{}); |
| 1059 | }, | 1020 | }, |
| 1060 | 1021 | ||
| 1061 | .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]), |
| 1062 | 1023 | ||
| 1063 | .@"defer", | 1024 | .@"defer" => try expr(w, scope, parent_decl, ast.nodeData(node).node), |
| 1064 | .@"errdefer", | 1025 | .@"errdefer" => try expr(w, scope, parent_decl, ast.nodeData(node).opt_token_and_node[1]), |
| 1065 | => try expr(w, scope, parent_decl, node_datas[node].rhs), | ||
| 1066 | 1026 | ||
| 1067 | else => try expr(w, scope, parent_decl, node), | 1027 | else => try expr(w, scope, parent_decl, node), |
| 1068 | } | 1028 | } |
| ... | @@ -1078,18 +1038,14 @@ fn while_expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, full: Ast.full.W | ... | @@ -1078,18 +1038,14 @@ fn while_expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, full: Ast.full.W |
| 1078 | 1038 | ||
| 1079 | 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 { |
| 1080 | const ast = w.file.get_ast(); | 1040 | const ast = w.file.get_ast(); |
| 1081 | const node_tags = ast.nodes.items(.tag); | ||
| 1082 | const main_tokens = ast.nodes.items(.main_token); | ||
| 1083 | const token_tags = ast.tokens.items(.tag); | ||
| 1084 | const node_datas = ast.nodes.items(.data); | ||
| 1085 | 1041 | ||
| 1086 | for (members) |member_node| { | 1042 | for (members) |member_node| { |
| 1087 | const name_token = switch (node_tags[member_node]) { | 1043 | const name_token = switch (ast.nodeTag(member_node)) { |
| 1088 | .global_var_decl, | 1044 | .global_var_decl, |
| 1089 | .local_var_decl, | 1045 | .local_var_decl, |
| 1090 | .simple_var_decl, | 1046 | .simple_var_decl, |
| 1091 | .aligned_var_decl, | 1047 | .aligned_var_decl, |
| 1092 | => main_tokens[member_node] + 1, | 1048 | => ast.nodeMainToken(member_node) + 1, |
| 1093 | 1049 | ||
| 1094 | .fn_proto_simple, | 1050 | .fn_proto_simple, |
| 1095 | .fn_proto_multi, | 1051 | .fn_proto_multi, |
| ... | @@ -1097,17 +1053,19 @@ fn scanDecls(w: *Walk, namespace: *Scope.Namespace, members: []const Ast.Node.In | ... | @@ -1097,17 +1053,19 @@ fn scanDecls(w: *Walk, namespace: *Scope.Namespace, members: []const Ast.Node.In |
| 1097 | .fn_proto, | 1053 | .fn_proto, |
| 1098 | .fn_decl, | 1054 | .fn_decl, |
| 1099 | => blk: { | 1055 | => blk: { |
| 1100 | const ident = main_tokens[member_node] + 1; | 1056 | const ident = ast.nodeMainToken(member_node) + 1; |
| 1101 | if (token_tags[ident] != .identifier) continue; | 1057 | if (ast.tokenTag(ident) != .identifier) continue; |
| 1102 | break :blk ident; | 1058 | break :blk ident; |
| 1103 | }, | 1059 | }, |
| 1104 | 1060 | ||
| 1105 | .test_decl => { | 1061 | .test_decl => { |
| 1106 | const ident_token = node_datas[member_node].lhs; | 1062 | const opt_ident_token = ast.nodeData(member_node).opt_token_and_node[0]; |
| 1107 | const is_doctest = token_tags[ident_token] == .identifier; | 1063 | if (opt_ident_token.unwrap()) |ident_token| { |
| 1108 | if (is_doctest) { | 1064 | const is_doctest = ast.tokenTag(ident_token) == .identifier; |
| 1109 | const token_bytes = ast.tokenSlice(ident_token); | 1065 | if (is_doctest) { |
| 1110 | 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 | } | ||
| 1111 | } | 1069 | } |
| 1112 | continue; | 1070 | continue; |
| 1113 | }, | 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+1681-1229| ... | @@ -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,15 +886,10 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -797,15 +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_starts = tree.tokens.items(.start); | ||
| 804 | const token_tags = tree.tokens.items(.tag); | ||
| 805 | var n = node; | 889 | var n = node; |
| 806 | var end_offset: TokenIndex = 0; | 890 | var end_offset: u32 = 0; |
| 807 | while (true) switch (tags[n]) { | 891 | while (true) switch (tree.nodeTag(n)) { |
| 808 | .root => return @as(TokenIndex, @intCast(tree.tokens.len - 1)), | 892 | .root => return @intCast(tree.tokens.len - 1), |
| 809 | 893 | ||
| 810 | .@"usingnamespace", | 894 | .@"usingnamespace", |
| 811 | .bool_not, | 895 | .bool_not, |
| ... | @@ -816,14 +900,12 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -816,14 +900,12 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { |
| 816 | .@"try", | 900 | .@"try", |
| 817 | .@"await", | 901 | .@"await", |
| 818 | .optional_type, | 902 | .optional_type, |
| 903 | .@"suspend", | ||
| 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,41 +954,52 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -873,41 +954,52 @@ 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, | 961 | .fn_decl, |
| 882 | .fn_proto_multi, | 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, | ||
| 883 | .ptr_type_aligned, | 972 | .ptr_type_aligned, |
| 884 | .ptr_type_sentinel, | 973 | .ptr_type_sentinel, |
| 974 | => n = tree.nodeData(n).opt_node_and_node[1], | ||
| 975 | |||
| 976 | .assign_destructure, | ||
| 885 | .ptr_type, | 977 | .ptr_type, |
| 886 | .ptr_type_bit_range, | 978 | .ptr_type_bit_range, |
| 887 | .array_type, | ||
| 888 | .switch_case_one, | ||
| 889 | .switch_case_inline_one, | ||
| 890 | .switch_case, | 979 | .switch_case, |
| 891 | .switch_case_inline, | 980 | .switch_case_inline, |
| 892 | .switch_range, | 981 | => n = tree.nodeData(n).extra_and_node[1], |
| 893 | => n = datas[n].rhs, | ||
| 894 | 982 | ||
| 895 | .for_range => if (datas[n].rhs != 0) { | 983 | .fn_proto_simple => n = tree.nodeData(n).opt_node_and_opt_node[1].unwrap().?, |
| 896 | n = datas[n].rhs; | 984 | .fn_proto_multi, |
| 897 | } else { | 985 | .fn_proto_one, |
| 898 | 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 | }; | ||
| 899 | }, | 993 | }, |
| 900 | 994 | ||
| 901 | .field_access, | 995 | .field_access, |
| 902 | .unwrap_optional, | 996 | .unwrap_optional, |
| 903 | .grouped_expression, | ||
| 904 | .multiline_string_literal, | ||
| 905 | .error_set_decl, | ||
| 906 | .asm_simple, | 997 | .asm_simple, |
| 907 | .asm_output, | 998 | => return tree.nodeData(n).node_and_token[1] + end_offset, |
| 908 | .asm_input, | 999 | .grouped_expression, .asm_input => return tree.nodeData(n).node_and_token[1] + end_offset, |
| 909 | .error_value, | 1000 | .multiline_string_literal, .error_set_decl => return tree.nodeData(n).token_and_token[1] + end_offset, |
| 910 | => return datas[n].rhs + end_offset, | 1001 | .asm_output => return tree.nodeData(n).opt_node_and_token[1] + end_offset, |
| 1002 | .error_value => return tree.nodeMainToken(n) + 2 + end_offset, | ||
| 911 | 1003 | ||
| 912 | .anyframe_literal, | 1004 | .anyframe_literal, |
| 913 | .char_literal, | 1005 | .char_literal, |
| ... | @@ -917,82 +1009,88 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -917,82 +1009,88 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { |
| 917 | .deref, | 1009 | .deref, |
| 918 | .enum_literal, | 1010 | .enum_literal, |
| 919 | .string_literal, | 1011 | .string_literal, |
| 920 | => return main_tokens[n] + end_offset, | 1012 | => return tree.nodeMainToken(n) + end_offset, |
| 921 | 1013 | ||
| 922 | .@"return" => if (datas[n].lhs != 0) { | 1014 | .@"return" => { |
| 923 | n = datas[n].lhs; | 1015 | n = tree.nodeData(n).opt_node.unwrap() orelse { |
| 924 | } else { | 1016 | return tree.nodeMainToken(n) + end_offset; |
| 925 | return main_tokens[n] + end_offset; | 1017 | }; |
| 926 | }, | 1018 | }, |
| 927 | 1019 | ||
| 928 | .call, .async_call => { | 1020 | .call, .async_call => { |
| 1021 | _, const extra_index = tree.nodeData(n).node_and_extra; | ||
| 1022 | const params = tree.extraData(extra_index, Node.SubRange); | ||
| 1023 | assert(params.start != params.end); | ||
| 929 | end_offset += 1; // for the rparen | 1024 | end_offset += 1; // for the rparen |
| 930 | const params = tree.extraData(datas[n].rhs, Node.SubRange); | 1025 | n = @enumFromInt(tree.extra_data[@intFromEnum(params.end) - 1]); // last parameter |
| 931 | if (params.end - params.start == 0) { | ||
| 932 | return main_tokens[n] + end_offset; | ||
| 933 | } | ||
| 934 | n = tree.extra_data[params.end - 1]; // last parameter | ||
| 935 | }, | 1026 | }, |
| 936 | .tagged_union_enum_tag => { | 1027 | .tagged_union_enum_tag => { |
| 937 | const members = tree.extraData(datas[n].rhs, Node.SubRange); | 1028 | const arg, const extra_index = tree.nodeData(n).node_and_extra; |
| 938 | if (members.end - members.start == 0) { | 1029 | const members = tree.extraData(extra_index, Node.SubRange); |
| 1030 | if (members.start == members.end) { | ||
| 939 | end_offset += 4; // for the rparen + rparen + lbrace + rbrace | 1031 | end_offset += 4; // for the rparen + rparen + lbrace + rbrace |
| 940 | n = datas[n].lhs; | 1032 | n = arg; |
| 941 | } else { | 1033 | } else { |
| 942 | end_offset += 1; // for the rbrace | 1034 | end_offset += 1; // for the rbrace |
| 943 | n = tree.extra_data[members.end - 1]; // last parameter | 1035 | n = @enumFromInt(tree.extra_data[@intFromEnum(members.end) - 1]); // last parameter |
| 944 | } | 1036 | } |
| 945 | }, | 1037 | }, |
| 946 | .call_comma, | 1038 | .call_comma, |
| 947 | .async_call_comma, | 1039 | .async_call_comma, |
| 948 | .tagged_union_enum_tag_trailing, | 1040 | .tagged_union_enum_tag_trailing, |
| 949 | => { | 1041 | => { |
| 1042 | _, const extra_index = tree.nodeData(n).node_and_extra; | ||
| 1043 | const params = tree.extraData(extra_index, Node.SubRange); | ||
| 1044 | assert(params.start != params.end); | ||
| 950 | end_offset += 2; // for the comma/semicolon + rparen/rbrace | 1045 | end_offset += 2; // for the comma/semicolon + rparen/rbrace |
| 951 | const params = tree.extraData(datas[n].rhs, Node.SubRange); | 1046 | n = @enumFromInt(tree.extra_data[@intFromEnum(params.end) - 1]); // last parameter |
| 952 | assert(params.end > params.start); | ||
| 953 | n = tree.extra_data[params.end - 1]; // last parameter | ||
| 954 | }, | 1047 | }, |
| 955 | .@"switch" => { | 1048 | .@"switch" => { |
| 956 | const cases = tree.extraData(datas[n].rhs, Node.SubRange); | 1049 | const condition, const extra_index = tree.nodeData(n).node_and_extra; |
| 957 | if (cases.end - cases.start == 0) { | 1050 | const cases = tree.extraData(extra_index, Node.SubRange); |
| 1051 | if (cases.start == cases.end) { | ||
| 958 | end_offset += 3; // rparen, lbrace, rbrace | 1052 | end_offset += 3; // rparen, lbrace, rbrace |
| 959 | n = datas[n].lhs; // condition expression | 1053 | n = condition; |
| 960 | } else { | 1054 | } else { |
| 961 | end_offset += 1; // for the rbrace | 1055 | end_offset += 1; // for the rbrace |
| 962 | n = tree.extra_data[cases.end - 1]; // last case | 1056 | n = @enumFromInt(tree.extra_data[@intFromEnum(cases.end) - 1]); // last case |
| 963 | } | 1057 | } |
| 964 | }, | 1058 | }, |
| 965 | .container_decl_arg => { | 1059 | .container_decl_arg => { |
| 966 | const members = tree.extraData(datas[n].rhs, Node.SubRange); | 1060 | const arg, const extra_index = tree.nodeData(n).node_and_extra; |
| 967 | if (members.end - members.start == 0) { | 1061 | const members = tree.extraData(extra_index, Node.SubRange); |
| 1062 | if (members.end == members.start) { | ||
| 968 | end_offset += 3; // for the rparen + lbrace + rbrace | 1063 | end_offset += 3; // for the rparen + lbrace + rbrace |
| 969 | n = datas[n].lhs; | 1064 | n = arg; |
| 970 | } else { | 1065 | } else { |
| 971 | end_offset += 1; // for the rbrace | 1066 | end_offset += 1; // for the rbrace |
| 972 | n = tree.extra_data[members.end - 1]; // last parameter | 1067 | n = @enumFromInt(tree.extra_data[@intFromEnum(members.end) - 1]); // last parameter |
| 973 | } | 1068 | } |
| 974 | }, | 1069 | }, |
| 975 | .@"asm" => { | 1070 | .@"asm" => { |
| 976 | const extra = tree.extraData(datas[n].rhs, Node.Asm); | 1071 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 1072 | const extra = tree.extraData(extra_index, Node.Asm); | ||
| 977 | return extra.rparen + end_offset; | 1073 | return extra.rparen + end_offset; |
| 978 | }, | 1074 | }, |
| 979 | .array_init, | 1075 | .array_init, |
| 980 | .struct_init, | 1076 | .struct_init, |
| 981 | => { | 1077 | => { |
| 982 | const elements = tree.extraData(datas[n].rhs, Node.SubRange); | 1078 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 983 | assert(elements.end - elements.start > 0); | 1079 | const elements = tree.extraData(extra_index, Node.SubRange); |
| 1080 | assert(elements.start != elements.end); | ||
| 984 | end_offset += 1; // for the rbrace | 1081 | end_offset += 1; // for the rbrace |
| 985 | n = tree.extra_data[elements.end - 1]; // last element | 1082 | n = @enumFromInt(tree.extra_data[@intFromEnum(elements.end) - 1]); // last element |
| 986 | }, | 1083 | }, |
| 987 | .array_init_comma, | 1084 | .array_init_comma, |
| 988 | .struct_init_comma, | 1085 | .struct_init_comma, |
| 989 | .container_decl_arg_trailing, | 1086 | .container_decl_arg_trailing, |
| 990 | .switch_comma, | 1087 | .switch_comma, |
| 991 | => { | 1088 | => { |
| 992 | const members = tree.extraData(datas[n].rhs, Node.SubRange); | 1089 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 993 | assert(members.end - members.start > 0); | 1090 | const members = tree.extraData(extra_index, Node.SubRange); |
| 1091 | assert(members.start != members.end); | ||
| 994 | end_offset += 2; // for the comma + rbrace | 1092 | end_offset += 2; // for the comma + rbrace |
| 995 | n = tree.extra_data[members.end - 1]; // last parameter | 1093 | n = @enumFromInt(tree.extra_data[@intFromEnum(members.end) - 1]); // last parameter |
| 996 | }, | 1094 | }, |
| 997 | .array_init_dot, | 1095 | .array_init_dot, |
| 998 | .struct_init_dot, | 1096 | .struct_init_dot, |
| ... | @@ -1001,9 +1099,10 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -1001,9 +1099,10 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { |
| 1001 | .tagged_union, | 1099 | .tagged_union, |
| 1002 | .builtin_call, | 1100 | .builtin_call, |
| 1003 | => { | 1101 | => { |
| 1004 | assert(datas[n].rhs - datas[n].lhs > 0); | 1102 | const range = tree.nodeData(n).extra_range; |
| 1103 | assert(range.start != range.end); | ||
| 1005 | end_offset += 1; // for the rbrace | 1104 | end_offset += 1; // for the rbrace |
| 1006 | n = tree.extra_data[datas[n].rhs - 1]; // last statement | 1105 | n = @enumFromInt(tree.extra_data[@intFromEnum(range.end) - 1]); // last statement |
| 1007 | }, | 1106 | }, |
| 1008 | .array_init_dot_comma, | 1107 | .array_init_dot_comma, |
| 1009 | .struct_init_dot_comma, | 1108 | .struct_init_dot_comma, |
| ... | @@ -1012,20 +1111,21 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -1012,20 +1111,21 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { |
| 1012 | .tagged_union_trailing, | 1111 | .tagged_union_trailing, |
| 1013 | .builtin_call_comma, | 1112 | .builtin_call_comma, |
| 1014 | => { | 1113 | => { |
| 1015 | assert(datas[n].rhs - datas[n].lhs > 0); | 1114 | const range = tree.nodeData(n).extra_range; |
| 1115 | assert(range.start != range.end); | ||
| 1016 | end_offset += 2; // for the comma/semicolon + rbrace/rparen | 1116 | end_offset += 2; // for the comma/semicolon + rbrace/rparen |
| 1017 | n = tree.extra_data[datas[n].rhs - 1]; // last member | 1117 | n = @enumFromInt(tree.extra_data[@intFromEnum(range.end) - 1]); // last member |
| 1018 | }, | 1118 | }, |
| 1019 | .call_one, | 1119 | .call_one, |
| 1020 | .async_call_one, | 1120 | .async_call_one, |
| 1021 | .array_access, | ||
| 1022 | => { | 1121 | => { |
| 1023 | end_offset += 1; // for the rparen/rbracket | 1122 | _, const first_param = tree.nodeData(n).node_and_opt_node; |
| 1024 | if (datas[n].rhs == 0) { | 1123 | end_offset += 1; // for the rparen |
| 1025 | return main_tokens[n] + end_offset; | 1124 | n = first_param.unwrap() orelse { |
| 1026 | } | 1125 | return tree.nodeMainToken(n) + end_offset; |
| 1027 | n = datas[n].rhs; | 1126 | }; |
| 1028 | }, | 1127 | }, |
| 1128 | |||
| 1029 | .array_init_dot_two, | 1129 | .array_init_dot_two, |
| 1030 | .block_two, | 1130 | .block_two, |
| 1031 | .builtin_call_two, | 1131 | .builtin_call_two, |
| ... | @@ -1033,14 +1133,15 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -1033,14 +1133,15 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { |
| 1033 | .container_decl_two, | 1133 | .container_decl_two, |
| 1034 | .tagged_union_two, | 1134 | .tagged_union_two, |
| 1035 | => { | 1135 | => { |
| 1036 | if (datas[n].rhs != 0) { | 1136 | const opt_lhs, const opt_rhs = tree.nodeData(n).opt_node_and_opt_node; |
| 1137 | if (opt_rhs.unwrap()) |rhs| { | ||
| 1037 | end_offset += 1; // for the rparen/rbrace | 1138 | end_offset += 1; // for the rparen/rbrace |
| 1038 | n = datas[n].rhs; | 1139 | n = rhs; |
| 1039 | } else if (datas[n].lhs != 0) { | 1140 | } else if (opt_lhs.unwrap()) |lhs| { |
| 1040 | end_offset += 1; // for the rparen/rbrace | 1141 | end_offset += 1; // for the rparen/rbrace |
| 1041 | n = datas[n].lhs; | 1142 | n = lhs; |
| 1042 | } else { | 1143 | } else { |
| 1043 | switch (tags[n]) { | 1144 | switch (tree.nodeTag(n)) { |
| 1044 | .array_init_dot_two, | 1145 | .array_init_dot_two, |
| 1045 | .block_two, | 1146 | .block_two, |
| 1046 | .struct_init_dot_two, | 1147 | .struct_init_dot_two, |
| ... | @@ -1048,17 +1149,17 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -1048,17 +1149,17 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { |
| 1048 | .builtin_call_two => end_offset += 2, // lparen/lbrace + rparen/rbrace | 1149 | .builtin_call_two => end_offset += 2, // lparen/lbrace + rparen/rbrace |
| 1049 | .container_decl_two => { | 1150 | .container_decl_two => { |
| 1050 | var i: u32 = 2; // lbrace + rbrace | 1151 | var i: u32 = 2; // lbrace + rbrace |
| 1051 | while (token_tags[main_tokens[n] + i] == .container_doc_comment) i += 1; | 1152 | while (tree.tokenTag(tree.nodeMainToken(n) + i) == .container_doc_comment) i += 1; |
| 1052 | end_offset += i; | 1153 | end_offset += i; |
| 1053 | }, | 1154 | }, |
| 1054 | .tagged_union_two => { | 1155 | .tagged_union_two => { |
| 1055 | var i: u32 = 5; // (enum) {} | 1156 | var i: u32 = 5; // (enum) {} |
| 1056 | while (token_tags[main_tokens[n] + i] == .container_doc_comment) i += 1; | 1157 | while (tree.tokenTag(tree.nodeMainToken(n) + i) == .container_doc_comment) i += 1; |
| 1057 | end_offset += i; | 1158 | end_offset += i; |
| 1058 | }, | 1159 | }, |
| 1059 | else => unreachable, | 1160 | else => unreachable, |
| 1060 | } | 1161 | } |
| 1061 | return main_tokens[n] + end_offset; | 1162 | return tree.nodeMainToken(n) + end_offset; |
| 1062 | } | 1163 | } |
| 1063 | }, | 1164 | }, |
| 1064 | .array_init_dot_two_comma, | 1165 | .array_init_dot_two_comma, |
| ... | @@ -1068,459 +1169,345 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { | ... | @@ -1068,459 +1169,345 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex { |
| 1068 | .container_decl_two_trailing, | 1169 | .container_decl_two_trailing, |
| 1069 | .tagged_union_two_trailing, | 1170 | .tagged_union_two_trailing, |
| 1070 | => { | 1171 | => { |
| 1172 | const opt_lhs, const opt_rhs = tree.nodeData(n).opt_node_and_opt_node; | ||
| 1071 | end_offset += 2; // for the comma/semicolon + rbrace/rparen | 1173 | end_offset += 2; // for the comma/semicolon + rbrace/rparen |
| 1072 | if (datas[n].rhs != 0) { | 1174 | if (opt_rhs.unwrap()) |rhs| { |
| 1073 | n = datas[n].rhs; | 1175 | n = rhs; |
| 1074 | } else if (datas[n].lhs != 0) { | 1176 | } else if (opt_lhs.unwrap()) |lhs| { |
| 1075 | n = datas[n].lhs; | 1177 | n = lhs; |
| 1076 | } else { | 1178 | } else { |
| 1077 | unreachable; | 1179 | unreachable; |
| 1078 | } | 1180 | } |
| 1079 | }, | 1181 | }, |
| 1080 | .simple_var_decl => { | 1182 | .simple_var_decl => { |
| 1081 | if (datas[n].rhs != 0) { | 1183 | const type_node, const init_node = tree.nodeData(n).opt_node_and_opt_node; |
| 1082 | n = datas[n].rhs; | 1184 | if (init_node.unwrap()) |rhs| { |
| 1083 | } else if (datas[n].lhs != 0) { | 1185 | n = rhs; |
| 1084 | n = datas[n].lhs; | 1186 | } else if (type_node.unwrap()) |lhs| { |
| 1187 | n = lhs; | ||
| 1085 | } else { | 1188 | } else { |
| 1086 | end_offset += 1; // from mut token to name | 1189 | end_offset += 1; // from mut token to name |
| 1087 | return main_tokens[n] + end_offset; | 1190 | return tree.nodeMainToken(n) + end_offset; |
| 1088 | } | 1191 | } |
| 1089 | }, | 1192 | }, |
| 1090 | .aligned_var_decl => { | 1193 | .aligned_var_decl => { |
| 1091 | if (datas[n].rhs != 0) { | 1194 | const align_node, const init_node = tree.nodeData(n).node_and_opt_node; |
| 1092 | n = datas[n].rhs; | 1195 | if (init_node.unwrap()) |rhs| { |
| 1093 | } else if (datas[n].lhs != 0) { | 1196 | n = rhs; |
| 1094 | end_offset += 1; // for the rparen | ||
| 1095 | n = datas[n].lhs; | ||
| 1096 | } else { | 1197 | } else { |
| 1097 | end_offset += 1; // from mut token to name | 1198 | end_offset += 1; // for the rparen |
| 1098 | return main_tokens[n] + end_offset; | 1199 | n = align_node; |
| 1099 | } | 1200 | } |
| 1100 | }, | 1201 | }, |
| 1101 | .global_var_decl => { | 1202 | .global_var_decl => { |
| 1102 | if (datas[n].rhs != 0) { | 1203 | const extra_index, const init_node = tree.nodeData(n).extra_and_opt_node; |
| 1103 | n = datas[n].rhs; | 1204 | if (init_node.unwrap()) |rhs| { |
| 1205 | n = rhs; | ||
| 1104 | } else { | 1206 | } else { |
| 1105 | const extra = tree.extraData(datas[n].lhs, Node.GlobalVarDecl); | 1207 | const extra = tree.extraData(extra_index, Node.GlobalVarDecl); |
| 1106 | if (extra.section_node != 0) { | 1208 | if (extra.section_node.unwrap()) |section_node| { |
| 1107 | end_offset += 1; // for the rparen | 1209 | end_offset += 1; // for the rparen |
| 1108 | n = extra.section_node; | 1210 | n = section_node; |
| 1109 | } else if (extra.align_node != 0) { | 1211 | } else if (extra.align_node.unwrap()) |align_node| { |
| 1110 | end_offset += 1; // for the rparen | 1212 | end_offset += 1; // for the rparen |
| 1111 | n = extra.align_node; | 1213 | n = align_node; |
| 1112 | } else if (extra.type_node != 0) { | 1214 | } else if (extra.type_node.unwrap()) |type_node| { |
| 1113 | n = extra.type_node; | 1215 | n = type_node; |
| 1114 | } else { | 1216 | } else { |
| 1115 | end_offset += 1; // from mut token to name | 1217 | end_offset += 1; // from mut token to name |
| 1116 | return main_tokens[n] + end_offset; | 1218 | return tree.nodeMainToken(n) + end_offset; |
| 1117 | } | 1219 | } |
| 1118 | } | 1220 | } |
| 1119 | }, | 1221 | }, |
| 1120 | .local_var_decl => { | 1222 | .local_var_decl => { |
| 1121 | if (datas[n].rhs != 0) { | 1223 | const extra_index, const init_node = tree.nodeData(n).extra_and_opt_node; |
| 1122 | n = datas[n].rhs; | 1224 | if (init_node.unwrap()) |rhs| { |
| 1225 | n = rhs; | ||
| 1123 | } else { | 1226 | } else { |
| 1124 | const extra = tree.extraData(datas[n].lhs, Node.LocalVarDecl); | 1227 | const extra = tree.extraData(extra_index, Node.LocalVarDecl); |
| 1125 | if (extra.align_node != 0) { | 1228 | end_offset += 1; // for the rparen |
| 1126 | end_offset += 1; // for the rparen | 1229 | n = extra.align_node; |
| 1127 | n = extra.align_node; | ||
| 1128 | } else if (extra.type_node != 0) { | ||
| 1129 | n = extra.type_node; | ||
| 1130 | } else { | ||
| 1131 | end_offset += 1; // from mut token to name | ||
| 1132 | return main_tokens[n] + end_offset; | ||
| 1133 | } | ||
| 1134 | } | 1230 | } |
| 1135 | }, | 1231 | }, |
| 1136 | .container_field_init => { | 1232 | .container_field_init => { |
| 1137 | if (datas[n].rhs != 0) { | 1233 | const type_expr, const value_expr = tree.nodeData(n).node_and_opt_node; |
| 1138 | n = datas[n].rhs; | 1234 | n = value_expr.unwrap() orelse type_expr; |
| 1139 | } else if (datas[n].lhs != 0) { | ||
| 1140 | n = datas[n].lhs; | ||
| 1141 | } else { | ||
| 1142 | return main_tokens[n] + end_offset; | ||
| 1143 | } | ||
| 1144 | }, | 1235 | }, |
| 1145 | .container_field_align => { | 1236 | |
| 1146 | if (datas[n].rhs != 0) { | 1237 | .array_access, |
| 1147 | end_offset += 1; // for the rparen | 1238 | .array_init_one, |
| 1148 | n = datas[n].rhs; | 1239 | .container_field_align, |
| 1149 | } else if (datas[n].lhs != 0) { | 1240 | => { |
| 1150 | n = datas[n].lhs; | 1241 | _, const rhs = tree.nodeData(n).node_and_node; |
| 1151 | } else { | 1242 | end_offset += 1; // for the rbracket/rbrace/rparen |
| 1152 | return main_tokens[n] + end_offset; | 1243 | n = rhs; |
| 1153 | } | ||
| 1154 | }, | 1244 | }, |
| 1155 | .container_field => { | 1245 | .container_field => { |
| 1156 | const extra = tree.extraData(datas[n].rhs, Node.ContainerField); | 1246 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 1157 | if (extra.value_expr != 0) { | 1247 | const extra = tree.extraData(extra_index, Node.ContainerField); |
| 1158 | n = extra.value_expr; | 1248 | n = extra.value_expr; |
| 1159 | } else if (extra.align_expr != 0) { | ||
| 1160 | end_offset += 1; // for the rparen | ||
| 1161 | n = extra.align_expr; | ||
| 1162 | } else if (datas[n].lhs != 0) { | ||
| 1163 | n = datas[n].lhs; | ||
| 1164 | } else { | ||
| 1165 | return main_tokens[n] + end_offset; | ||
| 1166 | } | ||
| 1167 | }, | 1249 | }, |
| 1168 | 1250 | ||
| 1169 | .array_init_one, | 1251 | .struct_init_one => { |
| 1170 | .struct_init_one, | 1252 | _, const first_field = tree.nodeData(n).node_and_opt_node; |
| 1171 | => { | ||
| 1172 | end_offset += 1; // rbrace | 1253 | end_offset += 1; // rbrace |
| 1173 | if (datas[n].rhs == 0) { | 1254 | n = first_field.unwrap() orelse { |
| 1174 | return main_tokens[n] + end_offset; | 1255 | return tree.nodeMainToken(n) + end_offset; |
| 1175 | } else { | 1256 | }; |
| 1176 | n = datas[n].rhs; | 1257 | }, |
| 1177 | } | 1258 | .slice_open => { |
| 1259 | _, const start_node = tree.nodeData(n).node_and_node; | ||
| 1260 | end_offset += 2; // ellipsis2 + rbracket, or comma + rparen | ||
| 1261 | n = start_node; | ||
| 1262 | }, | ||
| 1263 | .array_init_one_comma => { | ||
| 1264 | _, const first_element = tree.nodeData(n).node_and_node; | ||
| 1265 | end_offset += 2; // comma + rbrace | ||
| 1266 | n = first_element; | ||
| 1178 | }, | 1267 | }, |
| 1179 | .slice_open, | ||
| 1180 | .call_one_comma, | 1268 | .call_one_comma, |
| 1181 | .async_call_one_comma, | 1269 | .async_call_one_comma, |
| 1182 | .array_init_one_comma, | ||
| 1183 | .struct_init_one_comma, | 1270 | .struct_init_one_comma, |
| 1184 | => { | 1271 | => { |
| 1272 | _, const first_field = tree.nodeData(n).node_and_opt_node; | ||
| 1185 | end_offset += 2; // ellipsis2 + rbracket, or comma + rparen | 1273 | end_offset += 2; // ellipsis2 + rbracket, or comma + rparen |
| 1186 | n = datas[n].rhs; | 1274 | n = first_field.unwrap().?; |
| 1187 | assert(n != 0); | ||
| 1188 | }, | 1275 | }, |
| 1189 | .slice => { | 1276 | .slice => { |
| 1190 | const extra = tree.extraData(datas[n].rhs, Node.Slice); | 1277 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 1191 | assert(extra.end != 0); // should have used slice_open | 1278 | const extra = tree.extraData(extra_index, Node.Slice); |
| 1192 | end_offset += 1; // rbracket | 1279 | end_offset += 1; // rbracket |
| 1193 | n = extra.end; | 1280 | n = extra.end; |
| 1194 | }, | 1281 | }, |
| 1195 | .slice_sentinel => { | 1282 | .slice_sentinel => { |
| 1196 | const extra = tree.extraData(datas[n].rhs, Node.SliceSentinel); | 1283 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 1197 | assert(extra.sentinel != 0); // should have used slice | 1284 | const extra = tree.extraData(extra_index, Node.SliceSentinel); |
| 1198 | end_offset += 1; // rbracket | 1285 | end_offset += 1; // rbracket |
| 1199 | n = extra.sentinel; | 1286 | n = extra.sentinel; |
| 1200 | }, | 1287 | }, |
| 1201 | 1288 | ||
| 1202 | .@"continue", .@"break" => { | 1289 | .@"continue", .@"break" => { |
| 1203 | if (datas[n].rhs != 0) { | 1290 | const opt_label, const opt_rhs = tree.nodeData(n).opt_token_and_opt_node; |
| 1204 | n = datas[n].rhs; | 1291 | if (opt_rhs.unwrap()) |rhs| { |
| 1205 | } else if (datas[n].lhs != 0) { | 1292 | n = rhs; |
| 1206 | return datas[n].lhs + end_offset; | 1293 | } else if (opt_label.unwrap()) |lhs| { |
| 1207 | } else { | 1294 | return lhs + end_offset; |
| 1208 | return main_tokens[n] + end_offset; | ||
| 1209 | } | ||
| 1210 | }, | ||
| 1211 | .fn_decl => { | ||
| 1212 | if (datas[n].rhs != 0) { | ||
| 1213 | n = datas[n].rhs; | ||
| 1214 | } else { | 1295 | } else { |
| 1215 | n = datas[n].lhs; | 1296 | return tree.nodeMainToken(n) + end_offset; |
| 1216 | } | 1297 | } |
| 1217 | }, | 1298 | }, |
| 1218 | .fn_proto_one => { | ||
| 1219 | const extra = tree.extraData(datas[n].lhs, Node.FnProtoOne); | ||
| 1220 | // addrspace, linksection, callconv, align can appear in any order, so we | ||
| 1221 | // find the last one here. | ||
| 1222 | var max_node: Node.Index = datas[n].rhs; | ||
| 1223 | var max_start = token_starts[main_tokens[max_node]]; | ||
| 1224 | var max_offset: TokenIndex = 0; | ||
| 1225 | if (extra.align_expr != 0) { | ||
| 1226 | const start = token_starts[main_tokens[extra.align_expr]]; | ||
| 1227 | if (start > max_start) { | ||
| 1228 | max_node = extra.align_expr; | ||
| 1229 | max_start = start; | ||
| 1230 | max_offset = 1; // for the rparen | ||
| 1231 | } | ||
| 1232 | } | ||
| 1233 | if (extra.addrspace_expr != 0) { | ||
| 1234 | const start = token_starts[main_tokens[extra.addrspace_expr]]; | ||
| 1235 | if (start > max_start) { | ||
| 1236 | max_node = extra.addrspace_expr; | ||
| 1237 | max_start = start; | ||
| 1238 | max_offset = 1; // for the rparen | ||
| 1239 | } | ||
| 1240 | } | ||
| 1241 | if (extra.section_expr != 0) { | ||
| 1242 | const start = token_starts[main_tokens[extra.section_expr]]; | ||
| 1243 | if (start > max_start) { | ||
| 1244 | max_node = extra.section_expr; | ||
| 1245 | max_start = start; | ||
| 1246 | max_offset = 1; // for the rparen | ||
| 1247 | } | ||
| 1248 | } | ||
| 1249 | if (extra.callconv_expr != 0) { | ||
| 1250 | const start = token_starts[main_tokens[extra.callconv_expr]]; | ||
| 1251 | if (start > max_start) { | ||
| 1252 | max_node = extra.callconv_expr; | ||
| 1253 | max_start = start; | ||
| 1254 | max_offset = 1; // for the rparen | ||
| 1255 | } | ||
| 1256 | } | ||
| 1257 | n = max_node; | ||
| 1258 | end_offset += max_offset; | ||
| 1259 | }, | ||
| 1260 | .fn_proto => { | ||
| 1261 | const extra = tree.extraData(datas[n].lhs, Node.FnProto); | ||
| 1262 | // addrspace, linksection, callconv, align can appear in any order, so we | ||
| 1263 | // find the last one here. | ||
| 1264 | var max_node: Node.Index = datas[n].rhs; | ||
| 1265 | var max_start = token_starts[main_tokens[max_node]]; | ||
| 1266 | var max_offset: TokenIndex = 0; | ||
| 1267 | if (extra.align_expr != 0) { | ||
| 1268 | const start = token_starts[main_tokens[extra.align_expr]]; | ||
| 1269 | if (start > max_start) { | ||
| 1270 | max_node = extra.align_expr; | ||
| 1271 | max_start = start; | ||
| 1272 | max_offset = 1; // for the rparen | ||
| 1273 | } | ||
| 1274 | } | ||
| 1275 | if (extra.addrspace_expr != 0) { | ||
| 1276 | const start = token_starts[main_tokens[extra.addrspace_expr]]; | ||
| 1277 | if (start > max_start) { | ||
| 1278 | max_node = extra.addrspace_expr; | ||
| 1279 | max_start = start; | ||
| 1280 | max_offset = 1; // for the rparen | ||
| 1281 | } | ||
| 1282 | } | ||
| 1283 | if (extra.section_expr != 0) { | ||
| 1284 | const start = token_starts[main_tokens[extra.section_expr]]; | ||
| 1285 | if (start > max_start) { | ||
| 1286 | max_node = extra.section_expr; | ||
| 1287 | max_start = start; | ||
| 1288 | max_offset = 1; // for the rparen | ||
| 1289 | } | ||
| 1290 | } | ||
| 1291 | if (extra.callconv_expr != 0) { | ||
| 1292 | const start = token_starts[main_tokens[extra.callconv_expr]]; | ||
| 1293 | if (start > max_start) { | ||
| 1294 | max_node = extra.callconv_expr; | ||
| 1295 | max_start = start; | ||
| 1296 | max_offset = 1; // for the rparen | ||
| 1297 | } | ||
| 1298 | } | ||
| 1299 | n = max_node; | ||
| 1300 | end_offset += max_offset; | ||
| 1301 | }, | ||
| 1302 | .while_cont => { | 1299 | .while_cont => { |
| 1303 | const extra = tree.extraData(datas[n].rhs, Node.WhileCont); | 1300 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 1304 | assert(extra.then_expr != 0); | 1301 | const extra = tree.extraData(extra_index, Node.WhileCont); |
| 1305 | n = extra.then_expr; | 1302 | n = extra.then_expr; |
| 1306 | }, | 1303 | }, |
| 1307 | .@"while" => { | 1304 | .@"while" => { |
| 1308 | const extra = tree.extraData(datas[n].rhs, Node.While); | 1305 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 1309 | assert(extra.else_expr != 0); | 1306 | const extra = tree.extraData(extra_index, Node.While); |
| 1310 | n = extra.else_expr; | 1307 | n = extra.else_expr; |
| 1311 | }, | 1308 | }, |
| 1312 | .@"if" => { | 1309 | .@"if" => { |
| 1313 | const extra = tree.extraData(datas[n].rhs, Node.If); | 1310 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 1314 | assert(extra.else_expr != 0); | 1311 | const extra = tree.extraData(extra_index, Node.If); |
| 1315 | n = extra.else_expr; | 1312 | n = extra.else_expr; |
| 1316 | }, | 1313 | }, |
| 1317 | .@"for" => { | 1314 | .@"for" => { |
| 1318 | const extra = @as(Node.For, @bitCast(datas[n].rhs)); | 1315 | const extra_index, const extra = tree.nodeData(n).@"for"; |
| 1319 | n = tree.extra_data[datas[n].lhs + extra.inputs + @intFromBool(extra.has_else)]; | 1316 | const index = @intFromEnum(extra_index) + extra.inputs + @intFromBool(extra.has_else); |
| 1320 | }, | 1317 | n = @enumFromInt(tree.extra_data[index]); |
| 1321 | .@"suspend" => { | ||
| 1322 | if (datas[n].lhs != 0) { | ||
| 1323 | n = datas[n].lhs; | ||
| 1324 | } else { | ||
| 1325 | return main_tokens[n] + end_offset; | ||
| 1326 | } | ||
| 1327 | }, | 1318 | }, |
| 1328 | .array_type_sentinel => { | 1319 | .array_type_sentinel => { |
| 1329 | const extra = tree.extraData(datas[n].rhs, Node.ArrayTypeSentinel); | 1320 | _, const extra_index = tree.nodeData(n).node_and_extra; |
| 1321 | const extra = tree.extraData(extra_index, Node.ArrayTypeSentinel); | ||
| 1330 | n = extra.elem_type; | 1322 | n = extra.elem_type; |
| 1331 | }, | 1323 | }, |
| 1332 | }; | 1324 | }; |
| 1333 | } | 1325 | } |
| 1334 | 1326 | ||
| 1335 | pub fn tokensOnSameLine(tree: Ast, token1: TokenIndex, token2: TokenIndex) bool { | 1327 | pub fn tokensOnSameLine(tree: Ast, token1: TokenIndex, token2: TokenIndex) bool { |
| 1336 | const token_starts = tree.tokens.items(.start); | 1328 | const source = tree.source[tree.tokenStart(token1)..tree.tokenStart(token2)]; |
| 1337 | const source = tree.source[token_starts[token1]..token_starts[token2]]; | ||
| 1338 | return mem.indexOfScalar(u8, source, '\n') == null; | 1329 | return mem.indexOfScalar(u8, source, '\n') == null; |
| 1339 | } | 1330 | } |
| 1340 | 1331 | ||
| 1341 | pub fn getNodeSource(tree: Ast, node: Node.Index) []const u8 { | 1332 | pub fn getNodeSource(tree: Ast, node: Node.Index) []const u8 { |
| 1342 | const token_starts = tree.tokens.items(.start); | ||
| 1343 | const first_token = tree.firstToken(node); | 1333 | const first_token = tree.firstToken(node); |
| 1344 | const last_token = tree.lastToken(node); | 1334 | const last_token = tree.lastToken(node); |
| 1345 | const start = token_starts[first_token]; | 1335 | const start = tree.tokenStart(first_token); |
| 1346 | const end = token_starts[last_token] + tree.tokenSlice(last_token).len; | 1336 | const end = tree.tokenStart(last_token) + tree.tokenSlice(last_token).len; |
| 1347 | return tree.source[start..end]; | 1337 | return tree.source[start..end]; |
| 1348 | } | 1338 | } |
| 1349 | 1339 | ||
| 1350 | pub fn globalVarDecl(tree: Ast, node: Node.Index) full.VarDecl { | 1340 | pub fn globalVarDecl(tree: Ast, node: Node.Index) full.VarDecl { |
| 1351 | assert(tree.nodes.items(.tag)[node] == .global_var_decl); | 1341 | assert(tree.nodeTag(node) == .global_var_decl); |
| 1352 | const data = tree.nodes.items(.data)[node]; | 1342 | const extra_index, const init_node = tree.nodeData(node).extra_and_opt_node; |
| 1353 | const extra = tree.extraData(data.lhs, Node.GlobalVarDecl); | 1343 | const extra = tree.extraData(extra_index, Node.GlobalVarDecl); |
| 1354 | return tree.fullVarDeclComponents(.{ | 1344 | return tree.fullVarDeclComponents(.{ |
| 1355 | .type_node = extra.type_node, | 1345 | .type_node = extra.type_node, |
| 1356 | .align_node = extra.align_node, | 1346 | .align_node = extra.align_node, |
| 1357 | .addrspace_node = extra.addrspace_node, | 1347 | .addrspace_node = extra.addrspace_node, |
| 1358 | .section_node = extra.section_node, | 1348 | .section_node = extra.section_node, |
| 1359 | .init_node = data.rhs, | 1349 | .init_node = init_node, |
| 1360 | .mut_token = tree.nodes.items(.main_token)[node], | 1350 | .mut_token = tree.nodeMainToken(node), |
| 1361 | }); | 1351 | }); |
| 1362 | } | 1352 | } |
| 1363 | 1353 | ||
| 1364 | pub fn localVarDecl(tree: Ast, node: Node.Index) full.VarDecl { | 1354 | pub fn localVarDecl(tree: Ast, node: Node.Index) full.VarDecl { |
| 1365 | assert(tree.nodes.items(.tag)[node] == .local_var_decl); | 1355 | assert(tree.nodeTag(node) == .local_var_decl); |
| 1366 | const data = tree.nodes.items(.data)[node]; | 1356 | const extra_index, const init_node = tree.nodeData(node).extra_and_opt_node; |
| 1367 | const extra = tree.extraData(data.lhs, Node.LocalVarDecl); | 1357 | const extra = tree.extraData(extra_index, Node.LocalVarDecl); |
| 1368 | return tree.fullVarDeclComponents(.{ | 1358 | return tree.fullVarDeclComponents(.{ |
| 1369 | .type_node = extra.type_node, | 1359 | .type_node = extra.type_node.toOptional(), |
| 1370 | .align_node = extra.align_node, | 1360 | .align_node = extra.align_node.toOptional(), |
| 1371 | .addrspace_node = 0, | 1361 | .addrspace_node = .none, |
| 1372 | .section_node = 0, | 1362 | .section_node = .none, |
| 1373 | .init_node = data.rhs, | 1363 | .init_node = init_node, |
| 1374 | .mut_token = tree.nodes.items(.main_token)[node], | 1364 | .mut_token = tree.nodeMainToken(node), |
| 1375 | }); | 1365 | }); |
| 1376 | } | 1366 | } |
| 1377 | 1367 | ||
| 1378 | pub fn simpleVarDecl(tree: Ast, node: Node.Index) full.VarDecl { | 1368 | pub fn simpleVarDecl(tree: Ast, node: Node.Index) full.VarDecl { |
| 1379 | assert(tree.nodes.items(.tag)[node] == .simple_var_decl); | 1369 | assert(tree.nodeTag(node) == .simple_var_decl); |
| 1380 | const data = tree.nodes.items(.data)[node]; | 1370 | const type_node, const init_node = tree.nodeData(node).opt_node_and_opt_node; |
| 1381 | return tree.fullVarDeclComponents(.{ | 1371 | return tree.fullVarDeclComponents(.{ |
| 1382 | .type_node = data.lhs, | 1372 | .type_node = type_node, |
| 1383 | .align_node = 0, | 1373 | .align_node = .none, |
| 1384 | .addrspace_node = 0, | 1374 | .addrspace_node = .none, |
| 1385 | .section_node = 0, | 1375 | .section_node = .none, |
| 1386 | .init_node = data.rhs, | 1376 | .init_node = init_node, |
| 1387 | .mut_token = tree.nodes.items(.main_token)[node], | 1377 | .mut_token = tree.nodeMainToken(node), |
| 1388 | }); | 1378 | }); |
| 1389 | } | 1379 | } |
| 1390 | 1380 | ||
| 1391 | pub fn alignedVarDecl(tree: Ast, node: Node.Index) full.VarDecl { | 1381 | pub fn alignedVarDecl(tree: Ast, node: Node.Index) full.VarDecl { |
| 1392 | assert(tree.nodes.items(.tag)[node] == .aligned_var_decl); | 1382 | assert(tree.nodeTag(node) == .aligned_var_decl); |
| 1393 | const data = tree.nodes.items(.data)[node]; | 1383 | const align_node, const init_node = tree.nodeData(node).node_and_opt_node; |
| 1394 | return tree.fullVarDeclComponents(.{ | 1384 | return tree.fullVarDeclComponents(.{ |
| 1395 | .type_node = 0, | 1385 | .type_node = .none, |
| 1396 | .align_node = data.lhs, | 1386 | .align_node = align_node.toOptional(), |
| 1397 | .addrspace_node = 0, | 1387 | .addrspace_node = .none, |
| 1398 | .section_node = 0, | 1388 | .section_node = .none, |
| 1399 | .init_node = data.rhs, | 1389 | .init_node = init_node, |
| 1400 | .mut_token = tree.nodes.items(.main_token)[node], | 1390 | .mut_token = tree.nodeMainToken(node), |
| 1401 | }); | 1391 | }); |
| 1402 | } | 1392 | } |
| 1403 | 1393 | ||
| 1404 | pub fn assignDestructure(tree: Ast, node: Node.Index) full.AssignDestructure { | 1394 | pub fn assignDestructure(tree: Ast, node: Node.Index) full.AssignDestructure { |
| 1405 | const data = tree.nodes.items(.data)[node]; | 1395 | const extra_index, const value_expr = tree.nodeData(node).extra_and_node; |
| 1406 | const variable_count = tree.extra_data[data.lhs]; | 1396 | const variable_count = tree.extra_data[@intFromEnum(extra_index)]; |
| 1407 | return tree.fullAssignDestructureComponents(.{ | 1397 | return tree.fullAssignDestructureComponents(.{ |
| 1408 | .variables = tree.extra_data[data.lhs + 1 ..][0..variable_count], | 1398 | .variables = tree.extraDataSliceWithLen(@enumFromInt(@intFromEnum(extra_index) + 1), variable_count, Node.Index), |
| 1409 | .equal_token = tree.nodes.items(.main_token)[node], | 1399 | .equal_token = tree.nodeMainToken(node), |
| 1410 | .value_expr = data.rhs, | 1400 | .value_expr = value_expr, |
| 1411 | }); | 1401 | }); |
| 1412 | } | 1402 | } |
| 1413 | 1403 | ||
| 1414 | pub fn ifSimple(tree: Ast, node: Node.Index) full.If { | 1404 | pub fn ifSimple(tree: Ast, node: Node.Index) full.If { |
| 1415 | assert(tree.nodes.items(.tag)[node] == .if_simple); | 1405 | assert(tree.nodeTag(node) == .if_simple); |
| 1416 | const data = tree.nodes.items(.data)[node]; | 1406 | const cond_expr, const then_expr = tree.nodeData(node).node_and_node; |
| 1417 | return tree.fullIfComponents(.{ | 1407 | return tree.fullIfComponents(.{ |
| 1418 | .cond_expr = data.lhs, | 1408 | .cond_expr = cond_expr, |
| 1419 | .then_expr = data.rhs, | 1409 | .then_expr = then_expr, |
| 1420 | .else_expr = 0, | 1410 | .else_expr = .none, |
| 1421 | .if_token = tree.nodes.items(.main_token)[node], | 1411 | .if_token = tree.nodeMainToken(node), |
| 1422 | }); | 1412 | }); |
| 1423 | } | 1413 | } |
| 1424 | 1414 | ||
| 1425 | pub fn ifFull(tree: Ast, node: Node.Index) full.If { | 1415 | pub fn ifFull(tree: Ast, node: Node.Index) full.If { |
| 1426 | assert(tree.nodes.items(.tag)[node] == .@"if"); | 1416 | assert(tree.nodeTag(node) == .@"if"); |
| 1427 | const data = tree.nodes.items(.data)[node]; | 1417 | const cond_expr, const extra_index = tree.nodeData(node).node_and_extra; |
| 1428 | const extra = tree.extraData(data.rhs, Node.If); | 1418 | const extra = tree.extraData(extra_index, Node.If); |
| 1429 | return tree.fullIfComponents(.{ | 1419 | return tree.fullIfComponents(.{ |
| 1430 | .cond_expr = data.lhs, | 1420 | .cond_expr = cond_expr, |
| 1431 | .then_expr = extra.then_expr, | 1421 | .then_expr = extra.then_expr, |
| 1432 | .else_expr = extra.else_expr, | 1422 | .else_expr = extra.else_expr.toOptional(), |
| 1433 | .if_token = tree.nodes.items(.main_token)[node], | 1423 | .if_token = tree.nodeMainToken(node), |
| 1434 | }); | 1424 | }); |
| 1435 | } | 1425 | } |
| 1436 | 1426 | ||
| 1437 | pub fn containerField(tree: Ast, node: Node.Index) full.ContainerField { | 1427 | pub fn containerField(tree: Ast, node: Node.Index) full.ContainerField { |
| 1438 | assert(tree.nodes.items(.tag)[node] == .container_field); | 1428 | assert(tree.nodeTag(node) == .container_field); |
| 1439 | const data = tree.nodes.items(.data)[node]; | 1429 | const type_expr, const extra_index = tree.nodeData(node).node_and_extra; |
| 1440 | const extra = tree.extraData(data.rhs, Node.ContainerField); | 1430 | const extra = tree.extraData(extra_index, Node.ContainerField); |
| 1441 | const main_token = tree.nodes.items(.main_token)[node]; | 1431 | const main_token = tree.nodeMainToken(node); |
| 1442 | return tree.fullContainerFieldComponents(.{ | 1432 | return tree.fullContainerFieldComponents(.{ |
| 1443 | .main_token = main_token, | 1433 | .main_token = main_token, |
| 1444 | .type_expr = data.lhs, | 1434 | .type_expr = type_expr.toOptional(), |
| 1445 | .align_expr = extra.align_expr, | 1435 | .align_expr = extra.align_expr.toOptional(), |
| 1446 | .value_expr = extra.value_expr, | 1436 | .value_expr = extra.value_expr.toOptional(), |
| 1447 | .tuple_like = tree.tokens.items(.tag)[main_token] != .identifier or | 1437 | .tuple_like = tree.tokenTag(main_token) != .identifier or |
| 1448 | tree.tokens.items(.tag)[main_token + 1] != .colon, | 1438 | tree.tokenTag(main_token + 1) != .colon, |
| 1449 | }); | 1439 | }); |
| 1450 | } | 1440 | } |
| 1451 | 1441 | ||
| 1452 | pub fn containerFieldInit(tree: Ast, node: Node.Index) full.ContainerField { | 1442 | pub fn containerFieldInit(tree: Ast, node: Node.Index) full.ContainerField { |
| 1453 | assert(tree.nodes.items(.tag)[node] == .container_field_init); | 1443 | assert(tree.nodeTag(node) == .container_field_init); |
| 1454 | const data = tree.nodes.items(.data)[node]; | 1444 | const type_expr, const value_expr = tree.nodeData(node).node_and_opt_node; |
| 1455 | const main_token = tree.nodes.items(.main_token)[node]; | 1445 | const main_token = tree.nodeMainToken(node); |
| 1456 | return tree.fullContainerFieldComponents(.{ | 1446 | return tree.fullContainerFieldComponents(.{ |
| 1457 | .main_token = main_token, | 1447 | .main_token = main_token, |
| 1458 | .type_expr = data.lhs, | 1448 | .type_expr = type_expr.toOptional(), |
| 1459 | .align_expr = 0, | 1449 | .align_expr = .none, |
| 1460 | .value_expr = data.rhs, | 1450 | .value_expr = value_expr, |
| 1461 | .tuple_like = tree.tokens.items(.tag)[main_token] != .identifier or | 1451 | .tuple_like = tree.tokenTag(main_token) != .identifier or |
| 1462 | tree.tokens.items(.tag)[main_token + 1] != .colon, | 1452 | tree.tokenTag(main_token + 1) != .colon, |
| 1463 | }); | 1453 | }); |
| 1464 | } | 1454 | } |
| 1465 | 1455 | ||
| 1466 | pub fn containerFieldAlign(tree: Ast, node: Node.Index) full.ContainerField { | 1456 | pub fn containerFieldAlign(tree: Ast, node: Node.Index) full.ContainerField { |
| 1467 | assert(tree.nodes.items(.tag)[node] == .container_field_align); | 1457 | assert(tree.nodeTag(node) == .container_field_align); |
| 1468 | const data = tree.nodes.items(.data)[node]; | 1458 | const type_expr, const align_expr = tree.nodeData(node).node_and_node; |
| 1469 | const main_token = tree.nodes.items(.main_token)[node]; | 1459 | const main_token = tree.nodeMainToken(node); |
| 1470 | return tree.fullContainerFieldComponents(.{ | 1460 | return tree.fullContainerFieldComponents(.{ |
| 1471 | .main_token = main_token, | 1461 | .main_token = main_token, |
| 1472 | .type_expr = data.lhs, | 1462 | .type_expr = type_expr.toOptional(), |
| 1473 | .align_expr = data.rhs, | 1463 | .align_expr = align_expr.toOptional(), |
| 1474 | .value_expr = 0, | 1464 | .value_expr = .none, |
| 1475 | .tuple_like = tree.tokens.items(.tag)[main_token] != .identifier or | 1465 | .tuple_like = tree.tokenTag(main_token) != .identifier or |
| 1476 | tree.tokens.items(.tag)[main_token + 1] != .colon, | 1466 | tree.tokenTag(main_token + 1) != .colon, |
| 1477 | }); | 1467 | }); |
| 1478 | } | 1468 | } |
| 1479 | 1469 | ||
| 1480 | pub fn fnProtoSimple(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.FnProto { | 1470 | pub fn fnProtoSimple(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.FnProto { |
| 1481 | assert(tree.nodes.items(.tag)[node] == .fn_proto_simple); | 1471 | assert(tree.nodeTag(node) == .fn_proto_simple); |
| 1482 | const data = tree.nodes.items(.data)[node]; | 1472 | const first_param, const return_type = tree.nodeData(node).opt_node_and_opt_node; |
| 1483 | buffer[0] = data.lhs; | 1473 | const params = loadOptionalNodesIntoBuffer(1, buffer, .{first_param}); |
| 1484 | const params = if (data.lhs == 0) buffer[0..0] else buffer[0..1]; | ||
| 1485 | return tree.fullFnProtoComponents(.{ | 1474 | return tree.fullFnProtoComponents(.{ |
| 1486 | .proto_node = node, | 1475 | .proto_node = node, |
| 1487 | .fn_token = tree.nodes.items(.main_token)[node], | 1476 | .fn_token = tree.nodeMainToken(node), |
| 1488 | .return_type = data.rhs, | 1477 | .return_type = return_type, |
| 1489 | .params = params, | 1478 | .params = params, |
| 1490 | .align_expr = 0, | 1479 | .align_expr = .none, |
| 1491 | .addrspace_expr = 0, | 1480 | .addrspace_expr = .none, |
| 1492 | .section_expr = 0, | 1481 | .section_expr = .none, |
| 1493 | .callconv_expr = 0, | 1482 | .callconv_expr = .none, |
| 1494 | }); | 1483 | }); |
| 1495 | } | 1484 | } |
| 1496 | 1485 | ||
| 1497 | pub fn fnProtoMulti(tree: Ast, node: Node.Index) full.FnProto { | 1486 | pub fn fnProtoMulti(tree: Ast, node: Node.Index) full.FnProto { |
| 1498 | assert(tree.nodes.items(.tag)[node] == .fn_proto_multi); | 1487 | assert(tree.nodeTag(node) == .fn_proto_multi); |
| 1499 | const data = tree.nodes.items(.data)[node]; | 1488 | const extra_index, const return_type = tree.nodeData(node).extra_and_opt_node; |
| 1500 | const params_range = tree.extraData(data.lhs, Node.SubRange); | 1489 | const params = tree.extraDataSlice(tree.extraData(extra_index, Node.SubRange), Node.Index); |
| 1501 | const params = tree.extra_data[params_range.start..params_range.end]; | ||
| 1502 | return tree.fullFnProtoComponents(.{ | 1490 | return tree.fullFnProtoComponents(.{ |
| 1503 | .proto_node = node, | 1491 | .proto_node = node, |
| 1504 | .fn_token = tree.nodes.items(.main_token)[node], | 1492 | .fn_token = tree.nodeMainToken(node), |
| 1505 | .return_type = data.rhs, | 1493 | .return_type = return_type, |
| 1506 | .params = params, | 1494 | .params = params, |
| 1507 | .align_expr = 0, | 1495 | .align_expr = .none, |
| 1508 | .addrspace_expr = 0, | 1496 | .addrspace_expr = .none, |
| 1509 | .section_expr = 0, | 1497 | .section_expr = .none, |
| 1510 | .callconv_expr = 0, | 1498 | .callconv_expr = .none, |
| 1511 | }); | 1499 | }); |
| 1512 | } | 1500 | } |
| 1513 | 1501 | ||
| 1514 | pub fn fnProtoOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.FnProto { | 1502 | pub fn fnProtoOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.FnProto { |
| 1515 | assert(tree.nodes.items(.tag)[node] == .fn_proto_one); | 1503 | assert(tree.nodeTag(node) == .fn_proto_one); |
| 1516 | const data = tree.nodes.items(.data)[node]; | 1504 | const extra_index, const return_type = tree.nodeData(node).extra_and_opt_node; |
| 1517 | const extra = tree.extraData(data.lhs, Node.FnProtoOne); | 1505 | const extra = tree.extraData(extra_index, Node.FnProtoOne); |
| 1518 | buffer[0] = extra.param; | 1506 | const params = loadOptionalNodesIntoBuffer(1, buffer, .{extra.param}); |
| 1519 | const params = if (extra.param == 0) buffer[0..0] else buffer[0..1]; | ||
| 1520 | return tree.fullFnProtoComponents(.{ | 1507 | return tree.fullFnProtoComponents(.{ |
| 1521 | .proto_node = node, | 1508 | .proto_node = node, |
| 1522 | .fn_token = tree.nodes.items(.main_token)[node], | 1509 | .fn_token = tree.nodeMainToken(node), |
| 1523 | .return_type = data.rhs, | 1510 | .return_type = return_type, |
| 1524 | .params = params, | 1511 | .params = params, |
| 1525 | .align_expr = extra.align_expr, | 1512 | .align_expr = extra.align_expr, |
| 1526 | .addrspace_expr = extra.addrspace_expr, | 1513 | .addrspace_expr = extra.addrspace_expr, |
| ... | @@ -1530,14 +1517,14 @@ pub fn fnProtoOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.FnPr | ... | @@ -1530,14 +1517,14 @@ pub fn fnProtoOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.FnPr |
| 1530 | } | 1517 | } |
| 1531 | 1518 | ||
| 1532 | pub fn fnProto(tree: Ast, node: Node.Index) full.FnProto { | 1519 | pub fn fnProto(tree: Ast, node: Node.Index) full.FnProto { |
| 1533 | assert(tree.nodes.items(.tag)[node] == .fn_proto); | 1520 | assert(tree.nodeTag(node) == .fn_proto); |
| 1534 | const data = tree.nodes.items(.data)[node]; | 1521 | const extra_index, const return_type = tree.nodeData(node).extra_and_opt_node; |
| 1535 | const extra = tree.extraData(data.lhs, Node.FnProto); | 1522 | const extra = tree.extraData(extra_index, Node.FnProto); |
| 1536 | const params = tree.extra_data[extra.params_start..extra.params_end]; | 1523 | const params = tree.extraDataSlice(.{ .start = extra.params_start, .end = extra.params_end }, Node.Index); |
| 1537 | return tree.fullFnProtoComponents(.{ | 1524 | return tree.fullFnProtoComponents(.{ |
| 1538 | .proto_node = node, | 1525 | .proto_node = node, |
| 1539 | .fn_token = tree.nodes.items(.main_token)[node], | 1526 | .fn_token = tree.nodeMainToken(node), |
| 1540 | .return_type = data.rhs, | 1527 | .return_type = return_type, |
| 1541 | .params = params, | 1528 | .params = params, |
| 1542 | .align_expr = extra.align_expr, | 1529 | .align_expr = extra.align_expr, |
| 1543 | .addrspace_expr = extra.addrspace_expr, | 1530 | .addrspace_expr = extra.addrspace_expr, |
| ... | @@ -1547,300 +1534,275 @@ pub fn fnProto(tree: Ast, node: Node.Index) full.FnProto { | ... | @@ -1547,300 +1534,275 @@ pub fn fnProto(tree: Ast, node: Node.Index) full.FnProto { |
| 1547 | } | 1534 | } |
| 1548 | 1535 | ||
| 1549 | pub fn structInitOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.StructInit { | 1536 | pub fn structInitOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.StructInit { |
| 1550 | assert(tree.nodes.items(.tag)[node] == .struct_init_one or | 1537 | assert(tree.nodeTag(node) == .struct_init_one or |
| 1551 | tree.nodes.items(.tag)[node] == .struct_init_one_comma); | 1538 | tree.nodeTag(node) == .struct_init_one_comma); |
| 1552 | const data = tree.nodes.items(.data)[node]; | 1539 | const type_expr, const first_field = tree.nodeData(node).node_and_opt_node; |
| 1553 | buffer[0] = data.rhs; | 1540 | const fields = loadOptionalNodesIntoBuffer(1, buffer, .{first_field}); |
| 1554 | const fields = if (data.rhs == 0) buffer[0..0] else buffer[0..1]; | ||
| 1555 | return .{ | 1541 | return .{ |
| 1556 | .ast = .{ | 1542 | .ast = .{ |
| 1557 | .lbrace = tree.nodes.items(.main_token)[node], | 1543 | .lbrace = tree.nodeMainToken(node), |
| 1558 | .fields = fields, | 1544 | .fields = fields, |
| 1559 | .type_expr = data.lhs, | 1545 | .type_expr = type_expr.toOptional(), |
| 1560 | }, | 1546 | }, |
| 1561 | }; | 1547 | }; |
| 1562 | } | 1548 | } |
| 1563 | 1549 | ||
| 1564 | pub fn structInitDotTwo(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) full.StructInit { | 1550 | pub fn structInitDotTwo(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) full.StructInit { |
| 1565 | assert(tree.nodes.items(.tag)[node] == .struct_init_dot_two or | 1551 | assert(tree.nodeTag(node) == .struct_init_dot_two or |
| 1566 | tree.nodes.items(.tag)[node] == .struct_init_dot_two_comma); | 1552 | tree.nodeTag(node) == .struct_init_dot_two_comma); |
| 1567 | const data = tree.nodes.items(.data)[node]; | 1553 | const fields = loadOptionalNodesIntoBuffer(2, buffer, tree.nodeData(node).opt_node_and_opt_node); |
| 1568 | buffer.* = .{ data.lhs, data.rhs }; | ||
| 1569 | const fields = if (data.rhs != 0) | ||
| 1570 | buffer[0..2] | ||
| 1571 | else if (data.lhs != 0) | ||
| 1572 | buffer[0..1] | ||
| 1573 | else | ||
| 1574 | buffer[0..0]; | ||
| 1575 | return .{ | 1554 | return .{ |
| 1576 | .ast = .{ | 1555 | .ast = .{ |
| 1577 | .lbrace = tree.nodes.items(.main_token)[node], | 1556 | .lbrace = tree.nodeMainToken(node), |
| 1578 | .fields = fields, | 1557 | .fields = fields, |
| 1579 | .type_expr = 0, | 1558 | .type_expr = .none, |
| 1580 | }, | 1559 | }, |
| 1581 | }; | 1560 | }; |
| 1582 | } | 1561 | } |
| 1583 | 1562 | ||
| 1584 | pub fn structInitDot(tree: Ast, node: Node.Index) full.StructInit { | 1563 | pub fn structInitDot(tree: Ast, node: Node.Index) full.StructInit { |
| 1585 | assert(tree.nodes.items(.tag)[node] == .struct_init_dot or | 1564 | assert(tree.nodeTag(node) == .struct_init_dot or |
| 1586 | tree.nodes.items(.tag)[node] == .struct_init_dot_comma); | 1565 | tree.nodeTag(node) == .struct_init_dot_comma); |
| 1587 | const data = tree.nodes.items(.data)[node]; | 1566 | const fields = tree.extraDataSlice(tree.nodeData(node).extra_range, Node.Index); |
| 1588 | return .{ | 1567 | return .{ |
| 1589 | .ast = .{ | 1568 | .ast = .{ |
| 1590 | .lbrace = tree.nodes.items(.main_token)[node], | 1569 | .lbrace = tree.nodeMainToken(node), |
| 1591 | .fields = tree.extra_data[data.lhs..data.rhs], | 1570 | .fields = fields, |
| 1592 | .type_expr = 0, | 1571 | .type_expr = .none, |
| 1593 | }, | 1572 | }, |
| 1594 | }; | 1573 | }; |
| 1595 | } | 1574 | } |
| 1596 | 1575 | ||
| 1597 | pub fn structInit(tree: Ast, node: Node.Index) full.StructInit { | 1576 | pub fn structInit(tree: Ast, node: Node.Index) full.StructInit { |
| 1598 | assert(tree.nodes.items(.tag)[node] == .struct_init or | 1577 | assert(tree.nodeTag(node) == .struct_init or |
| 1599 | tree.nodes.items(.tag)[node] == .struct_init_comma); | 1578 | tree.nodeTag(node) == .struct_init_comma); |
| 1600 | const data = tree.nodes.items(.data)[node]; | 1579 | const type_expr, const extra_index = tree.nodeData(node).node_and_extra; |
| 1601 | const fields_range = tree.extraData(data.rhs, Node.SubRange); | 1580 | const fields = tree.extraDataSlice(tree.extraData(extra_index, Node.SubRange), Node.Index); |
| 1602 | return .{ | 1581 | return .{ |
| 1603 | .ast = .{ | 1582 | .ast = .{ |
| 1604 | .lbrace = tree.nodes.items(.main_token)[node], | 1583 | .lbrace = tree.nodeMainToken(node), |
| 1605 | .fields = tree.extra_data[fields_range.start..fields_range.end], | 1584 | .fields = fields, |
| 1606 | .type_expr = data.lhs, | 1585 | .type_expr = type_expr.toOptional(), |
| 1607 | }, | 1586 | }, |
| 1608 | }; | 1587 | }; |
| 1609 | } | 1588 | } |
| 1610 | 1589 | ||
| 1611 | pub fn arrayInitOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.ArrayInit { | 1590 | pub fn arrayInitOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.ArrayInit { |
| 1612 | assert(tree.nodes.items(.tag)[node] == .array_init_one or | 1591 | assert(tree.nodeTag(node) == .array_init_one or |
| 1613 | tree.nodes.items(.tag)[node] == .array_init_one_comma); | 1592 | tree.nodeTag(node) == .array_init_one_comma); |
| 1614 | const data = tree.nodes.items(.data)[node]; | 1593 | const type_expr, buffer[0] = tree.nodeData(node).node_and_node; |
| 1615 | buffer[0] = data.rhs; | ||
| 1616 | const elements = if (data.rhs == 0) buffer[0..0] else buffer[0..1]; | ||
| 1617 | return .{ | 1594 | return .{ |
| 1618 | .ast = .{ | 1595 | .ast = .{ |
| 1619 | .lbrace = tree.nodes.items(.main_token)[node], | 1596 | .lbrace = tree.nodeMainToken(node), |
| 1620 | .elements = elements, | 1597 | .elements = buffer[0..1], |
| 1621 | .type_expr = data.lhs, | 1598 | .type_expr = type_expr.toOptional(), |
| 1622 | }, | 1599 | }, |
| 1623 | }; | 1600 | }; |
| 1624 | } | 1601 | } |
| 1625 | 1602 | ||
| 1626 | pub fn arrayInitDotTwo(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) full.ArrayInit { | 1603 | pub fn arrayInitDotTwo(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) full.ArrayInit { |
| 1627 | assert(tree.nodes.items(.tag)[node] == .array_init_dot_two or | 1604 | assert(tree.nodeTag(node) == .array_init_dot_two or |
| 1628 | tree.nodes.items(.tag)[node] == .array_init_dot_two_comma); | 1605 | tree.nodeTag(node) == .array_init_dot_two_comma); |
| 1629 | const data = tree.nodes.items(.data)[node]; | 1606 | const elements = loadOptionalNodesIntoBuffer(2, buffer, tree.nodeData(node).opt_node_and_opt_node); |
| 1630 | buffer.* = .{ data.lhs, data.rhs }; | ||
| 1631 | const elements = if (data.rhs != 0) | ||
| 1632 | buffer[0..2] | ||
| 1633 | else if (data.lhs != 0) | ||
| 1634 | buffer[0..1] | ||
| 1635 | else | ||
| 1636 | buffer[0..0]; | ||
| 1637 | return .{ | 1607 | return .{ |
| 1638 | .ast = .{ | 1608 | .ast = .{ |
| 1639 | .lbrace = tree.nodes.items(.main_token)[node], | 1609 | .lbrace = tree.nodeMainToken(node), |
| 1640 | .elements = elements, | 1610 | .elements = elements, |
| 1641 | .type_expr = 0, | 1611 | .type_expr = .none, |
| 1642 | }, | 1612 | }, |
| 1643 | }; | 1613 | }; |
| 1644 | } | 1614 | } |
| 1645 | 1615 | ||
| 1646 | pub fn arrayInitDot(tree: Ast, node: Node.Index) full.ArrayInit { | 1616 | pub fn arrayInitDot(tree: Ast, node: Node.Index) full.ArrayInit { |
| 1647 | assert(tree.nodes.items(.tag)[node] == .array_init_dot or | 1617 | assert(tree.nodeTag(node) == .array_init_dot or |
| 1648 | tree.nodes.items(.tag)[node] == .array_init_dot_comma); | 1618 | tree.nodeTag(node) == .array_init_dot_comma); |
| 1649 | const data = tree.nodes.items(.data)[node]; | 1619 | const elements = tree.extraDataSlice(tree.nodeData(node).extra_range, Node.Index); |
| 1650 | return .{ | 1620 | return .{ |
| 1651 | .ast = .{ | 1621 | .ast = .{ |
| 1652 | .lbrace = tree.nodes.items(.main_token)[node], | 1622 | .lbrace = tree.nodeMainToken(node), |
| 1653 | .elements = tree.extra_data[data.lhs..data.rhs], | 1623 | .elements = elements, |
| 1654 | .type_expr = 0, | 1624 | .type_expr = .none, |
| 1655 | }, | 1625 | }, |
| 1656 | }; | 1626 | }; |
| 1657 | } | 1627 | } |
| 1658 | 1628 | ||
| 1659 | pub fn arrayInit(tree: Ast, node: Node.Index) full.ArrayInit { | 1629 | pub fn arrayInit(tree: Ast, node: Node.Index) full.ArrayInit { |
| 1660 | assert(tree.nodes.items(.tag)[node] == .array_init or | 1630 | assert(tree.nodeTag(node) == .array_init or |
| 1661 | tree.nodes.items(.tag)[node] == .array_init_comma); | 1631 | tree.nodeTag(node) == .array_init_comma); |
| 1662 | const data = tree.nodes.items(.data)[node]; | 1632 | const type_expr, const extra_index = tree.nodeData(node).node_and_extra; |
| 1663 | const elem_range = tree.extraData(data.rhs, Node.SubRange); | 1633 | const elements = tree.extraDataSlice(tree.extraData(extra_index, Node.SubRange), Node.Index); |
| 1664 | return .{ | 1634 | return .{ |
| 1665 | .ast = .{ | 1635 | .ast = .{ |
| 1666 | .lbrace = tree.nodes.items(.main_token)[node], | 1636 | .lbrace = tree.nodeMainToken(node), |
| 1667 | .elements = tree.extra_data[elem_range.start..elem_range.end], | 1637 | .elements = elements, |
| 1668 | .type_expr = data.lhs, | 1638 | .type_expr = type_expr.toOptional(), |
| 1669 | }, | 1639 | }, |
| 1670 | }; | 1640 | }; |
| 1671 | } | 1641 | } |
| 1672 | 1642 | ||
| 1673 | pub fn arrayType(tree: Ast, node: Node.Index) full.ArrayType { | 1643 | pub fn arrayType(tree: Ast, node: Node.Index) full.ArrayType { |
| 1674 | assert(tree.nodes.items(.tag)[node] == .array_type); | 1644 | assert(tree.nodeTag(node) == .array_type); |
| 1675 | const data = tree.nodes.items(.data)[node]; | 1645 | const elem_count, const elem_type = tree.nodeData(node).node_and_node; |
| 1676 | return .{ | 1646 | return .{ |
| 1677 | .ast = .{ | 1647 | .ast = .{ |
| 1678 | .lbracket = tree.nodes.items(.main_token)[node], | 1648 | .lbracket = tree.nodeMainToken(node), |
| 1679 | .elem_count = data.lhs, | 1649 | .elem_count = elem_count, |
| 1680 | .sentinel = 0, | 1650 | .sentinel = .none, |
| 1681 | .elem_type = data.rhs, | 1651 | .elem_type = elem_type, |
| 1682 | }, | 1652 | }, |
| 1683 | }; | 1653 | }; |
| 1684 | } | 1654 | } |
| 1685 | 1655 | ||
| 1686 | pub fn arrayTypeSentinel(tree: Ast, node: Node.Index) full.ArrayType { | 1656 | pub fn arrayTypeSentinel(tree: Ast, node: Node.Index) full.ArrayType { |
| 1687 | assert(tree.nodes.items(.tag)[node] == .array_type_sentinel); | 1657 | assert(tree.nodeTag(node) == .array_type_sentinel); |
| 1688 | const data = tree.nodes.items(.data)[node]; | 1658 | const elem_count, const extra_index = tree.nodeData(node).node_and_extra; |
| 1689 | const extra = tree.extraData(data.rhs, Node.ArrayTypeSentinel); | 1659 | const extra = tree.extraData(extra_index, Node.ArrayTypeSentinel); |
| 1690 | assert(extra.sentinel != 0); | ||
| 1691 | return .{ | 1660 | return .{ |
| 1692 | .ast = .{ | 1661 | .ast = .{ |
| 1693 | .lbracket = tree.nodes.items(.main_token)[node], | 1662 | .lbracket = tree.nodeMainToken(node), |
| 1694 | .elem_count = data.lhs, | 1663 | .elem_count = elem_count, |
| 1695 | .sentinel = extra.sentinel, | 1664 | .sentinel = extra.sentinel.toOptional(), |
| 1696 | .elem_type = extra.elem_type, | 1665 | .elem_type = extra.elem_type, |
| 1697 | }, | 1666 | }, |
| 1698 | }; | 1667 | }; |
| 1699 | } | 1668 | } |
| 1700 | 1669 | ||
| 1701 | pub fn ptrTypeAligned(tree: Ast, node: Node.Index) full.PtrType { | 1670 | pub fn ptrTypeAligned(tree: Ast, node: Node.Index) full.PtrType { |
| 1702 | assert(tree.nodes.items(.tag)[node] == .ptr_type_aligned); | 1671 | assert(tree.nodeTag(node) == .ptr_type_aligned); |
| 1703 | const data = tree.nodes.items(.data)[node]; | 1672 | const align_node, const child_type = tree.nodeData(node).opt_node_and_node; |
| 1704 | return tree.fullPtrTypeComponents(.{ | 1673 | return tree.fullPtrTypeComponents(.{ |
| 1705 | .main_token = tree.nodes.items(.main_token)[node], | 1674 | .main_token = tree.nodeMainToken(node), |
| 1706 | .align_node = data.lhs, | 1675 | .align_node = align_node, |
| 1707 | .addrspace_node = 0, | 1676 | .addrspace_node = .none, |
| 1708 | .sentinel = 0, | 1677 | .sentinel = .none, |
| 1709 | .bit_range_start = 0, | 1678 | .bit_range_start = .none, |
| 1710 | .bit_range_end = 0, | 1679 | .bit_range_end = .none, |
| 1711 | .child_type = data.rhs, | 1680 | .child_type = child_type, |
| 1712 | }); | 1681 | }); |
| 1713 | } | 1682 | } |
| 1714 | 1683 | ||
| 1715 | pub fn ptrTypeSentinel(tree: Ast, node: Node.Index) full.PtrType { | 1684 | pub fn ptrTypeSentinel(tree: Ast, node: Node.Index) full.PtrType { |
| 1716 | assert(tree.nodes.items(.tag)[node] == .ptr_type_sentinel); | 1685 | assert(tree.nodeTag(node) == .ptr_type_sentinel); |
| 1717 | const data = tree.nodes.items(.data)[node]; | 1686 | const sentinel, const child_type = tree.nodeData(node).opt_node_and_node; |
| 1718 | return tree.fullPtrTypeComponents(.{ | 1687 | return tree.fullPtrTypeComponents(.{ |
| 1719 | .main_token = tree.nodes.items(.main_token)[node], | 1688 | .main_token = tree.nodeMainToken(node), |
| 1720 | .align_node = 0, | 1689 | .align_node = .none, |
| 1721 | .addrspace_node = 0, | 1690 | .addrspace_node = .none, |
| 1722 | .sentinel = data.lhs, | 1691 | .sentinel = sentinel, |
| 1723 | .bit_range_start = 0, | 1692 | .bit_range_start = .none, |
| 1724 | .bit_range_end = 0, | 1693 | .bit_range_end = .none, |
| 1725 | .child_type = data.rhs, | 1694 | .child_type = child_type, |
| 1726 | }); | 1695 | }); |
| 1727 | } | 1696 | } |
| 1728 | 1697 | ||
| 1729 | pub fn ptrType(tree: Ast, node: Node.Index) full.PtrType { | 1698 | pub fn ptrType(tree: Ast, node: Node.Index) full.PtrType { |
| 1730 | assert(tree.nodes.items(.tag)[node] == .ptr_type); | 1699 | assert(tree.nodeTag(node) == .ptr_type); |
| 1731 | const data = tree.nodes.items(.data)[node]; | 1700 | const extra_index, const child_type = tree.nodeData(node).extra_and_node; |
| 1732 | const extra = tree.extraData(data.lhs, Node.PtrType); | 1701 | const extra = tree.extraData(extra_index, Node.PtrType); |
| 1733 | return tree.fullPtrTypeComponents(.{ | 1702 | return tree.fullPtrTypeComponents(.{ |
| 1734 | .main_token = tree.nodes.items(.main_token)[node], | 1703 | .main_token = tree.nodeMainToken(node), |
| 1735 | .align_node = extra.align_node, | 1704 | .align_node = extra.align_node, |
| 1736 | .addrspace_node = extra.addrspace_node, | 1705 | .addrspace_node = extra.addrspace_node, |
| 1737 | .sentinel = extra.sentinel, | 1706 | .sentinel = extra.sentinel, |
| 1738 | .bit_range_start = 0, | 1707 | .bit_range_start = .none, |
| 1739 | .bit_range_end = 0, | 1708 | .bit_range_end = .none, |
| 1740 | .child_type = data.rhs, | 1709 | .child_type = child_type, |
| 1741 | }); | 1710 | }); |
| 1742 | } | 1711 | } |
| 1743 | 1712 | ||
| 1744 | pub fn ptrTypeBitRange(tree: Ast, node: Node.Index) full.PtrType { | 1713 | pub fn ptrTypeBitRange(tree: Ast, node: Node.Index) full.PtrType { |
| 1745 | assert(tree.nodes.items(.tag)[node] == .ptr_type_bit_range); | 1714 | assert(tree.nodeTag(node) == .ptr_type_bit_range); |
| 1746 | const data = tree.nodes.items(.data)[node]; | 1715 | const extra_index, const child_type = tree.nodeData(node).extra_and_node; |
| 1747 | const extra = tree.extraData(data.lhs, Node.PtrTypeBitRange); | 1716 | const extra = tree.extraData(extra_index, Node.PtrTypeBitRange); |
| 1748 | return tree.fullPtrTypeComponents(.{ | 1717 | return tree.fullPtrTypeComponents(.{ |
| 1749 | .main_token = tree.nodes.items(.main_token)[node], | 1718 | .main_token = tree.nodeMainToken(node), |
| 1750 | .align_node = extra.align_node, | 1719 | .align_node = extra.align_node.toOptional(), |
| 1751 | .addrspace_node = extra.addrspace_node, | 1720 | .addrspace_node = extra.addrspace_node, |
| 1752 | .sentinel = extra.sentinel, | 1721 | .sentinel = extra.sentinel, |
| 1753 | .bit_range_start = extra.bit_range_start, | 1722 | .bit_range_start = extra.bit_range_start.toOptional(), |
| 1754 | .bit_range_end = extra.bit_range_end, | 1723 | .bit_range_end = extra.bit_range_end.toOptional(), |
| 1755 | .child_type = data.rhs, | 1724 | .child_type = child_type, |
| 1756 | }); | 1725 | }); |
| 1757 | } | 1726 | } |
| 1758 | 1727 | ||
| 1759 | pub fn sliceOpen(tree: Ast, node: Node.Index) full.Slice { | 1728 | pub fn sliceOpen(tree: Ast, node: Node.Index) full.Slice { |
| 1760 | assert(tree.nodes.items(.tag)[node] == .slice_open); | 1729 | assert(tree.nodeTag(node) == .slice_open); |
| 1761 | const data = tree.nodes.items(.data)[node]; | 1730 | const sliced, const start = tree.nodeData(node).node_and_node; |
| 1762 | return .{ | 1731 | return .{ |
| 1763 | .ast = .{ | 1732 | .ast = .{ |
| 1764 | .sliced = data.lhs, | 1733 | .sliced = sliced, |
| 1765 | .lbracket = tree.nodes.items(.main_token)[node], | 1734 | .lbracket = tree.nodeMainToken(node), |
| 1766 | .start = data.rhs, | 1735 | .start = start, |
| 1767 | .end = 0, | 1736 | .end = .none, |
| 1768 | .sentinel = 0, | 1737 | .sentinel = .none, |
| 1769 | }, | 1738 | }, |
| 1770 | }; | 1739 | }; |
| 1771 | } | 1740 | } |
| 1772 | 1741 | ||
| 1773 | pub fn slice(tree: Ast, node: Node.Index) full.Slice { | 1742 | pub fn slice(tree: Ast, node: Node.Index) full.Slice { |
| 1774 | assert(tree.nodes.items(.tag)[node] == .slice); | 1743 | assert(tree.nodeTag(node) == .slice); |
| 1775 | const data = tree.nodes.items(.data)[node]; | 1744 | const sliced, const extra_index = tree.nodeData(node).node_and_extra; |
| 1776 | const extra = tree.extraData(data.rhs, Node.Slice); | 1745 | const extra = tree.extraData(extra_index, Node.Slice); |
| 1777 | return .{ | 1746 | return .{ |
| 1778 | .ast = .{ | 1747 | .ast = .{ |
| 1779 | .sliced = data.lhs, | 1748 | .sliced = sliced, |
| 1780 | .lbracket = tree.nodes.items(.main_token)[node], | 1749 | .lbracket = tree.nodeMainToken(node), |
| 1781 | .start = extra.start, | 1750 | .start = extra.start, |
| 1782 | .end = extra.end, | 1751 | .end = extra.end.toOptional(), |
| 1783 | .sentinel = 0, | 1752 | .sentinel = .none, |
| 1784 | }, | 1753 | }, |
| 1785 | }; | 1754 | }; |
| 1786 | } | 1755 | } |
| 1787 | 1756 | ||
| 1788 | pub fn sliceSentinel(tree: Ast, node: Node.Index) full.Slice { | 1757 | pub fn sliceSentinel(tree: Ast, node: Node.Index) full.Slice { |
| 1789 | assert(tree.nodes.items(.tag)[node] == .slice_sentinel); | 1758 | assert(tree.nodeTag(node) == .slice_sentinel); |
| 1790 | const data = tree.nodes.items(.data)[node]; | 1759 | const sliced, const extra_index = tree.nodeData(node).node_and_extra; |
| 1791 | const extra = tree.extraData(data.rhs, Node.SliceSentinel); | 1760 | const extra = tree.extraData(extra_index, Node.SliceSentinel); |
| 1792 | return .{ | 1761 | return .{ |
| 1793 | .ast = .{ | 1762 | .ast = .{ |
| 1794 | .sliced = data.lhs, | 1763 | .sliced = sliced, |
| 1795 | .lbracket = tree.nodes.items(.main_token)[node], | 1764 | .lbracket = tree.nodeMainToken(node), |
| 1796 | .start = extra.start, | 1765 | .start = extra.start, |
| 1797 | .end = extra.end, | 1766 | .end = extra.end, |
| 1798 | .sentinel = extra.sentinel, | 1767 | .sentinel = extra.sentinel.toOptional(), |
| 1799 | }, | 1768 | }, |
| 1800 | }; | 1769 | }; |
| 1801 | } | 1770 | } |
| 1802 | 1771 | ||
| 1803 | pub fn containerDeclTwo(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl { | 1772 | pub fn containerDeclTwo(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl { |
| 1804 | assert(tree.nodes.items(.tag)[node] == .container_decl_two or | 1773 | assert(tree.nodeTag(node) == .container_decl_two or |
| 1805 | tree.nodes.items(.tag)[node] == .container_decl_two_trailing); | 1774 | tree.nodeTag(node) == .container_decl_two_trailing); |
| 1806 | const data = tree.nodes.items(.data)[node]; | 1775 | const members = loadOptionalNodesIntoBuffer(2, buffer, tree.nodeData(node).opt_node_and_opt_node); |
| 1807 | buffer.* = .{ data.lhs, data.rhs }; | ||
| 1808 | const members = if (data.rhs != 0) | ||
| 1809 | buffer[0..2] | ||
| 1810 | else if (data.lhs != 0) | ||
| 1811 | buffer[0..1] | ||
| 1812 | else | ||
| 1813 | buffer[0..0]; | ||
| 1814 | return tree.fullContainerDeclComponents(.{ | 1776 | return tree.fullContainerDeclComponents(.{ |
| 1815 | .main_token = tree.nodes.items(.main_token)[node], | 1777 | .main_token = tree.nodeMainToken(node), |
| 1816 | .enum_token = null, | 1778 | .enum_token = null, |
| 1817 | .members = members, | 1779 | .members = members, |
| 1818 | .arg = 0, | 1780 | .arg = .none, |
| 1819 | }); | 1781 | }); |
| 1820 | } | 1782 | } |
| 1821 | 1783 | ||
| 1822 | pub fn containerDecl(tree: Ast, node: Node.Index) full.ContainerDecl { | 1784 | pub fn containerDecl(tree: Ast, node: Node.Index) full.ContainerDecl { |
| 1823 | assert(tree.nodes.items(.tag)[node] == .container_decl or | 1785 | assert(tree.nodeTag(node) == .container_decl or |
| 1824 | tree.nodes.items(.tag)[node] == .container_decl_trailing); | 1786 | tree.nodeTag(node) == .container_decl_trailing); |
| 1825 | const data = tree.nodes.items(.data)[node]; | 1787 | const members = tree.extraDataSlice(tree.nodeData(node).extra_range, Node.Index); |
| 1826 | return tree.fullContainerDeclComponents(.{ | 1788 | return tree.fullContainerDeclComponents(.{ |
| 1827 | .main_token = tree.nodes.items(.main_token)[node], | 1789 | .main_token = tree.nodeMainToken(node), |
| 1828 | .enum_token = null, | 1790 | .enum_token = null, |
| 1829 | .members = tree.extra_data[data.lhs..data.rhs], | 1791 | .members = members, |
| 1830 | .arg = 0, | 1792 | .arg = .none, |
| 1831 | }); | 1793 | }); |
| 1832 | } | 1794 | } |
| 1833 | 1795 | ||
| 1834 | pub fn containerDeclArg(tree: Ast, node: Node.Index) full.ContainerDecl { | 1796 | pub fn containerDeclArg(tree: Ast, node: Node.Index) full.ContainerDecl { |
| 1835 | assert(tree.nodes.items(.tag)[node] == .container_decl_arg or | 1797 | assert(tree.nodeTag(node) == .container_decl_arg or |
| 1836 | tree.nodes.items(.tag)[node] == .container_decl_arg_trailing); | 1798 | tree.nodeTag(node) == .container_decl_arg_trailing); |
| 1837 | const data = tree.nodes.items(.data)[node]; | 1799 | const arg, const extra_index = tree.nodeData(node).node_and_extra; |
| 1838 | const members_range = tree.extraData(data.rhs, Node.SubRange); | 1800 | const members = tree.extraDataSlice(tree.extraData(extra_index, Node.SubRange), Node.Index); |
| 1839 | return tree.fullContainerDeclComponents(.{ | 1801 | return tree.fullContainerDeclComponents(.{ |
| 1840 | .main_token = tree.nodes.items(.main_token)[node], | 1802 | .main_token = tree.nodeMainToken(node), |
| 1841 | .enum_token = null, | 1803 | .enum_token = null, |
| 1842 | .members = tree.extra_data[members_range.start..members_range.end], | 1804 | .members = members, |
| 1843 | .arg = data.lhs, | 1805 | .arg = arg.toOptional(), |
| 1844 | }); | 1806 | }); |
| 1845 | } | 1807 | } |
| 1846 | 1808 | ||
| ... | @@ -1848,175 +1810,170 @@ pub fn containerDeclRoot(tree: Ast) full.ContainerDecl { | ... | @@ -1848,175 +1810,170 @@ pub fn containerDeclRoot(tree: Ast) full.ContainerDecl { |
| 1848 | return .{ | 1810 | return .{ |
| 1849 | .layout_token = null, | 1811 | .layout_token = null, |
| 1850 | .ast = .{ | 1812 | .ast = .{ |
| 1851 | .main_token = undefined, | 1813 | .main_token = 0, |
| 1852 | .enum_token = null, | 1814 | .enum_token = null, |
| 1853 | .members = tree.rootDecls(), | 1815 | .members = tree.rootDecls(), |
| 1854 | .arg = 0, | 1816 | .arg = .none, |
| 1855 | }, | 1817 | }, |
| 1856 | }; | 1818 | }; |
| 1857 | } | 1819 | } |
| 1858 | 1820 | ||
| 1859 | pub fn taggedUnionTwo(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl { | 1821 | pub fn taggedUnionTwo(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl { |
| 1860 | assert(tree.nodes.items(.tag)[node] == .tagged_union_two or | 1822 | assert(tree.nodeTag(node) == .tagged_union_two or |
| 1861 | tree.nodes.items(.tag)[node] == .tagged_union_two_trailing); | 1823 | tree.nodeTag(node) == .tagged_union_two_trailing); |
| 1862 | const data = tree.nodes.items(.data)[node]; | 1824 | const members = loadOptionalNodesIntoBuffer(2, buffer, tree.nodeData(node).opt_node_and_opt_node); |
| 1863 | buffer.* = .{ data.lhs, data.rhs }; | 1825 | const main_token = tree.nodeMainToken(node); |
| 1864 | const members = if (data.rhs != 0) | ||
| 1865 | buffer[0..2] | ||
| 1866 | else if (data.lhs != 0) | ||
| 1867 | buffer[0..1] | ||
| 1868 | else | ||
| 1869 | buffer[0..0]; | ||
| 1870 | const main_token = tree.nodes.items(.main_token)[node]; | ||
| 1871 | return tree.fullContainerDeclComponents(.{ | 1826 | return tree.fullContainerDeclComponents(.{ |
| 1872 | .main_token = main_token, | 1827 | .main_token = main_token, |
| 1873 | .enum_token = main_token + 2, // union lparen enum | 1828 | .enum_token = main_token + 2, // union lparen enum |
| 1874 | .members = members, | 1829 | .members = members, |
| 1875 | .arg = 0, | 1830 | .arg = .none, |
| 1876 | }); | 1831 | }); |
| 1877 | } | 1832 | } |
| 1878 | 1833 | ||
| 1879 | pub fn taggedUnion(tree: Ast, node: Node.Index) full.ContainerDecl { | 1834 | pub fn taggedUnion(tree: Ast, node: Node.Index) full.ContainerDecl { |
| 1880 | assert(tree.nodes.items(.tag)[node] == .tagged_union or | 1835 | assert(tree.nodeTag(node) == .tagged_union or |
| 1881 | tree.nodes.items(.tag)[node] == .tagged_union_trailing); | 1836 | tree.nodeTag(node) == .tagged_union_trailing); |
| 1882 | const data = tree.nodes.items(.data)[node]; | 1837 | const members = tree.extraDataSlice(tree.nodeData(node).extra_range, Node.Index); |
| 1883 | const main_token = tree.nodes.items(.main_token)[node]; | 1838 | const main_token = tree.nodeMainToken(node); |
| 1884 | return tree.fullContainerDeclComponents(.{ | 1839 | return tree.fullContainerDeclComponents(.{ |
| 1885 | .main_token = main_token, | 1840 | .main_token = main_token, |
| 1886 | .enum_token = main_token + 2, // union lparen enum | 1841 | .enum_token = main_token + 2, // union lparen enum |
| 1887 | .members = tree.extra_data[data.lhs..data.rhs], | 1842 | .members = members, |
| 1888 | .arg = 0, | 1843 | .arg = .none, |
| 1889 | }); | 1844 | }); |
| 1890 | } | 1845 | } |
| 1891 | 1846 | ||
| 1892 | pub fn taggedUnionEnumTag(tree: Ast, node: Node.Index) full.ContainerDecl { | 1847 | pub fn taggedUnionEnumTag(tree: Ast, node: Node.Index) full.ContainerDecl { |
| 1893 | assert(tree.nodes.items(.tag)[node] == .tagged_union_enum_tag or | 1848 | assert(tree.nodeTag(node) == .tagged_union_enum_tag or |
| 1894 | tree.nodes.items(.tag)[node] == .tagged_union_enum_tag_trailing); | 1849 | tree.nodeTag(node) == .tagged_union_enum_tag_trailing); |
| 1895 | const data = tree.nodes.items(.data)[node]; | 1850 | const arg, const extra_index = tree.nodeData(node).node_and_extra; |
| 1896 | const members_range = tree.extraData(data.rhs, Node.SubRange); | 1851 | const members = tree.extraDataSlice(tree.extraData(extra_index, Node.SubRange), Node.Index); |
| 1897 | const main_token = tree.nodes.items(.main_token)[node]; | 1852 | const main_token = tree.nodeMainToken(node); |
| 1898 | return tree.fullContainerDeclComponents(.{ | 1853 | return tree.fullContainerDeclComponents(.{ |
| 1899 | .main_token = main_token, | 1854 | .main_token = main_token, |
| 1900 | .enum_token = main_token + 2, // union lparen enum | 1855 | .enum_token = main_token + 2, // union lparen enum |
| 1901 | .members = tree.extra_data[members_range.start..members_range.end], | 1856 | .members = members, |
| 1902 | .arg = data.lhs, | 1857 | .arg = arg.toOptional(), |
| 1903 | }); | 1858 | }); |
| 1904 | } | 1859 | } |
| 1905 | 1860 | ||
| 1906 | pub fn switchFull(tree: Ast, node: Node.Index) full.Switch { | 1861 | pub fn switchFull(tree: Ast, node: Node.Index) full.Switch { |
| 1907 | const data = &tree.nodes.items(.data)[node]; | 1862 | const main_token = tree.nodeMainToken(node); |
| 1908 | const main_token = tree.nodes.items(.main_token)[node]; | 1863 | const switch_token: TokenIndex, const label_token: ?TokenIndex = switch (tree.tokenTag(main_token)) { |
| 1909 | const switch_token: TokenIndex, const label_token: ?TokenIndex = switch (tree.tokens.items(.tag)[main_token]) { | ||
| 1910 | .identifier => .{ main_token + 2, main_token }, | 1864 | .identifier => .{ main_token + 2, main_token }, |
| 1911 | .keyword_switch => .{ main_token, null }, | 1865 | .keyword_switch => .{ main_token, null }, |
| 1912 | else => unreachable, | 1866 | else => unreachable, |
| 1913 | }; | 1867 | }; |
| 1914 | const extra = tree.extraData(data.rhs, Ast.Node.SubRange); | 1868 | const condition, const extra_index = tree.nodeData(node).node_and_extra; |
| 1869 | const cases = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Node.Index); | ||
| 1915 | return .{ | 1870 | return .{ |
| 1916 | .ast = .{ | 1871 | .ast = .{ |
| 1917 | .switch_token = switch_token, | 1872 | .switch_token = switch_token, |
| 1918 | .condition = data.lhs, | 1873 | .condition = condition, |
| 1919 | .cases = tree.extra_data[extra.start..extra.end], | 1874 | .cases = cases, |
| 1920 | }, | 1875 | }, |
| 1921 | .label_token = label_token, | 1876 | .label_token = label_token, |
| 1922 | }; | 1877 | }; |
| 1923 | } | 1878 | } |
| 1924 | 1879 | ||
| 1925 | pub fn switchCaseOne(tree: Ast, node: Node.Index) full.SwitchCase { | 1880 | pub fn switchCaseOne(tree: Ast, node: Node.Index) full.SwitchCase { |
| 1926 | const data = &tree.nodes.items(.data)[node]; | 1881 | const first_value, const target_expr = tree.nodeData(node).opt_node_and_node; |
| 1927 | const values: *[1]Node.Index = &data.lhs; | ||
| 1928 | return tree.fullSwitchCaseComponents(.{ | 1882 | return tree.fullSwitchCaseComponents(.{ |
| 1929 | .values = if (data.lhs == 0) values[0..0] else values[0..1], | 1883 | .values = if (first_value == .none) |
| 1930 | .arrow_token = tree.nodes.items(.main_token)[node], | 1884 | &.{} |
| 1931 | .target_expr = data.rhs, | 1885 | else |
| 1886 | // Ensure that the returned slice points into the existing memory of the Ast | ||
| 1887 | (@as(*const Node.Index, @ptrCast(&tree.nodes.items(.data)[@intFromEnum(node)].opt_node_and_node[0])))[0..1], | ||
| 1888 | .arrow_token = tree.nodeMainToken(node), | ||
| 1889 | .target_expr = target_expr, | ||
| 1932 | }, node); | 1890 | }, node); |
| 1933 | } | 1891 | } |
| 1934 | 1892 | ||
| 1935 | pub fn switchCase(tree: Ast, node: Node.Index) full.SwitchCase { | 1893 | pub fn switchCase(tree: Ast, node: Node.Index) full.SwitchCase { |
| 1936 | const data = tree.nodes.items(.data)[node]; | 1894 | const extra_index, const target_expr = tree.nodeData(node).extra_and_node; |
| 1937 | const extra = tree.extraData(data.lhs, Node.SubRange); | 1895 | const values = tree.extraDataSlice(tree.extraData(extra_index, Node.SubRange), Node.Index); |
| 1938 | return tree.fullSwitchCaseComponents(.{ | 1896 | return tree.fullSwitchCaseComponents(.{ |
| 1939 | .values = tree.extra_data[extra.start..extra.end], | 1897 | .values = values, |
| 1940 | .arrow_token = tree.nodes.items(.main_token)[node], | 1898 | .arrow_token = tree.nodeMainToken(node), |
| 1941 | .target_expr = data.rhs, | 1899 | .target_expr = target_expr, |
| 1942 | }, node); | 1900 | }, node); |
| 1943 | } | 1901 | } |
| 1944 | 1902 | ||
| 1945 | pub fn asmSimple(tree: Ast, node: Node.Index) full.Asm { | 1903 | pub fn asmSimple(tree: Ast, node: Node.Index) full.Asm { |
| 1946 | const data = tree.nodes.items(.data)[node]; | 1904 | const template, const rparen = tree.nodeData(node).node_and_token; |
| 1947 | return tree.fullAsmComponents(.{ | 1905 | return tree.fullAsmComponents(.{ |
| 1948 | .asm_token = tree.nodes.items(.main_token)[node], | 1906 | .asm_token = tree.nodeMainToken(node), |
| 1949 | .template = data.lhs, | 1907 | .template = template, |
| 1950 | .items = &.{}, | 1908 | .items = &.{}, |
| 1951 | .rparen = data.rhs, | 1909 | .rparen = rparen, |
| 1952 | }); | 1910 | }); |
| 1953 | } | 1911 | } |
| 1954 | 1912 | ||
| 1955 | pub fn asmFull(tree: Ast, node: Node.Index) full.Asm { | 1913 | pub fn asmFull(tree: Ast, node: Node.Index) full.Asm { |
| 1956 | const data = tree.nodes.items(.data)[node]; | 1914 | const template, const extra_index = tree.nodeData(node).node_and_extra; |
| 1957 | const extra = tree.extraData(data.rhs, Node.Asm); | 1915 | const extra = tree.extraData(extra_index, Node.Asm); |
| 1916 | const items = tree.extraDataSlice(.{ .start = extra.items_start, .end = extra.items_end }, Node.Index); | ||
| 1958 | return tree.fullAsmComponents(.{ | 1917 | return tree.fullAsmComponents(.{ |
| 1959 | .asm_token = tree.nodes.items(.main_token)[node], | 1918 | .asm_token = tree.nodeMainToken(node), |
| 1960 | .template = data.lhs, | 1919 | .template = template, |
| 1961 | .items = tree.extra_data[extra.items_start..extra.items_end], | 1920 | .items = items, |
| 1962 | .rparen = extra.rparen, | 1921 | .rparen = extra.rparen, |
| 1963 | }); | 1922 | }); |
| 1964 | } | 1923 | } |
| 1965 | 1924 | ||
| 1966 | pub fn whileSimple(tree: Ast, node: Node.Index) full.While { | 1925 | pub fn whileSimple(tree: Ast, node: Node.Index) full.While { |
| 1967 | const data = tree.nodes.items(.data)[node]; | 1926 | const cond_expr, const then_expr = tree.nodeData(node).node_and_node; |
| 1968 | return tree.fullWhileComponents(.{ | 1927 | return tree.fullWhileComponents(.{ |
| 1969 | .while_token = tree.nodes.items(.main_token)[node], | 1928 | .while_token = tree.nodeMainToken(node), |
| 1970 | .cond_expr = data.lhs, | 1929 | .cond_expr = cond_expr, |
| 1971 | .cont_expr = 0, | 1930 | .cont_expr = .none, |
| 1972 | .then_expr = data.rhs, | 1931 | .then_expr = then_expr, |
| 1973 | .else_expr = 0, | 1932 | .else_expr = .none, |
| 1974 | }); | 1933 | }); |
| 1975 | } | 1934 | } |
| 1976 | 1935 | ||
| 1977 | pub fn whileCont(tree: Ast, node: Node.Index) full.While { | 1936 | pub fn whileCont(tree: Ast, node: Node.Index) full.While { |
| 1978 | const data = tree.nodes.items(.data)[node]; | 1937 | const cond_expr, const extra_index = tree.nodeData(node).node_and_extra; |
| 1979 | const extra = tree.extraData(data.rhs, Node.WhileCont); | 1938 | const extra = tree.extraData(extra_index, Node.WhileCont); |
| 1980 | return tree.fullWhileComponents(.{ | 1939 | return tree.fullWhileComponents(.{ |
| 1981 | .while_token = tree.nodes.items(.main_token)[node], | 1940 | .while_token = tree.nodeMainToken(node), |
| 1982 | .cond_expr = data.lhs, | 1941 | .cond_expr = cond_expr, |
| 1983 | .cont_expr = extra.cont_expr, | 1942 | .cont_expr = extra.cont_expr.toOptional(), |
| 1984 | .then_expr = extra.then_expr, | 1943 | .then_expr = extra.then_expr, |
| 1985 | .else_expr = 0, | 1944 | .else_expr = .none, |
| 1986 | }); | 1945 | }); |
| 1987 | } | 1946 | } |
| 1988 | 1947 | ||
| 1989 | pub fn whileFull(tree: Ast, node: Node.Index) full.While { | 1948 | pub fn whileFull(tree: Ast, node: Node.Index) full.While { |
| 1990 | const data = tree.nodes.items(.data)[node]; | 1949 | const cond_expr, const extra_index = tree.nodeData(node).node_and_extra; |
| 1991 | const extra = tree.extraData(data.rhs, Node.While); | 1950 | const extra = tree.extraData(extra_index, Node.While); |
| 1992 | return tree.fullWhileComponents(.{ | 1951 | return tree.fullWhileComponents(.{ |
| 1993 | .while_token = tree.nodes.items(.main_token)[node], | 1952 | .while_token = tree.nodeMainToken(node), |
| 1994 | .cond_expr = data.lhs, | 1953 | .cond_expr = cond_expr, |
| 1995 | .cont_expr = extra.cont_expr, | 1954 | .cont_expr = extra.cont_expr, |
| 1996 | .then_expr = extra.then_expr, | 1955 | .then_expr = extra.then_expr, |
| 1997 | .else_expr = extra.else_expr, | 1956 | .else_expr = extra.else_expr.toOptional(), |
| 1998 | }); | 1957 | }); |
| 1999 | } | 1958 | } |
| 2000 | 1959 | ||
| 2001 | pub fn forSimple(tree: Ast, node: Node.Index) full.For { | 1960 | pub fn forSimple(tree: Ast, node: Node.Index) full.For { |
| 2002 | const data = &tree.nodes.items(.data)[node]; | 1961 | const data = &tree.nodes.items(.data)[@intFromEnum(node)].node_and_node; |
| 2003 | const inputs: *[1]Node.Index = &data.lhs; | ||
| 2004 | return tree.fullForComponents(.{ | 1962 | return tree.fullForComponents(.{ |
| 2005 | .for_token = tree.nodes.items(.main_token)[node], | 1963 | .for_token = tree.nodeMainToken(node), |
| 2006 | .inputs = inputs[0..1], | 1964 | .inputs = (&data[0])[0..1], |
| 2007 | .then_expr = data.rhs, | 1965 | .then_expr = data[1], |
| 2008 | .else_expr = 0, | 1966 | .else_expr = .none, |
| 2009 | }); | 1967 | }); |
| 2010 | } | 1968 | } |
| 2011 | 1969 | ||
| 2012 | pub fn forFull(tree: Ast, node: Node.Index) full.For { | 1970 | pub fn forFull(tree: Ast, node: Node.Index) full.For { |
| 2013 | const data = tree.nodes.items(.data)[node]; | 1971 | const extra_index, const extra = tree.nodeData(node).@"for"; |
| 2014 | const extra = @as(Node.For, @bitCast(data.rhs)); | 1972 | const inputs = tree.extraDataSliceWithLen(extra_index, extra.inputs, Node.Index); |
| 2015 | const inputs = tree.extra_data[data.lhs..][0..extra.inputs]; | 1973 | const then_expr: Node.Index = @enumFromInt(tree.extra_data[@intFromEnum(extra_index) + extra.inputs]); |
| 2016 | const then_expr = tree.extra_data[data.lhs + extra.inputs]; | 1974 | const else_expr: Node.OptionalIndex = if (extra.has_else) @enumFromInt(tree.extra_data[@intFromEnum(extra_index) + extra.inputs + 1]) else .none; |
| 2017 | const else_expr = if (extra.has_else) tree.extra_data[data.lhs + extra.inputs + 1] else 0; | ||
| 2018 | return tree.fullForComponents(.{ | 1975 | return tree.fullForComponents(.{ |
| 2019 | .for_token = tree.nodes.items(.main_token)[node], | 1976 | .for_token = tree.nodeMainToken(node), |
| 2020 | .inputs = inputs, | 1977 | .inputs = inputs, |
| 2021 | .then_expr = then_expr, | 1978 | .then_expr = then_expr, |
| 2022 | .else_expr = else_expr, | 1979 | .else_expr = else_expr, |
| ... | @@ -2024,28 +1981,26 @@ pub fn forFull(tree: Ast, node: Node.Index) full.For { | ... | @@ -2024,28 +1981,26 @@ pub fn forFull(tree: Ast, node: Node.Index) full.For { |
| 2024 | } | 1981 | } |
| 2025 | 1982 | ||
| 2026 | pub fn callOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.Call { | 1983 | pub fn callOne(tree: Ast, buffer: *[1]Node.Index, node: Node.Index) full.Call { |
| 2027 | const data = tree.nodes.items(.data)[node]; | 1984 | const fn_expr, const first_param = tree.nodeData(node).node_and_opt_node; |
| 2028 | buffer.* = .{data.rhs}; | 1985 | const params = loadOptionalNodesIntoBuffer(1, buffer, .{first_param}); |
| 2029 | const params = if (data.rhs != 0) buffer[0..1] else buffer[0..0]; | ||
| 2030 | return tree.fullCallComponents(.{ | 1986 | return tree.fullCallComponents(.{ |
| 2031 | .lparen = tree.nodes.items(.main_token)[node], | 1987 | .lparen = tree.nodeMainToken(node), |
| 2032 | .fn_expr = data.lhs, | 1988 | .fn_expr = fn_expr, |
| 2033 | .params = params, | 1989 | .params = params, |
| 2034 | }); | 1990 | }); |
| 2035 | } | 1991 | } |
| 2036 | 1992 | ||
| 2037 | pub fn callFull(tree: Ast, node: Node.Index) full.Call { | 1993 | pub fn callFull(tree: Ast, node: Node.Index) full.Call { |
| 2038 | const data = tree.nodes.items(.data)[node]; | 1994 | const fn_expr, const extra_index = tree.nodeData(node).node_and_extra; |
| 2039 | const extra = tree.extraData(data.rhs, Node.SubRange); | 1995 | const params = tree.extraDataSlice(tree.extraData(extra_index, Node.SubRange), Node.Index); |
| 2040 | return tree.fullCallComponents(.{ | 1996 | return tree.fullCallComponents(.{ |
| 2041 | .lparen = tree.nodes.items(.main_token)[node], | 1997 | .lparen = tree.nodeMainToken(node), |
| 2042 | .fn_expr = data.lhs, | 1998 | .fn_expr = fn_expr, |
| 2043 | .params = tree.extra_data[extra.start..extra.end], | 1999 | .params = params, |
| 2044 | }); | 2000 | }); |
| 2045 | } | 2001 | } |
| 2046 | 2002 | ||
| 2047 | fn fullVarDeclComponents(tree: Ast, info: full.VarDecl.Components) full.VarDecl { | 2003 | fn fullVarDeclComponents(tree: Ast, info: full.VarDecl.Components) full.VarDecl { |
| 2048 | const token_tags = tree.tokens.items(.tag); | ||
| 2049 | var result: full.VarDecl = .{ | 2004 | var result: full.VarDecl = .{ |
| 2050 | .ast = info, | 2005 | .ast = info, |
| 2051 | .visib_token = null, | 2006 | .visib_token = null, |
| ... | @@ -2057,7 +2012,7 @@ fn fullVarDeclComponents(tree: Ast, info: full.VarDecl.Components) full.VarDecl | ... | @@ -2057,7 +2012,7 @@ fn fullVarDeclComponents(tree: Ast, info: full.VarDecl.Components) full.VarDecl |
| 2057 | var i = info.mut_token; | 2012 | var i = info.mut_token; |
| 2058 | while (i > 0) { | 2013 | while (i > 0) { |
| 2059 | i -= 1; | 2014 | i -= 1; |
| 2060 | switch (token_tags[i]) { | 2015 | switch (tree.tokenTag(i)) { |
| 2061 | .keyword_extern, .keyword_export => result.extern_export_token = i, | 2016 | .keyword_extern, .keyword_export => result.extern_export_token = i, |
| 2062 | .keyword_comptime => result.comptime_token = i, | 2017 | .keyword_comptime => result.comptime_token = i, |
| 2063 | .keyword_pub => result.visib_token = i, | 2018 | .keyword_pub => result.visib_token = i, |
| ... | @@ -2070,14 +2025,12 @@ fn fullVarDeclComponents(tree: Ast, info: full.VarDecl.Components) full.VarDecl | ... | @@ -2070,14 +2025,12 @@ fn fullVarDeclComponents(tree: Ast, info: full.VarDecl.Components) full.VarDecl |
| 2070 | } | 2025 | } |
| 2071 | 2026 | ||
| 2072 | fn fullAssignDestructureComponents(tree: Ast, info: full.AssignDestructure.Components) full.AssignDestructure { | 2027 | fn fullAssignDestructureComponents(tree: Ast, info: full.AssignDestructure.Components) full.AssignDestructure { |
| 2073 | const token_tags = tree.tokens.items(.tag); | ||
| 2074 | const node_tags = tree.nodes.items(.tag); | ||
| 2075 | var result: full.AssignDestructure = .{ | 2028 | var result: full.AssignDestructure = .{ |
| 2076 | .comptime_token = null, | 2029 | .comptime_token = null, |
| 2077 | .ast = info, | 2030 | .ast = info, |
| 2078 | }; | 2031 | }; |
| 2079 | const first_variable_token = tree.firstToken(info.variables[0]); | 2032 | const first_variable_token = tree.firstToken(info.variables[0]); |
| 2080 | const maybe_comptime_token = switch (node_tags[info.variables[0]]) { | 2033 | const maybe_comptime_token = switch (tree.nodeTag(info.variables[0])) { |
| 2081 | .global_var_decl, | 2034 | .global_var_decl, |
| 2082 | .local_var_decl, | 2035 | .local_var_decl, |
| 2083 | .aligned_var_decl, | 2036 | .aligned_var_decl, |
| ... | @@ -2085,14 +2038,13 @@ fn fullAssignDestructureComponents(tree: Ast, info: full.AssignDestructure.Compo | ... | @@ -2085,14 +2038,13 @@ fn fullAssignDestructureComponents(tree: Ast, info: full.AssignDestructure.Compo |
| 2085 | => first_variable_token, | 2038 | => first_variable_token, |
| 2086 | else => first_variable_token - 1, | 2039 | else => first_variable_token - 1, |
| 2087 | }; | 2040 | }; |
| 2088 | if (token_tags[maybe_comptime_token] == .keyword_comptime) { | 2041 | if (tree.tokenTag(maybe_comptime_token) == .keyword_comptime) { |
| 2089 | result.comptime_token = maybe_comptime_token; | 2042 | result.comptime_token = maybe_comptime_token; |
| 2090 | } | 2043 | } |
| 2091 | return result; | 2044 | return result; |
| 2092 | } | 2045 | } |
| 2093 | 2046 | ||
| 2094 | fn fullIfComponents(tree: Ast, info: full.If.Components) full.If { | 2047 | fn fullIfComponents(tree: Ast, info: full.If.Components) full.If { |
| 2095 | const token_tags = tree.tokens.items(.tag); | ||
| 2096 | var result: full.If = .{ | 2048 | var result: full.If = .{ |
| 2097 | .ast = info, | 2049 | .ast = info, |
| 2098 | .payload_token = null, | 2050 | .payload_token = null, |
| ... | @@ -2102,14 +2054,14 @@ fn fullIfComponents(tree: Ast, info: full.If.Components) full.If { | ... | @@ -2102,14 +2054,14 @@ fn fullIfComponents(tree: Ast, info: full.If.Components) full.If { |
| 2102 | // if (cond_expr) |x| | 2054 | // if (cond_expr) |x| |
| 2103 | // ^ ^ | 2055 | // ^ ^ |
| 2104 | const payload_pipe = tree.lastToken(info.cond_expr) + 2; | 2056 | const payload_pipe = tree.lastToken(info.cond_expr) + 2; |
| 2105 | if (token_tags[payload_pipe] == .pipe) { | 2057 | if (tree.tokenTag(payload_pipe) == .pipe) { |
| 2106 | result.payload_token = payload_pipe + 1; | 2058 | result.payload_token = payload_pipe + 1; |
| 2107 | } | 2059 | } |
| 2108 | if (info.else_expr != 0) { | 2060 | if (info.else_expr != .none) { |
| 2109 | // then_expr else |x| | 2061 | // then_expr else |x| |
| 2110 | // ^ ^ | 2062 | // ^ ^ |
| 2111 | result.else_token = tree.lastToken(info.then_expr) + 1; | 2063 | result.else_token = tree.lastToken(info.then_expr) + 1; |
| 2112 | if (token_tags[result.else_token + 1] == .pipe) { | 2064 | if (tree.tokenTag(result.else_token + 1) == .pipe) { |
| 2113 | result.error_token = result.else_token + 2; | 2065 | result.error_token = result.else_token + 2; |
| 2114 | } | 2066 | } |
| 2115 | } | 2067 | } |
| ... | @@ -2117,12 +2069,11 @@ fn fullIfComponents(tree: Ast, info: full.If.Components) full.If { | ... | @@ -2117,12 +2069,11 @@ fn fullIfComponents(tree: Ast, info: full.If.Components) full.If { |
| 2117 | } | 2069 | } |
| 2118 | 2070 | ||
| 2119 | fn fullContainerFieldComponents(tree: Ast, info: full.ContainerField.Components) full.ContainerField { | 2071 | fn fullContainerFieldComponents(tree: Ast, info: full.ContainerField.Components) full.ContainerField { |
| 2120 | const token_tags = tree.tokens.items(.tag); | ||
| 2121 | var result: full.ContainerField = .{ | 2072 | var result: full.ContainerField = .{ |
| 2122 | .ast = info, | 2073 | .ast = info, |
| 2123 | .comptime_token = null, | 2074 | .comptime_token = null, |
| 2124 | }; | 2075 | }; |
| 2125 | if (info.main_token > 0 and token_tags[info.main_token - 1] == .keyword_comptime) { | 2076 | if (tree.isTokenPrecededByTags(info.main_token, &.{.keyword_comptime})) { |
| 2126 | // comptime type = init, | 2077 | // comptime type = init, |
| 2127 | // ^ ^ | 2078 | // ^ ^ |
| 2128 | // comptime name: type = init, | 2079 | // comptime name: type = init, |
| ... | @@ -2133,7 +2084,6 @@ fn fullContainerFieldComponents(tree: Ast, info: full.ContainerField.Components) | ... | @@ -2133,7 +2084,6 @@ fn fullContainerFieldComponents(tree: Ast, info: full.ContainerField.Components) |
| 2133 | } | 2084 | } |
| 2134 | 2085 | ||
| 2135 | fn fullFnProtoComponents(tree: Ast, info: full.FnProto.Components) full.FnProto { | 2086 | fn fullFnProtoComponents(tree: Ast, info: full.FnProto.Components) full.FnProto { |
| 2136 | const token_tags = tree.tokens.items(.tag); | ||
| 2137 | var result: full.FnProto = .{ | 2087 | var result: full.FnProto = .{ |
| 2138 | .ast = info, | 2088 | .ast = info, |
| 2139 | .visib_token = null, | 2089 | .visib_token = null, |
| ... | @@ -2145,7 +2095,7 @@ fn fullFnProtoComponents(tree: Ast, info: full.FnProto.Components) full.FnProto | ... | @@ -2145,7 +2095,7 @@ fn fullFnProtoComponents(tree: Ast, info: full.FnProto.Components) full.FnProto |
| 2145 | var i = info.fn_token; | 2095 | var i = info.fn_token; |
| 2146 | while (i > 0) { | 2096 | while (i > 0) { |
| 2147 | i -= 1; | 2097 | i -= 1; |
| 2148 | switch (token_tags[i]) { | 2098 | switch (tree.tokenTag(i)) { |
| 2149 | .keyword_extern, | 2099 | .keyword_extern, |
| 2150 | .keyword_export, | 2100 | .keyword_export, |
| 2151 | .keyword_inline, | 2101 | .keyword_inline, |
| ... | @@ -2157,25 +2107,24 @@ fn fullFnProtoComponents(tree: Ast, info: full.FnProto.Components) full.FnProto | ... | @@ -2157,25 +2107,24 @@ fn fullFnProtoComponents(tree: Ast, info: full.FnProto.Components) full.FnProto |
| 2157 | } | 2107 | } |
| 2158 | } | 2108 | } |
| 2159 | const after_fn_token = info.fn_token + 1; | 2109 | const after_fn_token = info.fn_token + 1; |
| 2160 | if (token_tags[after_fn_token] == .identifier) { | 2110 | if (tree.tokenTag(after_fn_token) == .identifier) { |
| 2161 | result.name_token = after_fn_token; | 2111 | result.name_token = after_fn_token; |
| 2162 | result.lparen = after_fn_token + 1; | 2112 | result.lparen = after_fn_token + 1; |
| 2163 | } else { | 2113 | } else { |
| 2164 | result.lparen = after_fn_token; | 2114 | result.lparen = after_fn_token; |
| 2165 | } | 2115 | } |
| 2166 | assert(token_tags[result.lparen] == .l_paren); | 2116 | assert(tree.tokenTag(result.lparen) == .l_paren); |
| 2167 | 2117 | ||
| 2168 | return result; | 2118 | return result; |
| 2169 | } | 2119 | } |
| 2170 | 2120 | ||
| 2171 | fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType { | 2121 | fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType { |
| 2172 | const token_tags = tree.tokens.items(.tag); | 2122 | const size: std.builtin.Type.Pointer.Size = switch (tree.tokenTag(info.main_token)) { |
| 2173 | const size: std.builtin.Type.Pointer.Size = switch (token_tags[info.main_token]) { | ||
| 2174 | .asterisk, | 2123 | .asterisk, |
| 2175 | .asterisk_asterisk, | 2124 | .asterisk_asterisk, |
| 2176 | => .one, | 2125 | => .one, |
| 2177 | .l_bracket => switch (token_tags[info.main_token + 1]) { | 2126 | .l_bracket => switch (tree.tokenTag(info.main_token + 1)) { |
| 2178 | .asterisk => if (token_tags[info.main_token + 2] == .identifier) .c else .many, | 2127 | .asterisk => if (tree.tokenTag(info.main_token + 2) == .identifier) .c else .many, |
| 2179 | else => .slice, | 2128 | else => .slice, |
| 2180 | }, | 2129 | }, |
| 2181 | else => unreachable, | 2130 | else => unreachable, |
| ... | @@ -2191,23 +2140,23 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType | ... | @@ -2191,23 +2140,23 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType |
| 2191 | // here while looking for modifiers as that could result in false | 2140 | // here while looking for modifiers as that could result in false |
| 2192 | // positives. Therefore, start after a sentinel if there is one and | 2141 | // positives. Therefore, start after a sentinel if there is one and |
| 2193 | // skip over any align node and bit range nodes. | 2142 | // skip over any align node and bit range nodes. |
| 2194 | var i = if (info.sentinel != 0) tree.lastToken(info.sentinel) + 1 else switch (size) { | 2143 | var i = if (info.sentinel.unwrap()) |sentinel| tree.lastToken(sentinel) + 1 else switch (size) { |
| 2195 | .many, .c => info.main_token + 1, | 2144 | .many, .c => info.main_token + 1, |
| 2196 | else => info.main_token, | 2145 | else => info.main_token, |
| 2197 | }; | 2146 | }; |
| 2198 | const end = tree.firstToken(info.child_type); | 2147 | const end = tree.firstToken(info.child_type); |
| 2199 | while (i < end) : (i += 1) { | 2148 | while (i < end) : (i += 1) { |
| 2200 | switch (token_tags[i]) { | 2149 | switch (tree.tokenTag(i)) { |
| 2201 | .keyword_allowzero => result.allowzero_token = i, | 2150 | .keyword_allowzero => result.allowzero_token = i, |
| 2202 | .keyword_const => result.const_token = i, | 2151 | .keyword_const => result.const_token = i, |
| 2203 | .keyword_volatile => result.volatile_token = i, | 2152 | .keyword_volatile => result.volatile_token = i, |
| 2204 | .keyword_align => { | 2153 | .keyword_align => { |
| 2205 | assert(info.align_node != 0); | 2154 | const align_node = info.align_node.unwrap().?; |
| 2206 | if (info.bit_range_end != 0) { | 2155 | if (info.bit_range_end.unwrap()) |bit_range_end| { |
| 2207 | assert(info.bit_range_start != 0); | 2156 | assert(info.bit_range_start != .none); |
| 2208 | i = tree.lastToken(info.bit_range_end) + 1; | 2157 | i = tree.lastToken(bit_range_end) + 1; |
| 2209 | } else { | 2158 | } else { |
| 2210 | i = tree.lastToken(info.align_node) + 1; | 2159 | i = tree.lastToken(align_node) + 1; |
| 2211 | } | 2160 | } |
| 2212 | }, | 2161 | }, |
| 2213 | else => {}, | 2162 | else => {}, |
| ... | @@ -2217,30 +2166,29 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType | ... | @@ -2217,30 +2166,29 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType |
| 2217 | } | 2166 | } |
| 2218 | 2167 | ||
| 2219 | fn fullContainerDeclComponents(tree: Ast, info: full.ContainerDecl.Components) full.ContainerDecl { | 2168 | fn fullContainerDeclComponents(tree: Ast, info: full.ContainerDecl.Components) full.ContainerDecl { |
| 2220 | const token_tags = tree.tokens.items(.tag); | ||
| 2221 | var result: full.ContainerDecl = .{ | 2169 | var result: full.ContainerDecl = .{ |
| 2222 | .ast = info, | 2170 | .ast = info, |
| 2223 | .layout_token = null, | 2171 | .layout_token = null, |
| 2224 | }; | 2172 | }; |
| 2225 | 2173 | ||
| 2226 | if (info.main_token == 0) return result; | 2174 | if (info.main_token == 0) return result; // .root |
| 2175 | const previous_token = info.main_token - 1; | ||
| 2227 | 2176 | ||
| 2228 | switch (token_tags[info.main_token - 1]) { | 2177 | switch (tree.tokenTag(previous_token)) { |
| 2229 | .keyword_extern, .keyword_packed => result.layout_token = info.main_token - 1, | 2178 | .keyword_extern, .keyword_packed => result.layout_token = previous_token, |
| 2230 | else => {}, | 2179 | else => {}, |
| 2231 | } | 2180 | } |
| 2232 | return result; | 2181 | return result; |
| 2233 | } | 2182 | } |
| 2234 | 2183 | ||
| 2235 | fn fullSwitchComponents(tree: Ast, info: full.Switch.Components) full.Switch { | 2184 | fn fullSwitchComponents(tree: Ast, info: full.Switch.Components) full.Switch { |
| 2236 | const token_tags = tree.tokens.items(.tag); | ||
| 2237 | const tok_i = info.switch_token -| 1; | 2185 | const tok_i = info.switch_token -| 1; |
| 2238 | var result: full.Switch = .{ | 2186 | var result: full.Switch = .{ |
| 2239 | .ast = info, | 2187 | .ast = info, |
| 2240 | .label_token = null, | 2188 | .label_token = null, |
| 2241 | }; | 2189 | }; |
| 2242 | if (token_tags[tok_i] == .colon and | 2190 | if (tree.tokenTag(tok_i) == .colon and |
| 2243 | token_tags[tok_i -| 1] == .identifier) | 2191 | tree.tokenTag(tok_i -| 1) == .identifier) |
| 2244 | { | 2192 | { |
| 2245 | result.label_token = tok_i - 1; | 2193 | result.label_token = tok_i - 1; |
| 2246 | } | 2194 | } |
| ... | @@ -2248,26 +2196,25 @@ fn fullSwitchComponents(tree: Ast, info: full.Switch.Components) full.Switch { | ... | @@ -2248,26 +2196,25 @@ fn fullSwitchComponents(tree: Ast, info: full.Switch.Components) full.Switch { |
| 2248 | } | 2196 | } |
| 2249 | 2197 | ||
| 2250 | fn fullSwitchCaseComponents(tree: Ast, info: full.SwitchCase.Components, node: Node.Index) full.SwitchCase { | 2198 | fn fullSwitchCaseComponents(tree: Ast, info: full.SwitchCase.Components, node: Node.Index) full.SwitchCase { |
| 2251 | const token_tags = tree.tokens.items(.tag); | ||
| 2252 | const node_tags = tree.nodes.items(.tag); | ||
| 2253 | var result: full.SwitchCase = .{ | 2199 | var result: full.SwitchCase = .{ |
| 2254 | .ast = info, | 2200 | .ast = info, |
| 2255 | .payload_token = null, | 2201 | .payload_token = null, |
| 2256 | .inline_token = null, | 2202 | .inline_token = null, |
| 2257 | }; | 2203 | }; |
| 2258 | if (token_tags[info.arrow_token + 1] == .pipe) { | 2204 | if (tree.tokenTag(info.arrow_token + 1) == .pipe) { |
| 2259 | result.payload_token = info.arrow_token + 2; | 2205 | result.payload_token = info.arrow_token + 2; |
| 2260 | } | 2206 | } |
| 2261 | switch (node_tags[node]) { | 2207 | result.inline_token = switch (tree.nodeTag(node)) { |
| 2262 | .switch_case_inline, .switch_case_inline_one => result.inline_token = firstToken(tree, node), | 2208 | .switch_case_inline, .switch_case_inline_one => if (result.ast.values.len == 0) |
| 2263 | else => {}, | 2209 | info.arrow_token - 2 |
| 2264 | } | 2210 | else |
| 2211 | tree.firstToken(result.ast.values[0]) - 1, | ||
| 2212 | else => null, | ||
| 2213 | }; | ||
| 2265 | return result; | 2214 | return result; |
| 2266 | } | 2215 | } |
| 2267 | 2216 | ||
| 2268 | fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { | 2217 | fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { |
| 2269 | const token_tags = tree.tokens.items(.tag); | ||
| 2270 | const node_tags = tree.nodes.items(.tag); | ||
| 2271 | var result: full.Asm = .{ | 2218 | var result: full.Asm = .{ |
| 2272 | .ast = info, | 2219 | .ast = info, |
| 2273 | .volatile_token = null, | 2220 | .volatile_token = null, |
| ... | @@ -2275,11 +2222,11 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { | ... | @@ -2275,11 +2222,11 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { |
| 2275 | .outputs = &.{}, | 2222 | .outputs = &.{}, |
| 2276 | .first_clobber = null, | 2223 | .first_clobber = null, |
| 2277 | }; | 2224 | }; |
| 2278 | if (token_tags[info.asm_token + 1] == .keyword_volatile) { | 2225 | if (tree.tokenTag(info.asm_token + 1) == .keyword_volatile) { |
| 2279 | result.volatile_token = info.asm_token + 1; | 2226 | result.volatile_token = info.asm_token + 1; |
| 2280 | } | 2227 | } |
| 2281 | const outputs_end: usize = for (info.items, 0..) |item, i| { | 2228 | const outputs_end: usize = for (info.items, 0..) |item, i| { |
| 2282 | switch (node_tags[item]) { | 2229 | switch (tree.nodeTag(item)) { |
| 2283 | .asm_output => continue, | 2230 | .asm_output => continue, |
| 2284 | else => break i, | 2231 | else => break i, |
| 2285 | } | 2232 | } |
| ... | @@ -2291,10 +2238,10 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { | ... | @@ -2291,10 +2238,10 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { |
| 2291 | if (info.items.len == 0) { | 2238 | if (info.items.len == 0) { |
| 2292 | // asm ("foo" ::: "a", "b"); | 2239 | // asm ("foo" ::: "a", "b"); |
| 2293 | const template_token = tree.lastToken(info.template); | 2240 | const template_token = tree.lastToken(info.template); |
| 2294 | if (token_tags[template_token + 1] == .colon and | 2241 | if (tree.tokenTag(template_token + 1) == .colon and |
| 2295 | token_tags[template_token + 2] == .colon and | 2242 | tree.tokenTag(template_token + 2) == .colon and |
| 2296 | token_tags[template_token + 3] == .colon and | 2243 | tree.tokenTag(template_token + 3) == .colon and |
| 2297 | token_tags[template_token + 4] == .string_literal) | 2244 | tree.tokenTag(template_token + 4) == .string_literal) |
| 2298 | { | 2245 | { |
| 2299 | result.first_clobber = template_token + 4; | 2246 | result.first_clobber = template_token + 4; |
| 2300 | } | 2247 | } |
| ... | @@ -2304,9 +2251,9 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { | ... | @@ -2304,9 +2251,9 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { |
| 2304 | const rparen = tree.lastToken(last_input); | 2251 | const rparen = tree.lastToken(last_input); |
| 2305 | var i = rparen + 1; | 2252 | var i = rparen + 1; |
| 2306 | // Allow a (useless) comma right after the closing parenthesis. | 2253 | // Allow a (useless) comma right after the closing parenthesis. |
| 2307 | if (token_tags[i] == .comma) i += 1; | 2254 | if (tree.tokenTag(i) == .comma) i = i + 1; |
| 2308 | if (token_tags[i] == .colon and | 2255 | if (tree.tokenTag(i) == .colon and |
| 2309 | token_tags[i + 1] == .string_literal) | 2256 | tree.tokenTag(i + 1) == .string_literal) |
| 2310 | { | 2257 | { |
| 2311 | result.first_clobber = i + 1; | 2258 | result.first_clobber = i + 1; |
| 2312 | } | 2259 | } |
| ... | @@ -2316,10 +2263,10 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { | ... | @@ -2316,10 +2263,10 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { |
| 2316 | const rparen = tree.lastToken(last_output); | 2263 | const rparen = tree.lastToken(last_output); |
| 2317 | var i = rparen + 1; | 2264 | var i = rparen + 1; |
| 2318 | // Allow a (useless) comma right after the closing parenthesis. | 2265 | // Allow a (useless) comma right after the closing parenthesis. |
| 2319 | if (token_tags[i] == .comma) i += 1; | 2266 | if (tree.tokenTag(i) == .comma) i = i + 1; |
| 2320 | if (token_tags[i] == .colon and | 2267 | if (tree.tokenTag(i) == .colon and |
| 2321 | token_tags[i + 1] == .colon and | 2268 | tree.tokenTag(i + 1) == .colon and |
| 2322 | token_tags[i + 2] == .string_literal) | 2269 | tree.tokenTag(i + 2) == .string_literal) |
| 2323 | { | 2270 | { |
| 2324 | result.first_clobber = i + 2; | 2271 | result.first_clobber = i + 2; |
| 2325 | } | 2272 | } |
| ... | @@ -2329,7 +2276,6 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { | ... | @@ -2329,7 +2276,6 @@ fn fullAsmComponents(tree: Ast, info: full.Asm.Components) full.Asm { |
| 2329 | } | 2276 | } |
| 2330 | 2277 | ||
| 2331 | fn fullWhileComponents(tree: Ast, info: full.While.Components) full.While { | 2278 | fn fullWhileComponents(tree: Ast, info: full.While.Components) full.While { |
| 2332 | const token_tags = tree.tokens.items(.tag); | ||
| 2333 | var result: full.While = .{ | 2279 | var result: full.While = .{ |
| 2334 | .ast = info, | 2280 | .ast = info, |
| 2335 | .inline_token = null, | 2281 | .inline_token = null, |
| ... | @@ -2338,25 +2284,23 @@ fn fullWhileComponents(tree: Ast, info: full.While.Components) full.While { | ... | @@ -2338,25 +2284,23 @@ fn fullWhileComponents(tree: Ast, info: full.While.Components) full.While { |
| 2338 | .else_token = undefined, | 2284 | .else_token = undefined, |
| 2339 | .error_token = null, | 2285 | .error_token = null, |
| 2340 | }; | 2286 | }; |
| 2341 | var tok_i = info.while_token -| 1; | 2287 | var tok_i = info.while_token; |
| 2342 | if (token_tags[tok_i] == .keyword_inline) { | 2288 | if (tree.isTokenPrecededByTags(tok_i, &.{.keyword_inline})) { |
| 2343 | result.inline_token = tok_i; | 2289 | result.inline_token = tok_i - 1; |
| 2344 | tok_i -|= 1; | 2290 | tok_i = tok_i - 1; |
| 2345 | } | 2291 | } |
| 2346 | if (token_tags[tok_i] == .colon and | 2292 | if (tree.isTokenPrecededByTags(tok_i, &.{ .identifier, .colon })) { |
| 2347 | token_tags[tok_i -| 1] == .identifier) | 2293 | result.label_token = tok_i - 2; |
| 2348 | { | ||
| 2349 | result.label_token = tok_i - 1; | ||
| 2350 | } | 2294 | } |
| 2351 | const last_cond_token = tree.lastToken(info.cond_expr); | 2295 | const last_cond_token = tree.lastToken(info.cond_expr); |
| 2352 | if (token_tags[last_cond_token + 2] == .pipe) { | 2296 | if (tree.tokenTag(last_cond_token + 2) == .pipe) { |
| 2353 | result.payload_token = last_cond_token + 3; | 2297 | result.payload_token = last_cond_token + 3; |
| 2354 | } | 2298 | } |
| 2355 | if (info.else_expr != 0) { | 2299 | if (info.else_expr != .none) { |
| 2356 | // then_expr else |x| | 2300 | // then_expr else |x| |
| 2357 | // ^ ^ | 2301 | // ^ ^ |
| 2358 | result.else_token = tree.lastToken(info.then_expr) + 1; | 2302 | result.else_token = tree.lastToken(info.then_expr) + 1; |
| 2359 | if (token_tags[result.else_token + 1] == .pipe) { | 2303 | if (tree.tokenTag(result.else_token + 1) == .pipe) { |
| 2360 | result.error_token = result.else_token + 2; | 2304 | result.error_token = result.else_token + 2; |
| 2361 | } | 2305 | } |
| 2362 | } | 2306 | } |
| ... | @@ -2364,7 +2308,6 @@ fn fullWhileComponents(tree: Ast, info: full.While.Components) full.While { | ... | @@ -2364,7 +2308,6 @@ fn fullWhileComponents(tree: Ast, info: full.While.Components) full.While { |
| 2364 | } | 2308 | } |
| 2365 | 2309 | ||
| 2366 | fn fullForComponents(tree: Ast, info: full.For.Components) full.For { | 2310 | fn fullForComponents(tree: Ast, info: full.For.Components) full.For { |
| 2367 | const token_tags = tree.tokens.items(.tag); | ||
| 2368 | var result: full.For = .{ | 2311 | var result: full.For = .{ |
| 2369 | .ast = info, | 2312 | .ast = info, |
| 2370 | .inline_token = null, | 2313 | .inline_token = null, |
| ... | @@ -2372,39 +2315,36 @@ fn fullForComponents(tree: Ast, info: full.For.Components) full.For { | ... | @@ -2372,39 +2315,36 @@ fn fullForComponents(tree: Ast, info: full.For.Components) full.For { |
| 2372 | .payload_token = undefined, | 2315 | .payload_token = undefined, |
| 2373 | .else_token = undefined, | 2316 | .else_token = undefined, |
| 2374 | }; | 2317 | }; |
| 2375 | var tok_i = info.for_token -| 1; | 2318 | var tok_i = info.for_token; |
| 2376 | if (token_tags[tok_i] == .keyword_inline) { | 2319 | if (tree.isTokenPrecededByTags(tok_i, &.{.keyword_inline})) { |
| 2377 | result.inline_token = tok_i; | 2320 | result.inline_token = tok_i - 1; |
| 2378 | tok_i -|= 1; | 2321 | tok_i = tok_i - 1; |
| 2379 | } | 2322 | } |
| 2380 | if (token_tags[tok_i] == .colon and | 2323 | if (tree.isTokenPrecededByTags(tok_i, &.{ .identifier, .colon })) { |
| 2381 | token_tags[tok_i -| 1] == .identifier) | 2324 | result.label_token = tok_i - 2; |
| 2382 | { | ||
| 2383 | result.label_token = tok_i - 1; | ||
| 2384 | } | 2325 | } |
| 2385 | const last_cond_token = tree.lastToken(info.inputs[info.inputs.len - 1]); | 2326 | const last_cond_token = tree.lastToken(info.inputs[info.inputs.len - 1]); |
| 2386 | result.payload_token = last_cond_token + 3 + @intFromBool(token_tags[last_cond_token + 1] == .comma); | 2327 | result.payload_token = last_cond_token + @as(u32, 3) + @intFromBool(tree.tokenTag(last_cond_token + 1) == .comma); |
| 2387 | if (info.else_expr != 0) { | 2328 | if (info.else_expr != .none) { |
| 2388 | result.else_token = tree.lastToken(info.then_expr) + 1; | 2329 | result.else_token = tree.lastToken(info.then_expr) + 1; |
| 2389 | } | 2330 | } |
| 2390 | return result; | 2331 | return result; |
| 2391 | } | 2332 | } |
| 2392 | 2333 | ||
| 2393 | fn fullCallComponents(tree: Ast, info: full.Call.Components) full.Call { | 2334 | fn fullCallComponents(tree: Ast, info: full.Call.Components) full.Call { |
| 2394 | const token_tags = tree.tokens.items(.tag); | ||
| 2395 | var result: full.Call = .{ | 2335 | var result: full.Call = .{ |
| 2396 | .ast = info, | 2336 | .ast = info, |
| 2397 | .async_token = null, | 2337 | .async_token = null, |
| 2398 | }; | 2338 | }; |
| 2399 | const first_token = tree.firstToken(info.fn_expr); | 2339 | const first_token = tree.firstToken(info.fn_expr); |
| 2400 | if (first_token != 0 and token_tags[first_token - 1] == .keyword_async) { | 2340 | if (tree.isTokenPrecededByTags(first_token, &.{.keyword_async})) { |
| 2401 | result.async_token = first_token - 1; | 2341 | result.async_token = first_token - 1; |
| 2402 | } | 2342 | } |
| 2403 | return result; | 2343 | return result; |
| 2404 | } | 2344 | } |
| 2405 | 2345 | ||
| 2406 | pub fn fullVarDecl(tree: Ast, node: Node.Index) ?full.VarDecl { | 2346 | pub fn fullVarDecl(tree: Ast, node: Node.Index) ?full.VarDecl { |
| 2407 | return switch (tree.nodes.items(.tag)[node]) { | 2347 | return switch (tree.nodeTag(node)) { |
| 2408 | .global_var_decl => tree.globalVarDecl(node), | 2348 | .global_var_decl => tree.globalVarDecl(node), |
| 2409 | .local_var_decl => tree.localVarDecl(node), | 2349 | .local_var_decl => tree.localVarDecl(node), |
| 2410 | .aligned_var_decl => tree.alignedVarDecl(node), | 2350 | .aligned_var_decl => tree.alignedVarDecl(node), |
| ... | @@ -2414,7 +2354,7 @@ pub fn fullVarDecl(tree: Ast, node: Node.Index) ?full.VarDecl { | ... | @@ -2414,7 +2354,7 @@ pub fn fullVarDecl(tree: Ast, node: Node.Index) ?full.VarDecl { |
| 2414 | } | 2354 | } |
| 2415 | 2355 | ||
| 2416 | pub fn fullIf(tree: Ast, node: Node.Index) ?full.If { | 2356 | pub fn fullIf(tree: Ast, node: Node.Index) ?full.If { |
| 2417 | return switch (tree.nodes.items(.tag)[node]) { | 2357 | return switch (tree.nodeTag(node)) { |
| 2418 | .if_simple => tree.ifSimple(node), | 2358 | .if_simple => tree.ifSimple(node), |
| 2419 | .@"if" => tree.ifFull(node), | 2359 | .@"if" => tree.ifFull(node), |
| 2420 | else => null, | 2360 | else => null, |
| ... | @@ -2422,7 +2362,7 @@ pub fn fullIf(tree: Ast, node: Node.Index) ?full.If { | ... | @@ -2422,7 +2362,7 @@ pub fn fullIf(tree: Ast, node: Node.Index) ?full.If { |
| 2422 | } | 2362 | } |
| 2423 | 2363 | ||
| 2424 | pub fn fullWhile(tree: Ast, node: Node.Index) ?full.While { | 2364 | pub fn fullWhile(tree: Ast, node: Node.Index) ?full.While { |
| 2425 | return switch (tree.nodes.items(.tag)[node]) { | 2365 | return switch (tree.nodeTag(node)) { |
| 2426 | .while_simple => tree.whileSimple(node), | 2366 | .while_simple => tree.whileSimple(node), |
| 2427 | .while_cont => tree.whileCont(node), | 2367 | .while_cont => tree.whileCont(node), |
| 2428 | .@"while" => tree.whileFull(node), | 2368 | .@"while" => tree.whileFull(node), |
| ... | @@ -2431,7 +2371,7 @@ pub fn fullWhile(tree: Ast, node: Node.Index) ?full.While { | ... | @@ -2431,7 +2371,7 @@ pub fn fullWhile(tree: Ast, node: Node.Index) ?full.While { |
| 2431 | } | 2371 | } |
| 2432 | 2372 | ||
| 2433 | pub fn fullFor(tree: Ast, node: Node.Index) ?full.For { | 2373 | pub fn fullFor(tree: Ast, node: Node.Index) ?full.For { |
| 2434 | return switch (tree.nodes.items(.tag)[node]) { | 2374 | return switch (tree.nodeTag(node)) { |
| 2435 | .for_simple => tree.forSimple(node), | 2375 | .for_simple => tree.forSimple(node), |
| 2436 | .@"for" => tree.forFull(node), | 2376 | .@"for" => tree.forFull(node), |
| 2437 | else => null, | 2377 | else => null, |
| ... | @@ -2439,7 +2379,7 @@ pub fn fullFor(tree: Ast, node: Node.Index) ?full.For { | ... | @@ -2439,7 +2379,7 @@ pub fn fullFor(tree: Ast, node: Node.Index) ?full.For { |
| 2439 | } | 2379 | } |
| 2440 | 2380 | ||
| 2441 | pub fn fullContainerField(tree: Ast, node: Node.Index) ?full.ContainerField { | 2381 | pub fn fullContainerField(tree: Ast, node: Node.Index) ?full.ContainerField { |
| 2442 | return switch (tree.nodes.items(.tag)[node]) { | 2382 | return switch (tree.nodeTag(node)) { |
| 2443 | .container_field_init => tree.containerFieldInit(node), | 2383 | .container_field_init => tree.containerFieldInit(node), |
| 2444 | .container_field_align => tree.containerFieldAlign(node), | 2384 | .container_field_align => tree.containerFieldAlign(node), |
| 2445 | .container_field => tree.containerField(node), | 2385 | .container_field => tree.containerField(node), |
| ... | @@ -2448,18 +2388,18 @@ pub fn fullContainerField(tree: Ast, node: Node.Index) ?full.ContainerField { | ... | @@ -2448,18 +2388,18 @@ pub fn fullContainerField(tree: Ast, node: Node.Index) ?full.ContainerField { |
| 2448 | } | 2388 | } |
| 2449 | 2389 | ||
| 2450 | pub fn fullFnProto(tree: Ast, buffer: *[1]Ast.Node.Index, node: Node.Index) ?full.FnProto { | 2390 | pub fn fullFnProto(tree: Ast, buffer: *[1]Ast.Node.Index, node: Node.Index) ?full.FnProto { |
| 2451 | return switch (tree.nodes.items(.tag)[node]) { | 2391 | return switch (tree.nodeTag(node)) { |
| 2452 | .fn_proto => tree.fnProto(node), | 2392 | .fn_proto => tree.fnProto(node), |
| 2453 | .fn_proto_multi => tree.fnProtoMulti(node), | 2393 | .fn_proto_multi => tree.fnProtoMulti(node), |
| 2454 | .fn_proto_one => tree.fnProtoOne(buffer, node), | 2394 | .fn_proto_one => tree.fnProtoOne(buffer, node), |
| 2455 | .fn_proto_simple => tree.fnProtoSimple(buffer, node), | 2395 | .fn_proto_simple => tree.fnProtoSimple(buffer, node), |
| 2456 | .fn_decl => tree.fullFnProto(buffer, tree.nodes.items(.data)[node].lhs), | 2396 | .fn_decl => tree.fullFnProto(buffer, tree.nodeData(node).node_and_node[0]), |
| 2457 | else => null, | 2397 | else => null, |
| 2458 | }; | 2398 | }; |
| 2459 | } | 2399 | } |
| 2460 | 2400 | ||
| 2461 | pub fn fullStructInit(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index) ?full.StructInit { | 2401 | pub fn fullStructInit(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index) ?full.StructInit { |
| 2462 | return switch (tree.nodes.items(.tag)[node]) { | 2402 | return switch (tree.nodeTag(node)) { |
| 2463 | .struct_init_one, .struct_init_one_comma => tree.structInitOne(buffer[0..1], node), | 2403 | .struct_init_one, .struct_init_one_comma => tree.structInitOne(buffer[0..1], node), |
| 2464 | .struct_init_dot_two, .struct_init_dot_two_comma => tree.structInitDotTwo(buffer, node), | 2404 | .struct_init_dot_two, .struct_init_dot_two_comma => tree.structInitDotTwo(buffer, node), |
| 2465 | .struct_init_dot, .struct_init_dot_comma => tree.structInitDot(node), | 2405 | .struct_init_dot, .struct_init_dot_comma => tree.structInitDot(node), |
| ... | @@ -2469,7 +2409,7 @@ pub fn fullStructInit(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index) ? | ... | @@ -2469,7 +2409,7 @@ pub fn fullStructInit(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index) ? |
| 2469 | } | 2409 | } |
| 2470 | 2410 | ||
| 2471 | pub fn fullArrayInit(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) ?full.ArrayInit { | 2411 | pub fn fullArrayInit(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) ?full.ArrayInit { |
| 2472 | return switch (tree.nodes.items(.tag)[node]) { | 2412 | return switch (tree.nodeTag(node)) { |
| 2473 | .array_init_one, .array_init_one_comma => tree.arrayInitOne(buffer[0..1], node), | 2413 | .array_init_one, .array_init_one_comma => tree.arrayInitOne(buffer[0..1], node), |
| 2474 | .array_init_dot_two, .array_init_dot_two_comma => tree.arrayInitDotTwo(buffer, node), | 2414 | .array_init_dot_two, .array_init_dot_two_comma => tree.arrayInitDotTwo(buffer, node), |
| 2475 | .array_init_dot, .array_init_dot_comma => tree.arrayInitDot(node), | 2415 | .array_init_dot, .array_init_dot_comma => tree.arrayInitDot(node), |
| ... | @@ -2479,7 +2419,7 @@ pub fn fullArrayInit(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) ?full. | ... | @@ -2479,7 +2419,7 @@ pub fn fullArrayInit(tree: Ast, buffer: *[2]Node.Index, node: Node.Index) ?full. |
| 2479 | } | 2419 | } |
| 2480 | 2420 | ||
| 2481 | pub fn fullArrayType(tree: Ast, node: Node.Index) ?full.ArrayType { | 2421 | pub fn fullArrayType(tree: Ast, node: Node.Index) ?full.ArrayType { |
| 2482 | return switch (tree.nodes.items(.tag)[node]) { | 2422 | return switch (tree.nodeTag(node)) { |
| 2483 | .array_type => tree.arrayType(node), | 2423 | .array_type => tree.arrayType(node), |
| 2484 | .array_type_sentinel => tree.arrayTypeSentinel(node), | 2424 | .array_type_sentinel => tree.arrayTypeSentinel(node), |
| 2485 | else => null, | 2425 | else => null, |
| ... | @@ -2487,7 +2427,7 @@ pub fn fullArrayType(tree: Ast, node: Node.Index) ?full.ArrayType { | ... | @@ -2487,7 +2427,7 @@ pub fn fullArrayType(tree: Ast, node: Node.Index) ?full.ArrayType { |
| 2487 | } | 2427 | } |
| 2488 | 2428 | ||
| 2489 | pub fn fullPtrType(tree: Ast, node: Node.Index) ?full.PtrType { | 2429 | pub fn fullPtrType(tree: Ast, node: Node.Index) ?full.PtrType { |
| 2490 | return switch (tree.nodes.items(.tag)[node]) { | 2430 | return switch (tree.nodeTag(node)) { |
| 2491 | .ptr_type_aligned => tree.ptrTypeAligned(node), | 2431 | .ptr_type_aligned => tree.ptrTypeAligned(node), |
| 2492 | .ptr_type_sentinel => tree.ptrTypeSentinel(node), | 2432 | .ptr_type_sentinel => tree.ptrTypeSentinel(node), |
| 2493 | .ptr_type => tree.ptrType(node), | 2433 | .ptr_type => tree.ptrType(node), |
| ... | @@ -2497,7 +2437,7 @@ pub fn fullPtrType(tree: Ast, node: Node.Index) ?full.PtrType { | ... | @@ -2497,7 +2437,7 @@ pub fn fullPtrType(tree: Ast, node: Node.Index) ?full.PtrType { |
| 2497 | } | 2437 | } |
| 2498 | 2438 | ||
| 2499 | pub fn fullSlice(tree: Ast, node: Node.Index) ?full.Slice { | 2439 | pub fn fullSlice(tree: Ast, node: Node.Index) ?full.Slice { |
| 2500 | return switch (tree.nodes.items(.tag)[node]) { | 2440 | return switch (tree.nodeTag(node)) { |
| 2501 | .slice_open => tree.sliceOpen(node), | 2441 | .slice_open => tree.sliceOpen(node), |
| 2502 | .slice => tree.slice(node), | 2442 | .slice => tree.slice(node), |
| 2503 | .slice_sentinel => tree.sliceSentinel(node), | 2443 | .slice_sentinel => tree.sliceSentinel(node), |
| ... | @@ -2506,7 +2446,7 @@ pub fn fullSlice(tree: Ast, node: Node.Index) ?full.Slice { | ... | @@ -2506,7 +2446,7 @@ pub fn fullSlice(tree: Ast, node: Node.Index) ?full.Slice { |
| 2506 | } | 2446 | } |
| 2507 | 2447 | ||
| 2508 | pub fn fullContainerDecl(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index) ?full.ContainerDecl { | 2448 | pub fn fullContainerDecl(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index) ?full.ContainerDecl { |
| 2509 | return switch (tree.nodes.items(.tag)[node]) { | 2449 | return switch (tree.nodeTag(node)) { |
| 2510 | .root => tree.containerDeclRoot(), | 2450 | .root => tree.containerDeclRoot(), |
| 2511 | .container_decl, .container_decl_trailing => tree.containerDecl(node), | 2451 | .container_decl, .container_decl_trailing => tree.containerDecl(node), |
| 2512 | .container_decl_arg, .container_decl_arg_trailing => tree.containerDeclArg(node), | 2452 | .container_decl_arg, .container_decl_arg_trailing => tree.containerDeclArg(node), |
| ... | @@ -2519,14 +2459,14 @@ pub fn fullContainerDecl(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index | ... | @@ -2519,14 +2459,14 @@ pub fn fullContainerDecl(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index |
| 2519 | } | 2459 | } |
| 2520 | 2460 | ||
| 2521 | pub fn fullSwitch(tree: Ast, node: Node.Index) ?full.Switch { | 2461 | pub fn fullSwitch(tree: Ast, node: Node.Index) ?full.Switch { |
| 2522 | return switch (tree.nodes.items(.tag)[node]) { | 2462 | return switch (tree.nodeTag(node)) { |
| 2523 | .@"switch", .switch_comma => tree.switchFull(node), | 2463 | .@"switch", .switch_comma => tree.switchFull(node), |
| 2524 | else => null, | 2464 | else => null, |
| 2525 | }; | 2465 | }; |
| 2526 | } | 2466 | } |
| 2527 | 2467 | ||
| 2528 | pub fn fullSwitchCase(tree: Ast, node: Node.Index) ?full.SwitchCase { | 2468 | pub fn fullSwitchCase(tree: Ast, node: Node.Index) ?full.SwitchCase { |
| 2529 | return switch (tree.nodes.items(.tag)[node]) { | 2469 | return switch (tree.nodeTag(node)) { |
| 2530 | .switch_case_one, .switch_case_inline_one => tree.switchCaseOne(node), | 2470 | .switch_case_one, .switch_case_inline_one => tree.switchCaseOne(node), |
| 2531 | .switch_case, .switch_case_inline => tree.switchCase(node), | 2471 | .switch_case, .switch_case_inline => tree.switchCase(node), |
| 2532 | else => null, | 2472 | else => null, |
| ... | @@ -2534,7 +2474,7 @@ pub fn fullSwitchCase(tree: Ast, node: Node.Index) ?full.SwitchCase { | ... | @@ -2534,7 +2474,7 @@ pub fn fullSwitchCase(tree: Ast, node: Node.Index) ?full.SwitchCase { |
| 2534 | } | 2474 | } |
| 2535 | 2475 | ||
| 2536 | pub fn fullAsm(tree: Ast, node: Node.Index) ?full.Asm { | 2476 | pub fn fullAsm(tree: Ast, node: Node.Index) ?full.Asm { |
| 2537 | return switch (tree.nodes.items(.tag)[node]) { | 2477 | return switch (tree.nodeTag(node)) { |
| 2538 | .asm_simple => tree.asmSimple(node), | 2478 | .asm_simple => tree.asmSimple(node), |
| 2539 | .@"asm" => tree.asmFull(node), | 2479 | .@"asm" => tree.asmFull(node), |
| 2540 | else => null, | 2480 | else => null, |
| ... | @@ -2542,13 +2482,29 @@ pub fn fullAsm(tree: Ast, node: Node.Index) ?full.Asm { | ... | @@ -2542,13 +2482,29 @@ pub fn fullAsm(tree: Ast, node: Node.Index) ?full.Asm { |
| 2542 | } | 2482 | } |
| 2543 | 2483 | ||
| 2544 | pub fn fullCall(tree: Ast, buffer: *[1]Ast.Node.Index, node: Node.Index) ?full.Call { | 2484 | pub fn fullCall(tree: Ast, buffer: *[1]Ast.Node.Index, node: Node.Index) ?full.Call { |
| 2545 | return switch (tree.nodes.items(.tag)[node]) { | 2485 | return switch (tree.nodeTag(node)) { |
| 2546 | .call, .call_comma, .async_call, .async_call_comma => tree.callFull(node), | 2486 | .call, .call_comma, .async_call, .async_call_comma => tree.callFull(node), |
| 2547 | .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => tree.callOne(buffer, node), | 2487 | .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => tree.callOne(buffer, node), |
| 2548 | else => null, | 2488 | else => null, |
| 2549 | }; | 2489 | }; |
| 2550 | } | 2490 | } |
| 2551 | 2491 | ||
| 2492 | pub fn builtinCallParams(tree: Ast, buffer: *[2]Ast.Node.Index, node: Ast.Node.Index) ?[]const Node.Index { | ||
| 2493 | return switch (tree.nodeTag(node)) { | ||
| 2494 | .builtin_call_two, .builtin_call_two_comma => loadOptionalNodesIntoBuffer(2, buffer, tree.nodeData(node).opt_node_and_opt_node), | ||
| 2495 | .builtin_call, .builtin_call_comma => tree.extraDataSlice(tree.nodeData(node).extra_range, Node.Index), | ||
| 2496 | else => null, | ||
| 2497 | }; | ||
| 2498 | } | ||
| 2499 | |||
| 2500 | pub fn blockStatements(tree: Ast, buffer: *[2]Ast.Node.Index, node: Ast.Node.Index) ?[]const Node.Index { | ||
| 2501 | return switch (tree.nodeTag(node)) { | ||
| 2502 | .block_two, .block_two_semicolon => loadOptionalNodesIntoBuffer(2, buffer, tree.nodeData(node).opt_node_and_opt_node), | ||
| 2503 | .block, .block_semicolon => tree.extraDataSlice(tree.nodeData(node).extra_range, Node.Index), | ||
| 2504 | else => null, | ||
| 2505 | }; | ||
| 2506 | } | ||
| 2507 | |||
| 2552 | /// Fully assembled AST node information. | 2508 | /// Fully assembled AST node information. |
| 2553 | pub const full = struct { | 2509 | pub const full = struct { |
| 2554 | pub const VarDecl = struct { | 2510 | pub const VarDecl = struct { |
| ... | @@ -2561,11 +2517,11 @@ pub const full = struct { | ... | @@ -2561,11 +2517,11 @@ pub const full = struct { |
| 2561 | 2517 | ||
| 2562 | pub const Components = struct { | 2518 | pub const Components = struct { |
| 2563 | mut_token: TokenIndex, | 2519 | mut_token: TokenIndex, |
| 2564 | type_node: Node.Index, | 2520 | type_node: Node.OptionalIndex, |
| 2565 | align_node: Node.Index, | 2521 | align_node: Node.OptionalIndex, |
| 2566 | addrspace_node: Node.Index, | 2522 | addrspace_node: Node.OptionalIndex, |
| 2567 | section_node: Node.Index, | 2523 | section_node: Node.OptionalIndex, |
| 2568 | init_node: Node.Index, | 2524 | init_node: Node.OptionalIndex, |
| 2569 | }; | 2525 | }; |
| 2570 | 2526 | ||
| 2571 | pub fn firstToken(var_decl: VarDecl) TokenIndex { | 2527 | pub fn firstToken(var_decl: VarDecl) TokenIndex { |
| ... | @@ -2594,7 +2550,7 @@ pub const full = struct { | ... | @@ -2594,7 +2550,7 @@ pub const full = struct { |
| 2594 | payload_token: ?TokenIndex, | 2550 | payload_token: ?TokenIndex, |
| 2595 | /// Points to the identifier after the `|`. | 2551 | /// Points to the identifier after the `|`. |
| 2596 | error_token: ?TokenIndex, | 2552 | error_token: ?TokenIndex, |
| 2597 | /// Populated only if else_expr != 0. | 2553 | /// Populated only if else_expr != .none. |
| 2598 | else_token: TokenIndex, | 2554 | else_token: TokenIndex, |
| 2599 | ast: Components, | 2555 | ast: Components, |
| 2600 | 2556 | ||
| ... | @@ -2602,7 +2558,7 @@ pub const full = struct { | ... | @@ -2602,7 +2558,7 @@ pub const full = struct { |
| 2602 | if_token: TokenIndex, | 2558 | if_token: TokenIndex, |
| 2603 | cond_expr: Node.Index, | 2559 | cond_expr: Node.Index, |
| 2604 | then_expr: Node.Index, | 2560 | then_expr: Node.Index, |
| 2605 | else_expr: Node.Index, | 2561 | else_expr: Node.OptionalIndex, |
| 2606 | }; | 2562 | }; |
| 2607 | }; | 2563 | }; |
| 2608 | 2564 | ||
| ... | @@ -2612,15 +2568,15 @@ pub const full = struct { | ... | @@ -2612,15 +2568,15 @@ pub const full = struct { |
| 2612 | label_token: ?TokenIndex, | 2568 | label_token: ?TokenIndex, |
| 2613 | payload_token: ?TokenIndex, | 2569 | payload_token: ?TokenIndex, |
| 2614 | error_token: ?TokenIndex, | 2570 | error_token: ?TokenIndex, |
| 2615 | /// Populated only if else_expr != 0. | 2571 | /// Populated only if else_expr != none. |
| 2616 | else_token: TokenIndex, | 2572 | else_token: TokenIndex, |
| 2617 | 2573 | ||
| 2618 | pub const Components = struct { | 2574 | pub const Components = struct { |
| 2619 | while_token: TokenIndex, | 2575 | while_token: TokenIndex, |
| 2620 | cond_expr: Node.Index, | 2576 | cond_expr: Node.Index, |
| 2621 | cont_expr: Node.Index, | 2577 | cont_expr: Node.OptionalIndex, |
| 2622 | then_expr: Node.Index, | 2578 | then_expr: Node.Index, |
| 2623 | else_expr: Node.Index, | 2579 | else_expr: Node.OptionalIndex, |
| 2624 | }; | 2580 | }; |
| 2625 | }; | 2581 | }; |
| 2626 | 2582 | ||
| ... | @@ -2629,14 +2585,14 @@ pub const full = struct { | ... | @@ -2629,14 +2585,14 @@ pub const full = struct { |
| 2629 | inline_token: ?TokenIndex, | 2585 | inline_token: ?TokenIndex, |
| 2630 | label_token: ?TokenIndex, | 2586 | label_token: ?TokenIndex, |
| 2631 | payload_token: TokenIndex, | 2587 | payload_token: TokenIndex, |
| 2632 | /// Populated only if else_expr != 0. | 2588 | /// Populated only if else_expr != .none. |
| 2633 | else_token: TokenIndex, | 2589 | else_token: ?TokenIndex, |
| 2634 | 2590 | ||
| 2635 | pub const Components = struct { | 2591 | pub const Components = struct { |
| 2636 | for_token: TokenIndex, | 2592 | for_token: TokenIndex, |
| 2637 | inputs: []const Node.Index, | 2593 | inputs: []const Node.Index, |
| 2638 | then_expr: Node.Index, | 2594 | then_expr: Node.Index, |
| 2639 | else_expr: Node.Index, | 2595 | else_expr: Node.OptionalIndex, |
| 2640 | }; | 2596 | }; |
| 2641 | }; | 2597 | }; |
| 2642 | 2598 | ||
| ... | @@ -2646,9 +2602,10 @@ pub const full = struct { | ... | @@ -2646,9 +2602,10 @@ pub const full = struct { |
| 2646 | 2602 | ||
| 2647 | pub const Components = struct { | 2603 | pub const Components = struct { |
| 2648 | main_token: TokenIndex, | 2604 | main_token: TokenIndex, |
| 2649 | type_expr: Node.Index, | 2605 | /// Can only be `.none` after calling `convertToNonTupleLike`. |
| 2650 | align_expr: Node.Index, | 2606 | type_expr: Node.OptionalIndex, |
| 2651 | value_expr: Node.Index, | 2607 | align_expr: Node.OptionalIndex, |
| 2608 | value_expr: Node.OptionalIndex, | ||
| 2652 | tuple_like: bool, | 2609 | tuple_like: bool, |
| 2653 | }; | 2610 | }; |
| 2654 | 2611 | ||
| ... | @@ -2656,11 +2613,11 @@ pub const full = struct { | ... | @@ -2656,11 +2613,11 @@ pub const full = struct { |
| 2656 | return cf.comptime_token orelse cf.ast.main_token; | 2613 | return cf.comptime_token orelse cf.ast.main_token; |
| 2657 | } | 2614 | } |
| 2658 | 2615 | ||
| 2659 | pub fn convertToNonTupleLike(cf: *ContainerField, nodes: NodeList.Slice) void { | 2616 | pub fn convertToNonTupleLike(cf: *ContainerField, tree: *const Ast) void { |
| 2660 | if (!cf.ast.tuple_like) return; | 2617 | if (!cf.ast.tuple_like) return; |
| 2661 | if (nodes.items(.tag)[cf.ast.type_expr] != .identifier) return; | 2618 | if (tree.nodeTag(cf.ast.type_expr.unwrap().?) != .identifier) return; |
| 2662 | 2619 | ||
| 2663 | cf.ast.type_expr = 0; | 2620 | cf.ast.type_expr = .none; |
| 2664 | cf.ast.tuple_like = false; | 2621 | cf.ast.tuple_like = false; |
| 2665 | } | 2622 | } |
| 2666 | }; | 2623 | }; |
| ... | @@ -2676,12 +2633,12 @@ pub const full = struct { | ... | @@ -2676,12 +2633,12 @@ pub const full = struct { |
| 2676 | pub const Components = struct { | 2633 | pub const Components = struct { |
| 2677 | proto_node: Node.Index, | 2634 | proto_node: Node.Index, |
| 2678 | fn_token: TokenIndex, | 2635 | fn_token: TokenIndex, |
| 2679 | return_type: Node.Index, | 2636 | return_type: Node.OptionalIndex, |
| 2680 | params: []const Node.Index, | 2637 | params: []const Node.Index, |
| 2681 | align_expr: Node.Index, | 2638 | align_expr: Node.OptionalIndex, |
| 2682 | addrspace_expr: Node.Index, | 2639 | addrspace_expr: Node.OptionalIndex, |
| 2683 | section_expr: Node.Index, | 2640 | section_expr: Node.OptionalIndex, |
| 2684 | callconv_expr: Node.Index, | 2641 | callconv_expr: Node.OptionalIndex, |
| 2685 | }; | 2642 | }; |
| 2686 | 2643 | ||
| 2687 | pub const Param = struct { | 2644 | pub const Param = struct { |
| ... | @@ -2689,7 +2646,7 @@ pub const full = struct { | ... | @@ -2689,7 +2646,7 @@ pub const full = struct { |
| 2689 | name_token: ?TokenIndex, | 2646 | name_token: ?TokenIndex, |
| 2690 | comptime_noalias: ?TokenIndex, | 2647 | comptime_noalias: ?TokenIndex, |
| 2691 | anytype_ellipsis3: ?TokenIndex, | 2648 | anytype_ellipsis3: ?TokenIndex, |
| 2692 | type_expr: Node.Index, | 2649 | type_expr: ?Node.Index, |
| 2693 | }; | 2650 | }; |
| 2694 | 2651 | ||
| 2695 | pub fn firstToken(fn_proto: FnProto) TokenIndex { | 2652 | pub fn firstToken(fn_proto: FnProto) TokenIndex { |
| ... | @@ -2709,7 +2666,7 @@ pub const full = struct { | ... | @@ -2709,7 +2666,7 @@ pub const full = struct { |
| 2709 | tok_flag: bool, | 2666 | tok_flag: bool, |
| 2710 | 2667 | ||
| 2711 | pub fn next(it: *Iterator) ?Param { | 2668 | pub fn next(it: *Iterator) ?Param { |
| 2712 | const token_tags = it.tree.tokens.items(.tag); | 2669 | const tree = it.tree; |
| 2713 | while (true) { | 2670 | while (true) { |
| 2714 | var first_doc_comment: ?TokenIndex = null; | 2671 | var first_doc_comment: ?TokenIndex = null; |
| 2715 | var comptime_noalias: ?TokenIndex = null; | 2672 | var comptime_noalias: ?TokenIndex = null; |
| ... | @@ -2719,8 +2676,8 @@ pub const full = struct { | ... | @@ -2719,8 +2676,8 @@ pub const full = struct { |
| 2719 | return null; | 2676 | return null; |
| 2720 | } | 2677 | } |
| 2721 | const param_type = it.fn_proto.ast.params[it.param_i]; | 2678 | const param_type = it.fn_proto.ast.params[it.param_i]; |
| 2722 | var tok_i = it.tree.firstToken(param_type) - 1; | 2679 | var tok_i = tree.firstToken(param_type) - 1; |
| 2723 | while (true) : (tok_i -= 1) switch (token_tags[tok_i]) { | 2680 | while (true) : (tok_i -= 1) switch (tree.tokenTag(tok_i)) { |
| 2724 | .colon => continue, | 2681 | .colon => continue, |
| 2725 | .identifier => name_token = tok_i, | 2682 | .identifier => name_token = tok_i, |
| 2726 | .doc_comment => first_doc_comment = tok_i, | 2683 | .doc_comment => first_doc_comment = tok_i, |
| ... | @@ -2728,9 +2685,9 @@ pub const full = struct { | ... | @@ -2728,9 +2685,9 @@ pub const full = struct { |
| 2728 | else => break, | 2685 | else => break, |
| 2729 | }; | 2686 | }; |
| 2730 | it.param_i += 1; | 2687 | it.param_i += 1; |
| 2731 | it.tok_i = it.tree.lastToken(param_type) + 1; | 2688 | it.tok_i = tree.lastToken(param_type) + 1; |
| 2732 | // Look for anytype and ... params afterwards. | 2689 | // Look for anytype and ... params afterwards. |
| 2733 | if (token_tags[it.tok_i] == .comma) { | 2690 | if (tree.tokenTag(it.tok_i) == .comma) { |
| 2734 | it.tok_i += 1; | 2691 | it.tok_i += 1; |
| 2735 | } | 2692 | } |
| 2736 | it.tok_flag = true; | 2693 | it.tok_flag = true; |
| ... | @@ -2742,19 +2699,19 @@ pub const full = struct { | ... | @@ -2742,19 +2699,19 @@ pub const full = struct { |
| 2742 | .type_expr = param_type, | 2699 | .type_expr = param_type, |
| 2743 | }; | 2700 | }; |
| 2744 | } | 2701 | } |
| 2745 | if (token_tags[it.tok_i] == .comma) { | 2702 | if (tree.tokenTag(it.tok_i) == .comma) { |
| 2746 | it.tok_i += 1; | 2703 | it.tok_i += 1; |
| 2747 | } | 2704 | } |
| 2748 | if (token_tags[it.tok_i] == .r_paren) { | 2705 | if (tree.tokenTag(it.tok_i) == .r_paren) { |
| 2749 | return null; | 2706 | return null; |
| 2750 | } | 2707 | } |
| 2751 | if (token_tags[it.tok_i] == .doc_comment) { | 2708 | if (tree.tokenTag(it.tok_i) == .doc_comment) { |
| 2752 | first_doc_comment = it.tok_i; | 2709 | first_doc_comment = it.tok_i; |
| 2753 | while (token_tags[it.tok_i] == .doc_comment) { | 2710 | while (tree.tokenTag(it.tok_i) == .doc_comment) { |
| 2754 | it.tok_i += 1; | 2711 | it.tok_i += 1; |
| 2755 | } | 2712 | } |
| 2756 | } | 2713 | } |
| 2757 | switch (token_tags[it.tok_i]) { | 2714 | switch (tree.tokenTag(it.tok_i)) { |
| 2758 | .ellipsis3 => { | 2715 | .ellipsis3 => { |
| 2759 | it.tok_flag = false; // Next iteration should return null. | 2716 | it.tok_flag = false; // Next iteration should return null. |
| 2760 | return Param{ | 2717 | return Param{ |
| ... | @@ -2762,7 +2719,7 @@ pub const full = struct { | ... | @@ -2762,7 +2719,7 @@ pub const full = struct { |
| 2762 | .comptime_noalias = null, | 2719 | .comptime_noalias = null, |
| 2763 | .name_token = null, | 2720 | .name_token = null, |
| 2764 | .anytype_ellipsis3 = it.tok_i, | 2721 | .anytype_ellipsis3 = it.tok_i, |
| 2765 | .type_expr = 0, | 2722 | .type_expr = null, |
| 2766 | }; | 2723 | }; |
| 2767 | }, | 2724 | }, |
| 2768 | .keyword_noalias, .keyword_comptime => { | 2725 | .keyword_noalias, .keyword_comptime => { |
| ... | @@ -2771,20 +2728,20 @@ pub const full = struct { | ... | @@ -2771,20 +2728,20 @@ pub const full = struct { |
| 2771 | }, | 2728 | }, |
| 2772 | else => {}, | 2729 | else => {}, |
| 2773 | } | 2730 | } |
| 2774 | if (token_tags[it.tok_i] == .identifier and | 2731 | if (tree.tokenTag(it.tok_i) == .identifier and |
| 2775 | token_tags[it.tok_i + 1] == .colon) | 2732 | tree.tokenTag(it.tok_i + 1) == .colon) |
| 2776 | { | 2733 | { |
| 2777 | name_token = it.tok_i; | 2734 | name_token = it.tok_i; |
| 2778 | it.tok_i += 2; | 2735 | it.tok_i += 2; |
| 2779 | } | 2736 | } |
| 2780 | if (token_tags[it.tok_i] == .keyword_anytype) { | 2737 | if (tree.tokenTag(it.tok_i) == .keyword_anytype) { |
| 2781 | it.tok_i += 1; | 2738 | it.tok_i += 1; |
| 2782 | return Param{ | 2739 | return Param{ |
| 2783 | .first_doc_comment = first_doc_comment, | 2740 | .first_doc_comment = first_doc_comment, |
| 2784 | .comptime_noalias = comptime_noalias, | 2741 | .comptime_noalias = comptime_noalias, |
| 2785 | .name_token = name_token, | 2742 | .name_token = name_token, |
| 2786 | .anytype_ellipsis3 = it.tok_i - 1, | 2743 | .anytype_ellipsis3 = it.tok_i - 1, |
| 2787 | .type_expr = 0, | 2744 | .type_expr = null, |
| 2788 | }; | 2745 | }; |
| 2789 | } | 2746 | } |
| 2790 | it.tok_flag = false; | 2747 | it.tok_flag = false; |
| ... | @@ -2809,7 +2766,7 @@ pub const full = struct { | ... | @@ -2809,7 +2766,7 @@ pub const full = struct { |
| 2809 | pub const Components = struct { | 2766 | pub const Components = struct { |
| 2810 | lbrace: TokenIndex, | 2767 | lbrace: TokenIndex, |
| 2811 | fields: []const Node.Index, | 2768 | fields: []const Node.Index, |
| 2812 | type_expr: Node.Index, | 2769 | type_expr: Node.OptionalIndex, |
| 2813 | }; | 2770 | }; |
| 2814 | }; | 2771 | }; |
| 2815 | 2772 | ||
| ... | @@ -2819,7 +2776,7 @@ pub const full = struct { | ... | @@ -2819,7 +2776,7 @@ pub const full = struct { |
| 2819 | pub const Components = struct { | 2776 | pub const Components = struct { |
| 2820 | lbrace: TokenIndex, | 2777 | lbrace: TokenIndex, |
| 2821 | elements: []const Node.Index, | 2778 | elements: []const Node.Index, |
| 2822 | type_expr: Node.Index, | 2779 | type_expr: Node.OptionalIndex, |
| 2823 | }; | 2780 | }; |
| 2824 | }; | 2781 | }; |
| 2825 | 2782 | ||
| ... | @@ -2829,7 +2786,7 @@ pub const full = struct { | ... | @@ -2829,7 +2786,7 @@ pub const full = struct { |
| 2829 | pub const Components = struct { | 2786 | pub const Components = struct { |
| 2830 | lbracket: TokenIndex, | 2787 | lbracket: TokenIndex, |
| 2831 | elem_count: Node.Index, | 2788 | elem_count: Node.Index, |
| 2832 | sentinel: Node.Index, | 2789 | sentinel: Node.OptionalIndex, |
| 2833 | elem_type: Node.Index, | 2790 | elem_type: Node.Index, |
| 2834 | }; | 2791 | }; |
| 2835 | }; | 2792 | }; |
| ... | @@ -2843,11 +2800,11 @@ pub const full = struct { | ... | @@ -2843,11 +2800,11 @@ pub const full = struct { |
| 2843 | 2800 | ||
| 2844 | pub const Components = struct { | 2801 | pub const Components = struct { |
| 2845 | main_token: TokenIndex, | 2802 | main_token: TokenIndex, |
| 2846 | align_node: Node.Index, | 2803 | align_node: Node.OptionalIndex, |
| 2847 | addrspace_node: Node.Index, | 2804 | addrspace_node: Node.OptionalIndex, |
| 2848 | sentinel: Node.Index, | 2805 | sentinel: Node.OptionalIndex, |
| 2849 | bit_range_start: Node.Index, | 2806 | bit_range_start: Node.OptionalIndex, |
| 2850 | bit_range_end: Node.Index, | 2807 | bit_range_end: Node.OptionalIndex, |
| 2851 | child_type: Node.Index, | 2808 | child_type: Node.Index, |
| 2852 | }; | 2809 | }; |
| 2853 | }; | 2810 | }; |
| ... | @@ -2859,8 +2816,8 @@ pub const full = struct { | ... | @@ -2859,8 +2816,8 @@ pub const full = struct { |
| 2859 | sliced: Node.Index, | 2816 | sliced: Node.Index, |
| 2860 | lbracket: TokenIndex, | 2817 | lbracket: TokenIndex, |
| 2861 | start: Node.Index, | 2818 | start: Node.Index, |
| 2862 | end: Node.Index, | 2819 | end: Node.OptionalIndex, |
| 2863 | sentinel: Node.Index, | 2820 | sentinel: Node.OptionalIndex, |
| 2864 | }; | 2821 | }; |
| 2865 | }; | 2822 | }; |
| 2866 | 2823 | ||
| ... | @@ -2873,7 +2830,7 @@ pub const full = struct { | ... | @@ -2873,7 +2830,7 @@ pub const full = struct { |
| 2873 | /// Populated when main_token is Keyword_union. | 2830 | /// Populated when main_token is Keyword_union. |
| 2874 | enum_token: ?TokenIndex, | 2831 | enum_token: ?TokenIndex, |
| 2875 | members: []const Node.Index, | 2832 | members: []const Node.Index, |
| 2876 | arg: Node.Index, | 2833 | arg: Node.OptionalIndex, |
| 2877 | }; | 2834 | }; |
| 2878 | }; | 2835 | }; |
| 2879 | 2836 | ||
| ... | @@ -3016,492 +2973,971 @@ pub const Error = struct { | ... | @@ -3016,492 +2973,971 @@ pub const Error = struct { |
| 3016 | }; | 2973 | }; |
| 3017 | }; | 2974 | }; |
| 3018 | 2975 | ||
| 2976 | /// Index into `extra_data`. | ||
| 2977 | pub const ExtraIndex = enum(u32) { | ||
| 2978 | _, | ||
| 2979 | }; | ||
| 2980 | |||
| 3019 | pub const Node = struct { | 2981 | pub const Node = struct { |
| 3020 | tag: Tag, | 2982 | tag: Tag, |
| 3021 | main_token: TokenIndex, | 2983 | main_token: TokenIndex, |
| 3022 | data: Data, | 2984 | data: Data, |
| 3023 | 2985 | ||
| 3024 | pub const Index = u32; | 2986 | /// Index into `nodes`. |
| 2987 | pub const Index = enum(u32) { | ||
| 2988 | root = 0, | ||
| 2989 | _, | ||
| 2990 | |||
| 2991 | pub fn toOptional(i: Index) OptionalIndex { | ||
| 2992 | const result: OptionalIndex = @enumFromInt(@intFromEnum(i)); | ||
| 2993 | assert(result != .none); | ||
| 2994 | return result; | ||
| 2995 | } | ||
| 2996 | |||
| 2997 | pub fn toOffset(base: Index, destination: Index) Offset { | ||
| 2998 | const base_i64: i64 = @intFromEnum(base); | ||
| 2999 | const destination_i64: i64 = @intFromEnum(destination); | ||
| 3000 | return @enumFromInt(destination_i64 - base_i64); | ||
| 3001 | } | ||
| 3002 | }; | ||
| 3003 | |||
| 3004 | /// Index into `nodes`, or null. | ||
| 3005 | pub const OptionalIndex = enum(u32) { | ||
| 3006 | root = 0, | ||
| 3007 | none = std.math.maxInt(u32), | ||
| 3008 | _, | ||
| 3009 | |||
| 3010 | pub fn unwrap(oi: OptionalIndex) ?Index { | ||
| 3011 | return if (oi == .none) null else @enumFromInt(@intFromEnum(oi)); | ||
| 3012 | } | ||
| 3013 | |||
| 3014 | pub fn fromOptional(oi: ?Index) OptionalIndex { | ||
| 3015 | return if (oi) |i| i.toOptional() else .none; | ||
| 3016 | } | ||
| 3017 | }; | ||
| 3018 | |||
| 3019 | /// A relative node index. | ||
| 3020 | pub const Offset = enum(i32) { | ||
| 3021 | zero = 0, | ||
| 3022 | _, | ||
| 3023 | |||
| 3024 | pub fn toOptional(o: Offset) OptionalOffset { | ||
| 3025 | const result: OptionalOffset = @enumFromInt(@intFromEnum(o)); | ||
| 3026 | assert(result != .none); | ||
| 3027 | return result; | ||
| 3028 | } | ||
| 3029 | |||
| 3030 | pub fn toAbsolute(offset: Offset, base: Index) Index { | ||
| 3031 | return @enumFromInt(@as(i64, @intFromEnum(base)) + @intFromEnum(offset)); | ||
| 3032 | } | ||
| 3033 | }; | ||
| 3034 | |||
| 3035 | /// A relative node index, or null. | ||
| 3036 | pub const OptionalOffset = enum(i32) { | ||
| 3037 | none = std.math.maxInt(i32), | ||
| 3038 | _, | ||
| 3039 | |||
| 3040 | pub fn unwrap(oo: OptionalOffset) ?Offset { | ||
| 3041 | return if (oo == .none) null else @enumFromInt(@intFromEnum(oo)); | ||
| 3042 | } | ||
| 3043 | }; | ||
| 3025 | 3044 | ||
| 3026 | comptime { | 3045 | comptime { |
| 3027 | // Goal is to keep this under one byte for efficiency. | 3046 | // Goal is to keep this under one byte for efficiency. |
| 3028 | assert(@sizeOf(Tag) == 1); | 3047 | assert(@sizeOf(Tag) == 1); |
| 3048 | |||
| 3049 | if (!std.debug.runtime_safety) { | ||
| 3050 | assert(@sizeOf(Data) == 8); | ||
| 3051 | } | ||
| 3029 | } | 3052 | } |
| 3030 | 3053 | ||
| 3031 | /// Note: The FooComma/FooSemicolon variants exist to ease the implementation of | 3054 | /// The FooComma/FooSemicolon variants exist to ease the implementation of |
| 3032 | /// Ast.lastToken() | 3055 | /// `Ast.lastToken()` |
| 3033 | pub const Tag = enum { | 3056 | pub const Tag = enum { |
| 3034 | /// sub_list[lhs...rhs] | 3057 | /// The root node which is guaranteed to be at `Node.Index.root`. |
| 3058 | /// The meaning of the `data` field depends on whether it is a `.zig` or | ||
| 3059 | /// `.zon` file. | ||
| 3060 | /// | ||
| 3061 | /// The `main_token` field is the first token for the source file. | ||
| 3035 | root, | 3062 | root, |
| 3036 | /// `usingnamespace lhs;`. rhs unused. main_token is `usingnamespace`. | 3063 | /// `usingnamespace expr;`. |
| 3064 | /// | ||
| 3065 | /// The `data` field is a `.node` to expr. | ||
| 3066 | /// | ||
| 3067 | /// The `main_token` field is the `usingnamespace` token. | ||
| 3037 | @"usingnamespace", | 3068 | @"usingnamespace", |
| 3038 | /// lhs is test name token (must be string literal or identifier), if any. | 3069 | /// `test {}`, |
| 3039 | /// rhs is the body node. | 3070 | /// `test "name" {}`, |
| 3071 | /// `test identifier {}`. | ||
| 3072 | /// | ||
| 3073 | /// The `data` field is a `.opt_token_and_node`: | ||
| 3074 | /// 1. a `OptionalTokenIndex` to the test name token (must be string literal or identifier), if any. | ||
| 3075 | /// 2. a `Node.Index` to the block. | ||
| 3076 | /// | ||
| 3077 | /// The `main_token` field is the `test` token. | ||
| 3040 | test_decl, | 3078 | test_decl, |
| 3041 | /// lhs is the index into extra_data. | 3079 | /// The `data` field is a `.extra_and_opt_node`: |
| 3042 | /// rhs is the initialization expression, if any. | 3080 | /// 1. a `ExtraIndex` to `GlobalVarDecl`. |
| 3043 | /// main_token is `var` or `const`. | 3081 | /// 2. a `Node.OptionalIndex` to the initialization expression. |
| 3082 | /// | ||
| 3083 | /// The `main_token` field is the `var` or `const` token. | ||
| 3084 | /// | ||
| 3085 | /// The initialization expression can't be `.none` unless it is part of | ||
| 3086 | /// a `assign_destructure` node or a parsing error occured. | ||
| 3044 | global_var_decl, | 3087 | global_var_decl, |
| 3045 | /// `var a: x align(y) = rhs` | 3088 | /// `var a: b align(c) = d`. |
| 3046 | /// lhs is the index into extra_data. | 3089 | /// `const main_token: type_node align(align_node) = init_expr`. |
| 3047 | /// main_token is `var` or `const`. | 3090 | /// |
| 3091 | /// The `data` field is a `.extra_and_opt_node`: | ||
| 3092 | /// 1. a `ExtraIndex` to `LocalVarDecl`. | ||
| 3093 | /// 2. a `Node.OptionalIndex` to the initialization expression- | ||
| 3094 | /// | ||
| 3095 | /// The `main_token` field is the `var` or `const` token. | ||
| 3096 | /// | ||
| 3097 | /// The initialization expression can't be `.none` unless it is part of | ||
| 3098 | /// a `assign_destructure` node or a parsing error occured. | ||
| 3048 | local_var_decl, | 3099 | local_var_decl, |
| 3049 | /// `var a: lhs = rhs`. lhs and rhs may be unused. | 3100 | /// `var a: b = c`. |
| 3101 | /// `const name_token: type_expr = init_expr`. | ||
| 3050 | /// Can be local or global. | 3102 | /// Can be local or global. |
| 3051 | /// main_token is `var` or `const`. | 3103 | /// |
| 3104 | /// The `data` field is a `.opt_node_and_opt_node`: | ||
| 3105 | /// 1. a `Node.OptionalIndex` to the type expression, if any. | ||
| 3106 | /// 2. a `Node.OptionalIndex` to the initialization expression. | ||
| 3107 | /// | ||
| 3108 | /// The `main_token` field is the `var` or `const` token. | ||
| 3109 | /// | ||
| 3110 | /// The initialization expression can't be `.none` unless it is part of | ||
| 3111 | /// a `assign_destructure` node or a parsing error occured. | ||
| 3052 | simple_var_decl, | 3112 | simple_var_decl, |
| 3053 | /// `var a align(lhs) = rhs`. lhs and rhs may be unused. | 3113 | /// `var a align(b) = c`. |
| 3114 | /// `const name_token align(align_expr) = init_expr`. | ||
| 3054 | /// Can be local or global. | 3115 | /// Can be local or global. |
| 3055 | /// main_token is `var` or `const`. | 3116 | /// |
| 3117 | /// The `data` field is a `.node_and_opt_node`: | ||
| 3118 | /// 1. a `Node.Index` to the alignment expression. | ||
| 3119 | /// 2. a `Node.OptionalIndex` to the initialization expression. | ||
| 3120 | /// | ||
| 3121 | /// The `main_token` field is the `var` or `const` token. | ||
| 3122 | /// | ||
| 3123 | /// The initialization expression can't be `.none` unless it is part of | ||
| 3124 | /// a `assign_destructure` node or a parsing error occured. | ||
| 3056 | aligned_var_decl, | 3125 | aligned_var_decl, |
| 3057 | /// lhs is the identifier token payload if any, | 3126 | /// `errdefer expr`, |
| 3058 | /// rhs is the deferred expression. | 3127 | /// `errdefer |payload| expr`. |
| 3128 | /// | ||
| 3129 | /// The `data` field is a `.opt_token_and_node`: | ||
| 3130 | /// 1. a `OptionalTokenIndex` to the payload identifier, if any. | ||
| 3131 | /// 2. a `Node.Index` to the deferred expression. | ||
| 3132 | /// | ||
| 3133 | /// The `main_token` field is the `errdefer` token. | ||
| 3059 | @"errdefer", | 3134 | @"errdefer", |
| 3060 | /// lhs is unused. | 3135 | /// `defer expr`. |
| 3061 | /// rhs is the deferred expression. | 3136 | /// |
| 3137 | /// The `data` field is a `.node` to the deferred expression. | ||
| 3138 | /// | ||
| 3139 | /// The `main_token` field is the `defer`. | ||
| 3062 | @"defer", | 3140 | @"defer", |
| 3063 | /// lhs catch rhs | 3141 | /// `lhs catch rhs`, |
| 3064 | /// lhs catch |err| rhs | 3142 | /// `lhs catch |err| rhs`. |
| 3065 | /// main_token is the `catch` keyword. | 3143 | /// |
| 3066 | /// payload is determined by looking at the next token after the `catch` keyword. | 3144 | /// The `main_token` field is the `catch` token. |
| 3145 | /// | ||
| 3146 | /// The error payload is determined by looking at the next token after | ||
| 3147 | /// the `catch` token. | ||
| 3067 | @"catch", | 3148 | @"catch", |
| 3068 | /// `lhs.a`. main_token is the dot. rhs is the identifier token index. | 3149 | /// `lhs.a`. |
| 3150 | /// | ||
| 3151 | /// The `data` field is a `.node_and_token`: | ||
| 3152 | /// 1. a `Node.Index` to the left side of the field access. | ||
| 3153 | /// 2. a `TokenIndex` to the field name identifier. | ||
| 3154 | /// | ||
| 3155 | /// The `main_token` field is the `.` token. | ||
| 3069 | field_access, | 3156 | field_access, |
| 3070 | /// `lhs.?`. main_token is the dot. rhs is the `?` token index. | 3157 | /// `lhs.?`. |
| 3158 | /// | ||
| 3159 | /// The `data` field is a `.node_and_token`: | ||
| 3160 | /// 1. a `Node.Index` to the left side of the optional unwrap. | ||
| 3161 | /// 2. a `TokenIndex` to the `?` token. | ||
| 3162 | /// | ||
| 3163 | /// The `main_token` field is the `.` token. | ||
| 3071 | unwrap_optional, | 3164 | unwrap_optional, |
| 3072 | /// `lhs == rhs`. main_token is op. | 3165 | /// `lhs == rhs`. The `main_token` field is the `==` token. |
| 3073 | equal_equal, | 3166 | equal_equal, |
| 3074 | /// `lhs != rhs`. main_token is op. | 3167 | /// `lhs != rhs`. The `main_token` field is the `!=` token. |
| 3075 | bang_equal, | 3168 | bang_equal, |
| 3076 | /// `lhs < rhs`. main_token is op. | 3169 | /// `lhs < rhs`. The `main_token` field is the `<` token. |
| 3077 | less_than, | 3170 | less_than, |
| 3078 | /// `lhs > rhs`. main_token is op. | 3171 | /// `lhs > rhs`. The `main_token` field is the `>` token. |
| 3079 | greater_than, | 3172 | greater_than, |
| 3080 | /// `lhs <= rhs`. main_token is op. | 3173 | /// `lhs <= rhs`. The `main_token` field is the `<=` token. |
| 3081 | less_or_equal, | 3174 | less_or_equal, |
| 3082 | /// `lhs >= rhs`. main_token is op. | 3175 | /// `lhs >= rhs`. The `main_token` field is the `>=` token. |
| 3083 | greater_or_equal, | 3176 | greater_or_equal, |
| 3084 | /// `lhs *= rhs`. main_token is op. | 3177 | /// `lhs *= rhs`. The `main_token` field is the `*=` token. |
| 3085 | assign_mul, | 3178 | assign_mul, |
| 3086 | /// `lhs /= rhs`. main_token is op. | 3179 | /// `lhs /= rhs`. The `main_token` field is the `/=` token. |
| 3087 | assign_div, | 3180 | assign_div, |
| 3088 | /// `lhs %= rhs`. main_token is op. | 3181 | /// `lhs %= rhs`. The `main_token` field is the `%=` token. |
| 3089 | assign_mod, | 3182 | assign_mod, |
| 3090 | /// `lhs += rhs`. main_token is op. | 3183 | /// `lhs += rhs`. The `main_token` field is the `+=` token. |
| 3091 | assign_add, | 3184 | assign_add, |
| 3092 | /// `lhs -= rhs`. main_token is op. | 3185 | /// `lhs -= rhs`. The `main_token` field is the `-=` token. |
| 3093 | assign_sub, | 3186 | assign_sub, |
| 3094 | /// `lhs <<= rhs`. main_token is op. | 3187 | /// `lhs <<= rhs`. The `main_token` field is the `<<=` token. |
| 3095 | assign_shl, | 3188 | assign_shl, |
| 3096 | /// `lhs <<|= rhs`. main_token is op. | 3189 | /// `lhs <<|= rhs`. The `main_token` field is the `<<|=` token. |
| 3097 | assign_shl_sat, | 3190 | assign_shl_sat, |
| 3098 | /// `lhs >>= rhs`. main_token is op. | 3191 | /// `lhs >>= rhs`. The `main_token` field is the `>>=` token. |
| 3099 | assign_shr, | 3192 | assign_shr, |
| 3100 | /// `lhs &= rhs`. main_token is op. | 3193 | /// `lhs &= rhs`. The `main_token` field is the `&=` token. |
| 3101 | assign_bit_and, | 3194 | assign_bit_and, |
| 3102 | /// `lhs ^= rhs`. main_token is op. | 3195 | /// `lhs ^= rhs`. The `main_token` field is the `^=` token. |
| 3103 | assign_bit_xor, | 3196 | assign_bit_xor, |
| 3104 | /// `lhs |= rhs`. main_token is op. | 3197 | /// `lhs |= rhs`. The `main_token` field is the `|=` token. |
| 3105 | assign_bit_or, | 3198 | assign_bit_or, |
| 3106 | /// `lhs *%= rhs`. main_token is op. | 3199 | /// `lhs *%= rhs`. The `main_token` field is the `*%=` token. |
| 3107 | assign_mul_wrap, | 3200 | assign_mul_wrap, |
| 3108 | /// `lhs +%= rhs`. main_token is op. | 3201 | /// `lhs +%= rhs`. The `main_token` field is the `+%=` token. |
| 3109 | assign_add_wrap, | 3202 | assign_add_wrap, |
| 3110 | /// `lhs -%= rhs`. main_token is op. | 3203 | /// `lhs -%= rhs`. The `main_token` field is the `-%=` token. |
| 3111 | assign_sub_wrap, | 3204 | assign_sub_wrap, |
| 3112 | /// `lhs *|= rhs`. main_token is op. | 3205 | /// `lhs *|= rhs`. The `main_token` field is the `*%=` token. |
| 3113 | assign_mul_sat, | 3206 | assign_mul_sat, |
| 3114 | /// `lhs +|= rhs`. main_token is op. | 3207 | /// `lhs +|= rhs`. The `main_token` field is the `+|=` token. |
| 3115 | assign_add_sat, | 3208 | assign_add_sat, |
| 3116 | /// `lhs -|= rhs`. main_token is op. | 3209 | /// `lhs -|= rhs`. The `main_token` field is the `-|=` token. |
| 3117 | assign_sub_sat, | 3210 | assign_sub_sat, |
| 3118 | /// `lhs = rhs`. main_token is op. | 3211 | /// `lhs = rhs`. The `main_token` field is the `=` token. |
| 3119 | assign, | 3212 | assign, |
| 3120 | /// `a, b, ... = rhs`. main_token is op. lhs is index into `extra_data` | 3213 | /// `a, b, ... = rhs`. |
| 3121 | /// of an lhs elem count followed by an array of that many `Node.Index`, | 3214 | /// |
| 3122 | /// with each node having one of the following types: | 3215 | /// The `data` field is a `.extra_and_node`: |
| 3123 | /// * `global_var_decl` | 3216 | /// 1. a `ExtraIndex`. Further explained below. |
| 3124 | /// * `local_var_decl` | 3217 | /// 2. a `Node.Index` to the initialization expression. |
| 3125 | /// * `simple_var_decl` | 3218 | /// |
| 3126 | /// * `aligned_var_decl` | 3219 | /// The `main_token` field is the `=` token. |
| 3127 | /// * Any expression node | 3220 | /// |
| 3128 | /// The first 3 types correspond to a `var` or `const` lhs node (note | 3221 | /// The `ExtraIndex` stores the following data: |
| 3129 | /// that their `rhs` is always 0). An expression node corresponds to a | 3222 | /// ``` |
| 3130 | /// standard assignment LHS (which must be evaluated as an lvalue). | 3223 | /// elem_count: u32, |
| 3131 | /// There may be a preceding `comptime` token, which does not create a | 3224 | /// variables: [elem_count]Node.Index, |
| 3132 | /// corresponding `comptime` node so must be manually detected. | 3225 | /// ``` |
| 3226 | /// | ||
| 3227 | /// Each node in `variables` has one of the following tags: | ||
| 3228 | /// - `global_var_decl` | ||
| 3229 | /// - `local_var_decl` | ||
| 3230 | /// - `simple_var_decl` | ||
| 3231 | /// - `aligned_var_decl` | ||
| 3232 | /// - Any expression node | ||
| 3233 | /// | ||
| 3234 | /// The first 4 tags correspond to a `var` or `const` lhs node (note | ||
| 3235 | /// that their initialization expression is always `.none`). | ||
| 3236 | /// An expression node corresponds to a standard assignment LHS (which | ||
| 3237 | /// must be evaluated as an lvalue). There may be a preceding | ||
| 3238 | /// `comptime` token, which does not create a corresponding `comptime` | ||
| 3239 | /// node so must be manually detected. | ||
| 3133 | assign_destructure, | 3240 | assign_destructure, |
| 3134 | /// `lhs || rhs`. main_token is the `||`. | 3241 | /// `lhs || rhs`. The `main_token` field is the `||` token. |
| 3135 | merge_error_sets, | 3242 | merge_error_sets, |
| 3136 | /// `lhs * rhs`. main_token is the `*`. | 3243 | /// `lhs * rhs`. The `main_token` field is the `*` token. |
| 3137 | mul, | 3244 | mul, |
| 3138 | /// `lhs / rhs`. main_token is the `/`. | 3245 | /// `lhs / rhs`. The `main_token` field is the `/` token. |
| 3139 | div, | 3246 | div, |
| 3140 | /// `lhs % rhs`. main_token is the `%`. | 3247 | /// `lhs % rhs`. The `main_token` field is the `%` token. |
| 3141 | mod, | 3248 | mod, |
| 3142 | /// `lhs ** rhs`. main_token is the `**`. | 3249 | /// `lhs ** rhs`. The `main_token` field is the `**` token. |
| 3143 | array_mult, | 3250 | array_mult, |
| 3144 | /// `lhs *% rhs`. main_token is the `*%`. | 3251 | /// `lhs *% rhs`. The `main_token` field is the `*%` token. |
| 3145 | mul_wrap, | 3252 | mul_wrap, |
| 3146 | /// `lhs *| rhs`. main_token is the `*|`. | 3253 | /// `lhs *| rhs`. The `main_token` field is the `*|` token. |
| 3147 | mul_sat, | 3254 | mul_sat, |
| 3148 | /// `lhs + rhs`. main_token is the `+`. | 3255 | /// `lhs + rhs`. The `main_token` field is the `+` token. |
| 3149 | add, | 3256 | add, |
| 3150 | /// `lhs - rhs`. main_token is the `-`. | 3257 | /// `lhs - rhs`. The `main_token` field is the `-` token. |
| 3151 | sub, | 3258 | sub, |
| 3152 | /// `lhs ++ rhs`. main_token is the `++`. | 3259 | /// `lhs ++ rhs`. The `main_token` field is the `++` token. |
| 3153 | array_cat, | 3260 | array_cat, |
| 3154 | /// `lhs +% rhs`. main_token is the `+%`. | 3261 | /// `lhs +% rhs`. The `main_token` field is the `+%` token. |
| 3155 | add_wrap, | 3262 | add_wrap, |
| 3156 | /// `lhs -% rhs`. main_token is the `-%`. | 3263 | /// `lhs -% rhs`. The `main_token` field is the `-%` token. |
| 3157 | sub_wrap, | 3264 | sub_wrap, |
| 3158 | /// `lhs +| rhs`. main_token is the `+|`. | 3265 | /// `lhs +| rhs`. The `main_token` field is the `+|` token. |
| 3159 | add_sat, | 3266 | add_sat, |
| 3160 | /// `lhs -| rhs`. main_token is the `-|`. | 3267 | /// `lhs -| rhs`. The `main_token` field is the `-|` token. |
| 3161 | sub_sat, | 3268 | sub_sat, |
| 3162 | /// `lhs << rhs`. main_token is the `<<`. | 3269 | /// `lhs << rhs`. The `main_token` field is the `<<` token. |
| 3163 | shl, | 3270 | shl, |
| 3164 | /// `lhs <<| rhs`. main_token is the `<<|`. | 3271 | /// `lhs <<| rhs`. The `main_token` field is the `<<|` token. |
| 3165 | shl_sat, | 3272 | shl_sat, |
| 3166 | /// `lhs >> rhs`. main_token is the `>>`. | 3273 | /// `lhs >> rhs`. The `main_token` field is the `>>` token. |
| 3167 | shr, | 3274 | shr, |
| 3168 | /// `lhs & rhs`. main_token is the `&`. | 3275 | /// `lhs & rhs`. The `main_token` field is the `&` token. |
| 3169 | bit_and, | 3276 | bit_and, |
| 3170 | /// `lhs ^ rhs`. main_token is the `^`. | 3277 | /// `lhs ^ rhs`. The `main_token` field is the `^` token. |
| 3171 | bit_xor, | 3278 | bit_xor, |
| 3172 | /// `lhs | rhs`. main_token is the `|`. | 3279 | /// `lhs | rhs`. The `main_token` field is the `|` token. |
| 3173 | bit_or, | 3280 | bit_or, |
| 3174 | /// `lhs orelse rhs`. main_token is the `orelse`. | 3281 | /// `lhs orelse rhs`. The `main_token` field is the `orelse` token. |
| 3175 | @"orelse", | 3282 | @"orelse", |
| 3176 | /// `lhs and rhs`. main_token is the `and`. | 3283 | /// `lhs and rhs`. The `main_token` field is the `and` token. |
| 3177 | bool_and, | 3284 | bool_and, |
| 3178 | /// `lhs or rhs`. main_token is the `or`. | 3285 | /// `lhs or rhs`. The `main_token` field is the `or` token. |
| 3179 | bool_or, | 3286 | bool_or, |
| 3180 | /// `op lhs`. rhs unused. main_token is op. | 3287 | /// `!expr`. The `main_token` field is the `!` token. |
| 3181 | bool_not, | 3288 | bool_not, |
| 3182 | /// `op lhs`. rhs unused. main_token is op. | 3289 | /// `-expr`. The `main_token` field is the `-` token. |
| 3183 | negation, | 3290 | negation, |
| 3184 | /// `op lhs`. rhs unused. main_token is op. | 3291 | /// `~expr`. The `main_token` field is the `~` token. |
| 3185 | bit_not, | 3292 | bit_not, |
| 3186 | /// `op lhs`. rhs unused. main_token is op. | 3293 | /// `-%expr`. The `main_token` field is the `-%` token. |
| 3187 | negation_wrap, | 3294 | negation_wrap, |
| 3188 | /// `op lhs`. rhs unused. main_token is op. | 3295 | /// `&expr`. The `main_token` field is the `&` token. |
| 3189 | address_of, | 3296 | address_of, |
| 3190 | /// `op lhs`. rhs unused. main_token is op. | 3297 | /// `try expr`. The `main_token` field is the `try` token. |
| 3191 | @"try", | 3298 | @"try", |
| 3192 | /// `op lhs`. rhs unused. main_token is op. | 3299 | /// `await expr`. The `main_token` field is the `await` token. |
| 3193 | @"await", | 3300 | @"await", |
| 3194 | /// `?lhs`. rhs unused. main_token is the `?`. | 3301 | /// `?expr`. The `main_token` field is the `?` token. |
| 3195 | optional_type, | 3302 | optional_type, |
| 3196 | /// `[lhs]rhs`. | 3303 | /// `[lhs]rhs`. The `main_token` field is the `[` token. |
| 3197 | array_type, | 3304 | array_type, |
| 3198 | /// `[lhs:a]b`. `ArrayTypeSentinel[rhs]`. | 3305 | /// `[lhs:a]b`. |
| 3306 | /// | ||
| 3307 | /// The `data` field is a `.node_and_extra`: | ||
| 3308 | /// 1. a `Node.Index` to the length expression. | ||
| 3309 | /// 2. a `ExtraIndex` to `ArrayTypeSentinel`. | ||
| 3310 | /// | ||
| 3311 | /// The `main_token` field is the `[` token. | ||
| 3199 | array_type_sentinel, | 3312 | array_type_sentinel, |
| 3200 | /// `[*]align(lhs) rhs`. lhs can be omitted. | 3313 | /// `[*]align(lhs) rhs`, |
| 3201 | /// `*align(lhs) rhs`. lhs can be omitted. | 3314 | /// `*align(lhs) rhs`, |
| 3202 | /// `[]rhs`. | 3315 | /// `[]rhs`. |
| 3203 | /// main_token is the asterisk if a single item pointer or the lbracket | 3316 | /// |
| 3204 | /// if a slice, many-item pointer, or C-pointer | 3317 | /// The `data` field is a `.opt_node_and_node`: |
| 3205 | /// main_token might be a ** token, which is shared with a parent/child | 3318 | /// 1. a `Node.OptionalIndex` to the alignment expression, if any. |
| 3206 | /// pointer type and may require special handling. | 3319 | /// 2. a `Node.Index` to the element type expression. |
| 3320 | /// | ||
| 3321 | /// The `main_token` is the asterisk if a single item pointer or the | ||
| 3322 | /// lbracket if a slice, many-item pointer, or C-pointer. | ||
| 3323 | /// The `main_token` might be a ** token, which is shared with a | ||
| 3324 | /// parent/child pointer type and may require special handling. | ||
| 3207 | ptr_type_aligned, | 3325 | ptr_type_aligned, |
| 3208 | /// `[*:lhs]rhs`. lhs can be omitted. | 3326 | /// `[*:lhs]rhs`, |
| 3209 | /// `*rhs`. | 3327 | /// `*rhs`, |
| 3210 | /// `[:lhs]rhs`. | 3328 | /// `[:lhs]rhs`. |
| 3211 | /// main_token is the asterisk if a single item pointer or the lbracket | 3329 | /// |
| 3212 | /// if a slice, many-item pointer, or C-pointer | 3330 | /// The `data` field is a `.opt_node_and_node`: |
| 3213 | /// main_token might be a ** token, which is shared with a parent/child | 3331 | /// 1. a `Node.OptionalIndex` to the sentinel expression, if any. |
| 3214 | /// pointer type and may require special handling. | 3332 | /// 2. a `Node.Index` to the element type expression. |
| 3333 | /// | ||
| 3334 | /// The `main_token` is the asterisk if a single item pointer or the | ||
| 3335 | /// lbracket if a slice, many-item pointer, or C-pointer. | ||
| 3336 | /// The `main_token` might be a ** token, which is shared with a | ||
| 3337 | /// parent/child pointer type and may require special handling. | ||
| 3215 | ptr_type_sentinel, | 3338 | ptr_type_sentinel, |
| 3216 | /// lhs is index into ptr_type. rhs is the element type expression. | 3339 | /// The `data` field is a `.opt_node_and_node`: |
| 3217 | /// main_token is the asterisk if a single item pointer or the lbracket | 3340 | /// 1. a `ExtraIndex` to `PtrType`. |
| 3218 | /// if a slice, many-item pointer, or C-pointer | 3341 | /// 2. a `Node.Index` to the element type expression. |
| 3219 | /// main_token might be a ** token, which is shared with a parent/child | 3342 | /// |
| 3220 | /// pointer type and may require special handling. | 3343 | /// The `main_token` is the asterisk if a single item pointer or the |
| 3344 | /// lbracket if a slice, many-item pointer, or C-pointer. | ||
| 3345 | /// The `main_token` might be a ** token, which is shared with a | ||
| 3346 | /// parent/child pointer type and may require special handling. | ||
| 3221 | ptr_type, | 3347 | ptr_type, |
| 3222 | /// lhs is index into ptr_type_bit_range. rhs is the element type expression. | 3348 | /// The `data` field is a `.opt_node_and_node`: |
| 3223 | /// main_token is the asterisk if a single item pointer or the lbracket | 3349 | /// 1. a `ExtraIndex` to `PtrTypeBitRange`. |
| 3224 | /// if a slice, many-item pointer, or C-pointer | 3350 | /// 2. a `Node.Index` to the element type expression. |
| 3225 | /// main_token might be a ** token, which is shared with a parent/child | 3351 | /// |
| 3226 | /// pointer type and may require special handling. | 3352 | /// The `main_token` is the asterisk if a single item pointer or the |
| 3353 | /// lbracket if a slice, many-item pointer, or C-pointer. | ||
| 3354 | /// The `main_token` might be a ** token, which is shared with a | ||
| 3355 | /// parent/child pointer type and may require special handling. | ||
| 3227 | ptr_type_bit_range, | 3356 | ptr_type_bit_range, |
| 3228 | /// `lhs[rhs..]` | 3357 | /// `lhs[rhs..]` |
| 3229 | /// main_token is the lbracket. | 3358 | /// |
| 3359 | /// The `main_token` field is the `[` token. | ||
| 3230 | slice_open, | 3360 | slice_open, |
| 3231 | /// `lhs[b..c]`. rhs is index into Slice | 3361 | /// `sliced[start..end]`. |
| 3232 | /// main_token is the lbracket. | 3362 | /// |
| 3363 | /// The `data` field is a `.node_and_extra`: | ||
| 3364 | /// 1. a `Node.Index` to the sliced expression. | ||
| 3365 | /// 2. a `ExtraIndex` to `Slice`. | ||
| 3366 | /// | ||
| 3367 | /// The `main_token` field is the `[` token. | ||
| 3233 | slice, | 3368 | slice, |
| 3234 | /// `lhs[b..c :d]`. rhs is index into SliceSentinel. Slice end "c" can be omitted. | 3369 | /// `sliced[start..end :sentinel]`, |
| 3235 | /// main_token is the lbracket. | 3370 | /// `sliced[start.. :sentinel]`. |
| 3371 | /// | ||
| 3372 | /// The `data` field is a `.node_and_extra`: | ||
| 3373 | /// 1. a `Node.Index` to the sliced expression. | ||
| 3374 | /// 2. a `ExtraIndex` to `SliceSentinel`. | ||
| 3375 | /// | ||
| 3376 | /// The `main_token` field is the `[` token. | ||
| 3236 | slice_sentinel, | 3377 | slice_sentinel, |
| 3237 | /// `lhs.*`. rhs is unused. | 3378 | /// `expr.*`. |
| 3379 | /// | ||
| 3380 | /// The `data` field is a `.node` to expr. | ||
| 3381 | /// | ||
| 3382 | /// The `main_token` field is the `*` token. | ||
| 3238 | deref, | 3383 | deref, |
| 3239 | /// `lhs[rhs]`. | 3384 | /// `lhs[rhs]`. |
| 3385 | /// | ||
| 3386 | /// The `main_token` field is the `[` token. | ||
| 3240 | array_access, | 3387 | array_access, |
| 3241 | /// `lhs{rhs}`. rhs can be omitted. | 3388 | /// `lhs{rhs}`. |
| 3389 | /// | ||
| 3390 | /// The `main_token` field is the `{` token. | ||
| 3242 | array_init_one, | 3391 | array_init_one, |
| 3243 | /// `lhs{rhs,}`. rhs can *not* be omitted | 3392 | /// Same as `array_init_one` except there is known to be a trailing |
| 3393 | /// comma before the final rbrace. | ||
| 3244 | array_init_one_comma, | 3394 | array_init_one_comma, |
| 3245 | /// `.{lhs, rhs}`. lhs and rhs can be omitted. | 3395 | /// `.{a}`, |
| 3396 | /// `.{a, b}`. | ||
| 3397 | /// | ||
| 3398 | /// The `data` field is a `.opt_node_and_opt_node`: | ||
| 3399 | /// 1. a `Node.OptionalIndex` to the first element. Never `.none` | ||
| 3400 | /// 2. a `Node.OptionalIndex` to the second element, if any. | ||
| 3401 | /// | ||
| 3402 | /// The `main_token` field is the `{` token. | ||
| 3246 | array_init_dot_two, | 3403 | array_init_dot_two, |
| 3247 | /// Same as `array_init_dot_two` except there is known to be a trailing comma | 3404 | /// Same as `array_init_dot_two` except there is known to be a trailing |
| 3248 | /// before the final rbrace. | 3405 | /// comma before the final rbrace. |
| 3249 | array_init_dot_two_comma, | 3406 | array_init_dot_two_comma, |
| 3250 | /// `.{a, b}`. `sub_list[lhs..rhs]`. | 3407 | /// `.{a, b, c}`. |
| 3408 | /// | ||
| 3409 | /// The `data` field is a `.extra_range` that stores a `Node.Index` for | ||
| 3410 | /// each element. | ||
| 3411 | /// | ||
| 3412 | /// The `main_token` field is the `{` token. | ||
| 3251 | array_init_dot, | 3413 | array_init_dot, |
| 3252 | /// Same as `array_init_dot` except there is known to be a trailing comma | 3414 | /// Same as `array_init_dot` except there is known to be a trailing |
| 3253 | /// before the final rbrace. | 3415 | /// comma before the final rbrace. |
| 3254 | array_init_dot_comma, | 3416 | array_init_dot_comma, |
| 3255 | /// `lhs{a, b}`. `sub_range_list[rhs]`. lhs can be omitted which means `.{a, b}`. | 3417 | /// `a{b, c}`. |
| 3418 | /// | ||
| 3419 | /// The `data` field is a `.node_and_extra`: | ||
| 3420 | /// 1. a `Node.Index` to the type expression. | ||
| 3421 | /// 2. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for | ||
| 3422 | /// each element. | ||
| 3423 | /// | ||
| 3424 | /// The `main_token` field is the `{` token. | ||
| 3256 | array_init, | 3425 | array_init, |
| 3257 | /// Same as `array_init` except there is known to be a trailing comma | 3426 | /// Same as `array_init` except there is known to be a trailing comma |
| 3258 | /// before the final rbrace. | 3427 | /// before the final rbrace. |
| 3259 | array_init_comma, | 3428 | array_init_comma, |
| 3260 | /// `lhs{.a = rhs}`. rhs can be omitted making it empty. | 3429 | /// `a{.x = b}`, `a{}`. |
| 3261 | /// main_token is the lbrace. | 3430 | /// |
| 3431 | /// The `data` field is a `.node_and_opt_node`: | ||
| 3432 | /// 1. a `Node.Index` to the type expression. | ||
| 3433 | /// 2. a `Node.OptionalIndex` to the first field initialization, if any. | ||
| 3434 | /// | ||
| 3435 | /// The `main_token` field is the `{` token. | ||
| 3436 | /// | ||
| 3437 | /// The field name is determined by looking at the tokens preceding the | ||
| 3438 | /// field initialization. | ||
| 3262 | struct_init_one, | 3439 | struct_init_one, |
| 3263 | /// `lhs{.a = rhs,}`. rhs can *not* be omitted. | 3440 | /// Same as `struct_init_one` except there is known to be a trailing comma |
| 3264 | /// main_token is the lbrace. | 3441 | /// before the final rbrace. |
| 3265 | struct_init_one_comma, | 3442 | struct_init_one_comma, |
| 3266 | /// `.{.a = lhs, .b = rhs}`. lhs and rhs can be omitted. | 3443 | /// `.{.x = a, .y = b}`. |
| 3267 | /// main_token is the lbrace. | 3444 | /// |
| 3268 | /// No trailing comma before the rbrace. | 3445 | /// The `data` field is a `.opt_node_and_opt_node`: |
| 3446 | /// 1. a `Node.OptionalIndex` to the first field initialization. Never `.none` | ||
| 3447 | /// 2. a `Node.OptionalIndex` to the second field initialization, if any. | ||
| 3448 | /// | ||
| 3449 | /// The `main_token` field is the '{' token. | ||
| 3450 | /// | ||
| 3451 | /// The field name is determined by looking at the tokens preceding the | ||
| 3452 | /// field initialization. | ||
| 3269 | struct_init_dot_two, | 3453 | struct_init_dot_two, |
| 3270 | /// Same as `struct_init_dot_two` except there is known to be a trailing comma | 3454 | /// Same as `struct_init_dot_two` except there is known to be a trailing |
| 3271 | /// before the final rbrace. | 3455 | /// comma before the final rbrace. |
| 3272 | struct_init_dot_two_comma, | 3456 | struct_init_dot_two_comma, |
| 3273 | /// `.{.a = b, .c = d}`. `sub_list[lhs..rhs]`. | 3457 | /// `.{.x = a, .y = b, .z = c}`. |
| 3274 | /// main_token is the lbrace. | 3458 | /// |
| 3459 | /// The `data` field is a `.extra_range` that stores a `Node.Index` for | ||
| 3460 | /// each field initialization. | ||
| 3461 | /// | ||
| 3462 | /// The `main_token` field is the `{` token. | ||
| 3463 | /// | ||
| 3464 | /// The field name is determined by looking at the tokens preceding the | ||
| 3465 | /// field initialization. | ||
| 3275 | struct_init_dot, | 3466 | struct_init_dot, |
| 3276 | /// Same as `struct_init_dot` except there is known to be a trailing comma | 3467 | /// Same as `struct_init_dot` except there is known to be a trailing |
| 3277 | /// before the final rbrace. | 3468 | /// comma before the final rbrace. |
| 3278 | struct_init_dot_comma, | 3469 | struct_init_dot_comma, |
| 3279 | /// `lhs{.a = b, .c = d}`. `sub_range_list[rhs]`. | 3470 | /// `a{.x = b, .y = c}`. |
| 3280 | /// lhs can be omitted which means `.{.a = b, .c = d}`. | 3471 | /// |
| 3281 | /// main_token is the lbrace. | 3472 | /// The `data` field is a `.node_and_extra`: |
| 3473 | /// 1. a `Node.Index` to the type expression. | ||
| 3474 | /// 2. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for | ||
| 3475 | /// each field initialization. | ||
| 3476 | /// | ||
| 3477 | /// The `main_token` field is the `{` token. | ||
| 3478 | /// | ||
| 3479 | /// The field name is determined by looking at the tokens preceding the | ||
| 3480 | /// field initialization. | ||
| 3282 | struct_init, | 3481 | struct_init, |
| 3283 | /// Same as `struct_init` except there is known to be a trailing comma | 3482 | /// Same as `struct_init` except there is known to be a trailing comma |
| 3284 | /// before the final rbrace. | 3483 | /// before the final rbrace. |
| 3285 | struct_init_comma, | 3484 | struct_init_comma, |
| 3286 | /// `lhs(rhs)`. rhs can be omitted. | 3485 | /// `a(b)`, `a()`. |
| 3287 | /// main_token is the lparen. | 3486 | /// |
| 3487 | /// The `data` field is a `.node_and_opt_node`: | ||
| 3488 | /// 1. a `Node.Index` to the function expression. | ||
| 3489 | /// 2. a `Node.OptionalIndex` to the first argument, if any. | ||
| 3490 | /// | ||
| 3491 | /// The `main_token` field is the `(` token. | ||
| 3288 | call_one, | 3492 | call_one, |
| 3289 | /// `lhs(rhs,)`. rhs can be omitted. | 3493 | /// Same as `call_one` except there is known to be a trailing comma |
| 3290 | /// main_token is the lparen. | 3494 | /// before the final rparen. |
| 3291 | call_one_comma, | 3495 | call_one_comma, |
| 3292 | /// `async lhs(rhs)`. rhs can be omitted. | 3496 | /// `async a(b)`, `async a()`. |
| 3497 | /// | ||
| 3498 | /// The `data` field is a `.node_and_opt_node`: | ||
| 3499 | /// 1. a `Node.Index` to the function expression. | ||
| 3500 | /// 2. a `Node.OptionalIndex` to the first argument, if any. | ||
| 3501 | /// | ||
| 3502 | /// The `main_token` field is the `(` token. | ||
| 3293 | async_call_one, | 3503 | async_call_one, |
| 3294 | /// `async lhs(rhs,)`. | 3504 | /// Same as `async_call_one` except there is known to be a trailing |
| 3505 | /// comma before the final rparen. | ||
| 3295 | async_call_one_comma, | 3506 | async_call_one_comma, |
| 3296 | /// `lhs(a, b, c)`. `SubRange[rhs]`. | 3507 | /// `a(b, c, d)`. |
| 3297 | /// main_token is the `(`. | 3508 | /// |
| 3509 | /// The `data` field is a `.node_and_extra`: | ||
| 3510 | /// 1. a `Node.Index` to the function expression. | ||
| 3511 | /// 2. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for | ||
| 3512 | /// each argument. | ||
| 3513 | /// | ||
| 3514 | /// The `main_token` field is the `(` token. | ||
| 3298 | call, | 3515 | call, |
| 3299 | /// `lhs(a, b, c,)`. `SubRange[rhs]`. | 3516 | /// Same as `call` except there is known to be a trailing comma before |
| 3300 | /// main_token is the `(`. | 3517 | /// the final rparen. |
| 3301 | call_comma, | 3518 | call_comma, |
| 3302 | /// `async lhs(a, b, c)`. `SubRange[rhs]`. | 3519 | /// `async a(b, c, d)`. |
| 3303 | /// main_token is the `(`. | 3520 | /// |
| 3521 | /// The `data` field is a `.node_and_extra`: | ||
| 3522 | /// 1. a `Node.Index` to the function expression. | ||
| 3523 | /// 2. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for | ||
| 3524 | /// each argument. | ||
| 3525 | /// | ||
| 3526 | /// The `main_token` field is the `(` token. | ||
| 3304 | async_call, | 3527 | async_call, |
| 3305 | /// `async lhs(a, b, c,)`. `SubRange[rhs]`. | 3528 | /// Same as `async_call` except there is known to be a trailing comma |
| 3306 | /// main_token is the `(`. | 3529 | /// before the final rparen. |
| 3307 | async_call_comma, | 3530 | async_call_comma, |
| 3308 | /// `switch(lhs) {}`. `SubRange[rhs]`. | 3531 | /// `switch(a) {}`. |
| 3309 | /// `main_token` is the identifier of a preceding label, if any; otherwise `switch`. | 3532 | /// |
| 3533 | /// The `data` field is a `.node_and_extra`: | ||
| 3534 | /// 1. a `Node.Index` to the switch operand. | ||
| 3535 | /// 2. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for | ||
| 3536 | /// each switch case. | ||
| 3537 | /// | ||
| 3538 | /// `The `main_token` field` is the identifier of a preceding label, if any; otherwise `switch`. | ||
| 3310 | @"switch", | 3539 | @"switch", |
| 3311 | /// Same as switch except there is known to be a trailing comma | 3540 | /// Same as `switch` except there is known to be a trailing comma before |
| 3312 | /// before the final rbrace | 3541 | /// the final rbrace. |
| 3313 | switch_comma, | 3542 | switch_comma, |
| 3314 | /// `lhs => rhs`. If lhs is omitted it means `else`. | 3543 | /// `a => b`, |
| 3315 | /// main_token is the `=>` | 3544 | /// `else => b`. |
| 3545 | /// | ||
| 3546 | /// The `data` field is a `.opt_node_and_node`: | ||
| 3547 | /// 1. a `Node.OptionalIndex` where `.none` means `else`. | ||
| 3548 | /// 2. a `Node.Index` to the target expression. | ||
| 3549 | /// | ||
| 3550 | /// The `main_token` field is the `=>` token. | ||
| 3316 | switch_case_one, | 3551 | switch_case_one, |
| 3317 | /// Same ast `switch_case_one` but the case is inline | 3552 | /// Same as `switch_case_one` but the case is inline. |
| 3318 | switch_case_inline_one, | 3553 | switch_case_inline_one, |
| 3319 | /// `a, b, c => rhs`. `SubRange[lhs]`. | 3554 | /// `a, b, c => d`. |
| 3320 | /// main_token is the `=>` | 3555 | /// |
| 3556 | /// The `data` field is a `.extra_and_node`: | ||
| 3557 | /// 1. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for | ||
| 3558 | /// each switch item. | ||
| 3559 | /// 2. a `Node.Index` to the target expression. | ||
| 3560 | /// | ||
| 3561 | /// The `main_token` field is the `=>` token. | ||
| 3321 | switch_case, | 3562 | switch_case, |
| 3322 | /// Same ast `switch_case` but the case is inline | 3563 | /// Same as `switch_case` but the case is inline. |
| 3323 | switch_case_inline, | 3564 | switch_case_inline, |
| 3324 | /// `lhs...rhs`. | 3565 | /// `lhs...rhs`. |
| 3566 | /// | ||
| 3567 | /// The `main_token` field is the `...` token. | ||
| 3325 | switch_range, | 3568 | switch_range, |
| 3326 | /// `while (lhs) rhs`. | 3569 | /// `while (a) b`, |
| 3327 | /// `while (lhs) |x| rhs`. | 3570 | /// `while (a) |x| b`. |
| 3328 | while_simple, | 3571 | while_simple, |
| 3329 | /// `while (lhs) : (a) b`. `WhileCont[rhs]`. | 3572 | /// `while (a) : (b) c`, |
| 3330 | /// `while (lhs) : (a) b`. `WhileCont[rhs]`. | 3573 | /// `while (a) |x| : (b) c`. |
| 3331 | while_cont, | 3574 | while_cont, |
| 3332 | /// `while (lhs) : (a) b else c`. `While[rhs]`. | 3575 | /// `while (a) : (b) c else d`, |
| 3333 | /// `while (lhs) |x| : (a) b else c`. `While[rhs]`. | 3576 | /// `while (a) |x| : (b) c else d`, |
| 3334 | /// `while (lhs) |x| : (a) b else |y| c`. `While[rhs]`. | 3577 | /// `while (a) |x| : (b) c else |y| d`. |
| 3335 | /// The cont expression part `: (a)` may be omitted. | 3578 | /// The continue expression part `: (b)` may be omitted. |
| 3336 | @"while", | 3579 | @"while", |
| 3337 | /// `for (lhs) rhs`. | 3580 | /// `for (a) b`. |
| 3338 | for_simple, | 3581 | for_simple, |
| 3339 | /// `for (lhs[0..inputs]) lhs[inputs + 1] else lhs[inputs + 2]`. `For[rhs]`. | 3582 | /// `for (lhs[0..inputs]) lhs[inputs + 1] else lhs[inputs + 2]`. `For[rhs]`. |
| 3340 | @"for", | 3583 | @"for", |
| 3341 | /// `lhs..rhs`. rhs can be omitted. | 3584 | /// `lhs..rhs`, `lhs..`. |
| 3342 | for_range, | 3585 | for_range, |
| 3343 | /// `if (lhs) rhs`. | 3586 | /// `if (a) b`. |
| 3344 | /// `if (lhs) |a| rhs`. | 3587 | /// `if (b) |x| b`. |
| 3345 | if_simple, | 3588 | if_simple, |
| 3346 | /// `if (lhs) a else b`. `If[rhs]`. | 3589 | /// `if (a) b else c`. |
| 3347 | /// `if (lhs) |x| a else b`. `If[rhs]`. | 3590 | /// `if (a) |x| b else c`. |
| 3348 | /// `if (lhs) |x| a else |y| b`. `If[rhs]`. | 3591 | /// `if (a) |x| b else |y| d`. |
| 3349 | @"if", | 3592 | @"if", |
| 3350 | /// `suspend lhs`. lhs can be omitted. rhs is unused. | 3593 | /// `suspend expr`. |
| 3594 | /// | ||
| 3595 | /// The `data` field is a `.node` to expr. | ||
| 3596 | /// | ||
| 3597 | /// The `main_token` field is the `suspend` token. | ||
| 3351 | @"suspend", | 3598 | @"suspend", |
| 3352 | /// `resume lhs`. rhs is unused. | 3599 | /// `resume expr`. |
| 3600 | /// | ||
| 3601 | /// The `data` field is a `.node` to expr. | ||
| 3602 | /// | ||
| 3603 | /// The `main_token` field is the `resume` token. | ||
| 3353 | @"resume", | 3604 | @"resume", |
| 3354 | /// `continue :lhs rhs` | 3605 | /// `continue :label expr`, |
| 3355 | /// both lhs and rhs may be omitted. | 3606 | /// `continue expr`, |
| 3607 | /// `continue :label`, | ||
| 3608 | /// `continue`. | ||
| 3609 | /// | ||
| 3610 | /// The `data` field is a `.opt_token_and_opt_node`: | ||
| 3611 | /// 1. a `OptionalTokenIndex` to the label identifier, if any. | ||
| 3612 | /// 2. a `Node.OptionalIndex` to the target expression, if any. | ||
| 3613 | /// | ||
| 3614 | /// The `main_token` field is the `continue` token. | ||
| 3356 | @"continue", | 3615 | @"continue", |
| 3357 | /// `break :lhs rhs` | 3616 | /// `break :label expr`, |
| 3358 | /// both lhs and rhs may be omitted. | 3617 | /// `break expr`, |
| 3618 | /// `break :label`, | ||
| 3619 | /// `break`. | ||
| 3620 | /// | ||
| 3621 | /// The `data` field is a `.opt_token_and_opt_node`: | ||
| 3622 | /// 1. a `OptionalTokenIndex` to the label identifier, if any. | ||
| 3623 | /// 2. a `Node.OptionalIndex` to the target expression, if any. | ||
| 3624 | /// | ||
| 3625 | /// The `main_token` field is the `break` token. | ||
| 3359 | @"break", | 3626 | @"break", |
| 3360 | /// `return lhs`. lhs can be omitted. rhs is unused. | 3627 | /// `return expr`, `return`. |
| 3628 | /// | ||
| 3629 | /// The `data` field is a `.opt_node` to the return value, if any. | ||
| 3630 | /// | ||
| 3631 | /// The `main_token` field is the `return` token. | ||
| 3361 | @"return", | 3632 | @"return", |
| 3362 | /// `fn (a: lhs) rhs`. lhs can be omitted. | 3633 | /// `fn (a: type_expr) return_type`. |
| 3363 | /// anytype and ... parameters are omitted from the AST tree. | 3634 | /// |
| 3364 | /// main_token is the `fn` keyword. | 3635 | /// The `data` field is a `.opt_node_and_opt_node`: |
| 3365 | /// extern function declarations use this tag. | 3636 | /// 1. a `Node.OptionalIndex` to the first parameter type expression, if any. |
| 3637 | /// 2. a `Node.OptionalIndex` to the return type expression. Can't be | ||
| 3638 | /// `.none` unless a parsing error occured. | ||
| 3639 | /// | ||
| 3640 | /// The `main_token` field is the `fn` token. | ||
| 3641 | /// | ||
| 3642 | /// `anytype` and `...` parameters are omitted from the AST tree. | ||
| 3643 | /// Extern function declarations use this tag. | ||
| 3366 | fn_proto_simple, | 3644 | fn_proto_simple, |
| 3367 | /// `fn (a: b, c: d) rhs`. `sub_range_list[lhs]`. | 3645 | /// `fn (a: b, c: d) return_type`. |
| 3368 | /// anytype and ... parameters are omitted from the AST tree. | 3646 | /// |
| 3369 | /// main_token is the `fn` keyword. | 3647 | /// The `data` field is a `.extra_and_opt_node`: |
| 3370 | /// extern function declarations use this tag. | 3648 | /// 1. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for |
| 3649 | /// each parameter type expression. | ||
| 3650 | /// 2. a `Node.OptionalIndex` to the return type expression. Can't be | ||
| 3651 | /// `.none` unless a parsing error occured. | ||
| 3652 | /// | ||
| 3653 | /// The `main_token` field is the `fn` token. | ||
| 3654 | /// | ||
| 3655 | /// `anytype` and `...` parameters are omitted from the AST tree. | ||
| 3656 | /// Extern function declarations use this tag. | ||
| 3371 | fn_proto_multi, | 3657 | fn_proto_multi, |
| 3372 | /// `fn (a: b) addrspace(e) linksection(f) callconv(g) rhs`. `FnProtoOne[lhs]`. | 3658 | /// `fn (a: b) addrspace(e) linksection(f) callconv(g) return_type`. |
| 3373 | /// zero or one parameters. | 3659 | /// zero or one parameters. |
| 3374 | /// anytype and ... parameters are omitted from the AST tree. | 3660 | /// |
| 3375 | /// main_token is the `fn` keyword. | 3661 | /// The `data` field is a `.extra_and_opt_node`: |
| 3376 | /// extern function declarations use this tag. | 3662 | /// 1. a `Node.ExtraIndex` to `FnProtoOne`. |
| 3663 | /// 2. a `Node.OptionalIndex` to the return type expression. Can't be | ||
| 3664 | /// `.none` unless a parsing error occured. | ||
| 3665 | /// | ||
| 3666 | /// The `main_token` field is the `fn` token. | ||
| 3667 | /// | ||
| 3668 | /// `anytype` and `...` parameters are omitted from the AST tree. | ||
| 3669 | /// Extern function declarations use this tag. | ||
| 3377 | fn_proto_one, | 3670 | fn_proto_one, |
| 3378 | /// `fn (a: b, c: d) addrspace(e) linksection(f) callconv(g) rhs`. `FnProto[lhs]`. | 3671 | /// `fn (a: b, c: d) addrspace(e) linksection(f) callconv(g) return_type`. |
| 3379 | /// anytype and ... parameters are omitted from the AST tree. | 3672 | /// |
| 3380 | /// main_token is the `fn` keyword. | 3673 | /// The `data` field is a `.extra_and_opt_node`: |
| 3381 | /// extern function declarations use this tag. | 3674 | /// 1. a `Node.ExtraIndex` to `FnProto`. |
| 3675 | /// 2. a `Node.OptionalIndex` to the return type expression. Can't be | ||
| 3676 | /// `.none` unless a parsing error occured. | ||
| 3677 | /// | ||
| 3678 | /// The `main_token` field is the `fn` token. | ||
| 3679 | /// | ||
| 3680 | /// `anytype` and `...` parameters are omitted from the AST tree. | ||
| 3681 | /// Extern function declarations use this tag. | ||
| 3382 | fn_proto, | 3682 | fn_proto, |
| 3383 | /// lhs is the fn_proto. | 3683 | /// Extern function declarations use the fn_proto tags rather than this one. |
| 3384 | /// rhs is the function body block. | 3684 | /// |
| 3385 | /// Note that extern function declarations use the fn_proto tags rather | 3685 | /// The `data` field is a `.node_and_node`: |
| 3386 | /// than this one. | 3686 | /// 1. a `Node.Index` to `fn_proto_*`. |
| 3687 | /// 2. a `Node.Index` to function body block. | ||
| 3688 | /// | ||
| 3689 | /// The `main_token` field is the `fn` token. | ||
| 3387 | fn_decl, | 3690 | fn_decl, |
| 3388 | /// `anyframe->rhs`. main_token is `anyframe`. `lhs` is arrow token index. | 3691 | /// `anyframe->return_type`. |
| 3692 | /// | ||
| 3693 | /// The `data` field is a `.token_and_node`: | ||
| 3694 | /// 1. a `TokenIndex` to the `->` token. | ||
| 3695 | /// 2. a `Node.Index` to the function frame return type expression. | ||
| 3696 | /// | ||
| 3697 | /// The `main_token` field is the `anyframe` token. | ||
| 3389 | anyframe_type, | 3698 | anyframe_type, |
| 3390 | /// Both lhs and rhs unused. | 3699 | /// The `data` field is unused. |
| 3391 | anyframe_literal, | 3700 | anyframe_literal, |
| 3392 | /// Both lhs and rhs unused. | 3701 | /// The `data` field is unused. |
| 3393 | char_literal, | 3702 | char_literal, |
| 3394 | /// Both lhs and rhs unused. | 3703 | /// The `data` field is unused. |
| 3395 | number_literal, | 3704 | number_literal, |
| 3396 | /// Both lhs and rhs unused. | 3705 | /// The `data` field is unused. |
| 3397 | unreachable_literal, | 3706 | unreachable_literal, |
| 3398 | /// Both lhs and rhs unused. | 3707 | /// The `data` field is unused. |
| 3399 | /// Most identifiers will not have explicit AST nodes, however for expressions | 3708 | /// |
| 3400 | /// which could be one of many different kinds of AST nodes, there will be an | 3709 | /// Most identifiers will not have explicit AST nodes, however for |
| 3401 | /// identifier AST node for it. | 3710 | /// expressions which could be one of many different kinds of AST nodes, |
| 3711 | /// there will be an identifier AST node for it. | ||
| 3402 | identifier, | 3712 | identifier, |
| 3403 | /// lhs is the dot token index, rhs unused, main_token is the identifier. | 3713 | /// `.foo`. |
| 3714 | /// | ||
| 3715 | /// The `data` field is unused. | ||
| 3716 | /// | ||
| 3717 | /// The `main_token` field is the identifier. | ||
| 3404 | enum_literal, | 3718 | enum_literal, |
| 3405 | /// main_token is the string literal token | 3719 | /// The `data` field is unused. |
| 3406 | /// Both lhs and rhs unused. | 3720 | /// |
| 3721 | /// The `main_token` field is the string literal token. | ||
| 3407 | string_literal, | 3722 | string_literal, |
| 3408 | /// main_token is the first token index (redundant with lhs) | 3723 | /// The `data` field is a `.token_and_token`: |
| 3409 | /// lhs is the first token index; rhs is the last token index. | 3724 | /// 1. a `TokenIndex` to the first `.multiline_string_literal_line` token. |
| 3410 | /// Could be a series of multiline_string_literal_line tokens, or a single | 3725 | /// 2. a `TokenIndex` to the last `.multiline_string_literal_line` token. |
| 3411 | /// string_literal token. | 3726 | /// |
| 3727 | /// The `main_token` field is the first token index (redundant with `data`). | ||
| 3412 | multiline_string_literal, | 3728 | multiline_string_literal, |
| 3413 | /// `(lhs)`. main_token is the `(`; rhs is the token index of the `)`. | 3729 | /// `(expr)`. |
| 3730 | /// | ||
| 3731 | /// The `data` field is a `.node_and_token`: | ||
| 3732 | /// 1. a `Node.Index` to the sub-expression | ||
| 3733 | /// 2. a `TokenIndex` to the `)` token. | ||
| 3734 | /// | ||
| 3735 | /// The `main_token` field is the `(` token. | ||
| 3414 | grouped_expression, | 3736 | grouped_expression, |
| 3415 | /// `@a(lhs, rhs)`. lhs and rhs may be omitted. | 3737 | /// `@a(b, c)`. |
| 3416 | /// main_token is the builtin token. | 3738 | /// |
| 3739 | /// The `data` field is a `.opt_node_and_opt_node`: | ||
| 3740 | /// 1. a `Node.OptionalIndex` to the first argument, if any. | ||
| 3741 | /// 2. a `Node.OptionalIndex` to the second argument, if any. | ||
| 3742 | /// | ||
| 3743 | /// The `main_token` field is the builtin token. | ||
| 3417 | builtin_call_two, | 3744 | builtin_call_two, |
| 3418 | /// Same as builtin_call_two but there is known to be a trailing comma before the rparen. | 3745 | /// Same as `builtin_call_two` except there is known to be a trailing comma |
| 3746 | /// before the final rparen. | ||
| 3419 | builtin_call_two_comma, | 3747 | builtin_call_two_comma, |
| 3420 | /// `@a(b, c)`. `sub_list[lhs..rhs]`. | 3748 | /// `@a(b, c, d)`. |
| 3421 | /// main_token is the builtin token. | 3749 | /// |
| 3750 | /// The `data` field is a `.extra_range` that stores a `Node.Index` for | ||
| 3751 | /// each argument. | ||
| 3752 | /// | ||
| 3753 | /// The `main_token` field is the builtin token. | ||
| 3422 | builtin_call, | 3754 | builtin_call, |
| 3423 | /// Same as builtin_call but there is known to be a trailing comma before the rparen. | 3755 | /// Same as `builtin_call` except there is known to be a trailing comma |
| 3756 | /// before the final rparen. | ||
| 3424 | builtin_call_comma, | 3757 | builtin_call_comma, |
| 3425 | /// `error{a, b}`. | 3758 | /// `error{a, b}`. |
| 3426 | /// rhs is the rbrace, lhs is unused. | 3759 | /// |
| 3760 | /// The `data` field is a `.token_and_token`: | ||
| 3761 | /// 1. a `TokenIndex` to the `{` token. | ||
| 3762 | /// 2. a `TokenIndex` to the `}` token. | ||
| 3763 | /// | ||
| 3764 | /// The `main_token` field is the `error`. | ||
| 3427 | error_set_decl, | 3765 | error_set_decl, |
| 3428 | /// `struct {}`, `union {}`, `opaque {}`, `enum {}`. `extra_data[lhs..rhs]`. | 3766 | /// `struct {}`, `union {}`, `opaque {}`, `enum {}`. |
| 3429 | /// main_token is `struct`, `union`, `opaque`, `enum` keyword. | 3767 | /// |
| 3768 | /// The `data` field is a `.extra_range` that stores a `Node.Index` for | ||
| 3769 | /// each container member. | ||
| 3770 | /// | ||
| 3771 | /// The `main_token` field is the `struct`, `union`, `opaque` or `enum` token. | ||
| 3430 | container_decl, | 3772 | container_decl, |
| 3431 | /// Same as ContainerDecl but there is known to be a trailing comma | 3773 | /// Same as `container_decl` except there is known to be a trailing |
| 3432 | /// or semicolon before the rbrace. | 3774 | /// comma before the final rbrace. |
| 3433 | container_decl_trailing, | 3775 | container_decl_trailing, |
| 3434 | /// `struct {lhs, rhs}`, `union {lhs, rhs}`, `opaque {lhs, rhs}`, `enum {lhs, rhs}`. | 3776 | /// `struct {lhs, rhs}`, `union {lhs, rhs}`, `opaque {lhs, rhs}`, `enum {lhs, rhs}`. |
| 3435 | /// lhs or rhs can be omitted. | 3777 | /// |
| 3436 | /// main_token is `struct`, `union`, `opaque`, `enum` keyword. | 3778 | /// The `data` field is a `.opt_node_and_opt_node`: |
| 3779 | /// 1. a `Node.OptionalIndex` to the first container member, if any. | ||
| 3780 | /// 2. a `Node.OptionalIndex` to the second container member, if any. | ||
| 3781 | /// | ||
| 3782 | /// The `main_token` field is the `struct`, `union`, `opaque` or `enum` token. | ||
| 3437 | container_decl_two, | 3783 | container_decl_two, |
| 3438 | /// Same as ContainerDeclTwo except there is known to be a trailing comma | 3784 | /// Same as `container_decl_two` except there is known to be a trailing |
| 3439 | /// or semicolon before the rbrace. | 3785 | /// comma before the final rbrace. |
| 3440 | container_decl_two_trailing, | 3786 | container_decl_two_trailing, |
| 3441 | /// `struct(lhs)` / `union(lhs)` / `enum(lhs)`. `SubRange[rhs]`. | 3787 | /// `struct(arg)`, `union(arg)`, `enum(arg)`. |
| 3788 | /// | ||
| 3789 | /// The `data` field is a `.node_and_extra`: | ||
| 3790 | /// 1. a `Node.Index` to arg. | ||
| 3791 | /// 2. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for | ||
| 3792 | /// each container member. | ||
| 3793 | /// | ||
| 3794 | /// The `main_token` field is the `struct`, `union` or `enum` token. | ||
| 3442 | container_decl_arg, | 3795 | container_decl_arg, |
| 3443 | /// Same as container_decl_arg but there is known to be a trailing | 3796 | /// Same as `container_decl_arg` except there is known to be a trailing |
| 3444 | /// comma or semicolon before the rbrace. | 3797 | /// comma before the final rbrace. |
| 3445 | container_decl_arg_trailing, | 3798 | container_decl_arg_trailing, |
| 3446 | /// `union(enum) {}`. `sub_list[lhs..rhs]`. | 3799 | /// `union(enum) {}`. |
| 3447 | /// Note that tagged unions with explicitly provided enums are represented | 3800 | /// |
| 3448 | /// by `container_decl_arg`. | 3801 | /// The `data` field is a `.extra_range` that stores a `Node.Index` for |
| 3802 | /// each container member. | ||
| 3803 | /// | ||
| 3804 | /// The `main_token` field is the `union` token. | ||
| 3805 | /// | ||
| 3806 | /// A tagged union with explicitly provided enums will instead be | ||
| 3807 | /// represented by `container_decl_arg`. | ||
| 3449 | tagged_union, | 3808 | tagged_union, |
| 3450 | /// Same as tagged_union but there is known to be a trailing comma | 3809 | /// Same as `tagged_union` except there is known to be a trailing comma |
| 3451 | /// or semicolon before the rbrace. | 3810 | /// before the final rbrace. |
| 3452 | tagged_union_trailing, | 3811 | tagged_union_trailing, |
| 3453 | /// `union(enum) {lhs, rhs}`. lhs or rhs may be omitted. | 3812 | /// `union(enum) {lhs, rhs}`. |
| 3454 | /// Note that tagged unions with explicitly provided enums are represented | 3813 | /// |
| 3455 | /// by `container_decl_arg`. | 3814 | /// The `data` field is a `.opt_node_and_opt_node`: |
| 3815 | /// 1. a `Node.OptionalIndex` to the first container member, if any. | ||
| 3816 | /// 2. a `Node.OptionalIndex` to the second container member, if any. | ||
| 3817 | /// | ||
| 3818 | /// The `main_token` field is the `union` token. | ||
| 3819 | /// | ||
| 3820 | /// A tagged union with explicitly provided enums will instead be | ||
| 3821 | /// represented by `container_decl_arg`. | ||
| 3456 | tagged_union_two, | 3822 | tagged_union_two, |
| 3457 | /// Same as tagged_union_two but there is known to be a trailing comma | 3823 | /// Same as `tagged_union_two` except there is known to be a trailing |
| 3458 | /// or semicolon before the rbrace. | 3824 | /// comma before the final rbrace. |
| 3459 | tagged_union_two_trailing, | 3825 | tagged_union_two_trailing, |
| 3460 | /// `union(enum(lhs)) {}`. `SubRange[rhs]`. | 3826 | /// `union(enum(arg)) {}`. |
| 3827 | /// | ||
| 3828 | /// The `data` field is a `.node_and_extra`: | ||
| 3829 | /// 1. a `Node.Index` to arg. | ||
| 3830 | /// 2. a `ExtraIndex` to a `SubRange` that stores a `Node.Index` for | ||
| 3831 | /// each container member. | ||
| 3832 | /// | ||
| 3833 | /// The `main_token` field is the `union` token. | ||
| 3461 | tagged_union_enum_tag, | 3834 | tagged_union_enum_tag, |
| 3462 | /// Same as tagged_union_enum_tag but there is known to be a trailing comma | 3835 | /// Same as `tagged_union_enum_tag` except there is known to be a |
| 3463 | /// or semicolon before the rbrace. | 3836 | /// trailing comma before the final rbrace. |
| 3464 | tagged_union_enum_tag_trailing, | 3837 | tagged_union_enum_tag_trailing, |
| 3465 | /// `a: lhs = rhs,`. lhs and rhs can be omitted. | 3838 | /// `a: lhs = rhs,`, |
| 3466 | /// main_token is the field name identifier. | 3839 | /// `a: lhs,`. |
| 3467 | /// lastToken() does not include the possible trailing comma. | 3840 | /// |
| 3841 | /// The `data` field is a `.node_and_opt_node`: | ||
| 3842 | /// 1. a `Node.Index` to the field type expression. | ||
| 3843 | /// 2. a `Node.OptionalIndex` to the default value expression, if any. | ||
| 3844 | /// | ||
| 3845 | /// The `main_token` field is the field name identifier. | ||
| 3846 | /// | ||
| 3847 | /// `lastToken()` does not include the possible trailing comma. | ||
| 3468 | container_field_init, | 3848 | container_field_init, |
| 3469 | /// `a: lhs align(rhs),`. rhs can be omitted. | 3849 | /// `a: lhs align(rhs),`. |
| 3470 | /// main_token is the field name identifier. | 3850 | /// |
| 3471 | /// lastToken() does not include the possible trailing comma. | 3851 | /// The `data` field is a `.node_and_node`: |
| 3852 | /// 1. a `Node.Index` to the field type expression. | ||
| 3853 | /// 2. a `Node.Index` to the alignment expression. | ||
| 3854 | /// | ||
| 3855 | /// The `main_token` field is the field name identifier. | ||
| 3856 | /// | ||
| 3857 | /// `lastToken()` does not include the possible trailing comma. | ||
| 3472 | container_field_align, | 3858 | container_field_align, |
| 3473 | /// `a: lhs align(c) = d,`. `container_field_list[rhs]`. | 3859 | /// `a: lhs align(c) = d,`. |
| 3474 | /// main_token is the field name identifier. | 3860 | /// |
| 3475 | /// lastToken() does not include the possible trailing comma. | 3861 | /// The `data` field is a `.node_and_extra`: |
| 3862 | /// 1. a `Node.Index` to the field type expression. | ||
| 3863 | /// 2. a `ExtraIndex` to `ContainerField`. | ||
| 3864 | /// | ||
| 3865 | /// The `main_token` field is the field name identifier. | ||
| 3866 | /// | ||
| 3867 | /// `lastToken()` does not include the possible trailing comma. | ||
| 3476 | container_field, | 3868 | container_field, |
| 3477 | /// `comptime lhs`. rhs unused. | 3869 | /// `comptime expr`. |
| 3870 | /// | ||
| 3871 | /// The `data` field is a `.node` to expr. | ||
| 3872 | /// | ||
| 3873 | /// The `main_token` field is the `comptime` token. | ||
| 3478 | @"comptime", | 3874 | @"comptime", |
| 3479 | /// `nosuspend lhs`. rhs unused. | 3875 | /// `nosuspend expr`. |
| 3876 | /// | ||
| 3877 | /// The `data` field is a `.node` to expr. | ||
| 3878 | /// | ||
| 3879 | /// The `main_token` field is the `nosuspend` token. | ||
| 3480 | @"nosuspend", | 3880 | @"nosuspend", |
| 3481 | /// `{lhs rhs}`. rhs or lhs can be omitted. | 3881 | /// `{lhs rhs}`. |
| 3482 | /// main_token points at the lbrace. | 3882 | /// |
| 3883 | /// The `data` field is a `.opt_node_and_opt_node`: | ||
| 3884 | /// 1. a `Node.OptionalIndex` to the first statement, if any. | ||
| 3885 | /// 2. a `Node.OptionalIndex` to the second statement, if any. | ||
| 3886 | /// | ||
| 3887 | /// The `main_token` field is the `{` token. | ||
| 3483 | block_two, | 3888 | block_two, |
| 3484 | /// Same as block_two but there is known to be a semicolon before the rbrace. | 3889 | /// Same as `block_two_semicolon` except there is known to be a trailing |
| 3890 | /// comma before the final rbrace. | ||
| 3485 | block_two_semicolon, | 3891 | block_two_semicolon, |
| 3486 | /// `{}`. `sub_list[lhs..rhs]`. | 3892 | /// `{a b}`. |
| 3487 | /// main_token points at the lbrace. | 3893 | /// |
| 3894 | /// The `data` field is a `.extra_range` that stores a `Node.Index` for | ||
| 3895 | /// each statement. | ||
| 3896 | /// | ||
| 3897 | /// The `main_token` field is the `{` token. | ||
| 3488 | block, | 3898 | block, |
| 3489 | /// Same as block but there is known to be a semicolon before the rbrace. | 3899 | /// Same as `block` except there is known to be a trailing comma before |
| 3900 | /// the final rbrace. | ||
| 3490 | block_semicolon, | 3901 | block_semicolon, |
| 3491 | /// `asm(lhs)`. rhs is the token index of the rparen. | 3902 | /// `asm(lhs)`. |
| 3903 | /// | ||
| 3904 | /// rhs is a `Token.Index` to the `)` token. | ||
| 3905 | /// The `main_token` field is the `asm` token. | ||
| 3492 | asm_simple, | 3906 | asm_simple, |
| 3493 | /// `asm(lhs, a)`. `Asm[rhs]`. | 3907 | /// `asm(lhs, a)`. |
| 3908 | /// | ||
| 3909 | /// The `data` field is a `.node_and_extra`: | ||
| 3910 | /// 1. a `Node.Index` to lhs. | ||
| 3911 | /// 2. a `ExtraIndex` to `Asm`. | ||
| 3912 | /// | ||
| 3913 | /// The `main_token` field is the `asm` token. | ||
| 3494 | @"asm", | 3914 | @"asm", |
| 3495 | /// `[a] "b" (c)`. lhs is 0, rhs is token index of the rparen. | 3915 | /// `[a] "b" (c)`. |
| 3496 | /// `[a] "b" (-> lhs)`. rhs is token index of the rparen. | 3916 | /// `[a] "b" (-> lhs)`. |
| 3497 | /// main_token is `a`. | 3917 | /// |
| 3918 | /// The `data` field is a `.opt_node_and_token`: | ||
| 3919 | /// 1. a `Node.OptionalIndex` to lhs, if any. | ||
| 3920 | /// 2. a `TokenIndex` to the `)` token. | ||
| 3921 | /// | ||
| 3922 | /// The `main_token` field is `a`. | ||
| 3498 | asm_output, | 3923 | asm_output, |
| 3499 | /// `[a] "b" (lhs)`. rhs is token index of the rparen. | 3924 | /// `[a] "b" (lhs)`. |
| 3500 | /// main_token is `a`. | 3925 | /// |
| 3926 | /// The `data` field is a `.node_and_token`: | ||
| 3927 | /// 1. a `Node.Index` to lhs. | ||
| 3928 | /// 2. a `TokenIndex` to the `)` token. | ||
| 3929 | /// | ||
| 3930 | /// The `main_token` field is `a`. | ||
| 3501 | asm_input, | 3931 | asm_input, |
| 3502 | /// `error.a`. lhs is token index of `.`. rhs is token index of `a`. | 3932 | /// `error.a`. |
| 3933 | /// | ||
| 3934 | /// The `data` field is unused. | ||
| 3935 | /// | ||
| 3936 | /// The `main_token` field is `error` token. | ||
| 3503 | error_value, | 3937 | error_value, |
| 3504 | /// `lhs!rhs`. main_token is the `!`. | 3938 | /// `lhs!rhs`. |
| 3939 | /// | ||
| 3940 | /// The `main_token` field is the `!` token. | ||
| 3505 | error_union, | 3941 | error_union, |
| 3506 | 3942 | ||
| 3507 | pub fn isContainerField(tag: Tag) bool { | 3943 | pub fn isContainerField(tag: Tag) bool { |
| ... | @@ -3516,9 +3952,26 @@ pub const Node = struct { | ... | @@ -3516,9 +3952,26 @@ pub const Node = struct { |
| 3516 | } | 3952 | } |
| 3517 | }; | 3953 | }; |
| 3518 | 3954 | ||
| 3519 | pub const Data = struct { | 3955 | pub const Data = union { |
| 3520 | lhs: Index, | 3956 | node: Index, |
| 3521 | rhs: Index, | 3957 | opt_node: OptionalIndex, |
| 3958 | token: TokenIndex, | ||
| 3959 | node_and_node: struct { Index, Index }, | ||
| 3960 | opt_node_and_opt_node: struct { OptionalIndex, OptionalIndex }, | ||
| 3961 | node_and_opt_node: struct { Index, OptionalIndex }, | ||
| 3962 | opt_node_and_node: struct { OptionalIndex, Index }, | ||
| 3963 | node_and_extra: struct { Index, ExtraIndex }, | ||
| 3964 | extra_and_node: struct { ExtraIndex, Index }, | ||
| 3965 | extra_and_opt_node: struct { ExtraIndex, OptionalIndex }, | ||
| 3966 | node_and_token: struct { Index, TokenIndex }, | ||
| 3967 | token_and_node: struct { TokenIndex, Index }, | ||
| 3968 | token_and_token: struct { TokenIndex, TokenIndex }, | ||
| 3969 | opt_node_and_token: struct { OptionalIndex, TokenIndex }, | ||
| 3970 | opt_token_and_node: struct { OptionalTokenIndex, Index }, | ||
| 3971 | opt_token_and_opt_node: struct { OptionalTokenIndex, OptionalIndex }, | ||
| 3972 | opt_token_and_opt_token: struct { OptionalTokenIndex, OptionalTokenIndex }, | ||
| 3973 | @"for": struct { ExtraIndex, For }, | ||
| 3974 | extra_range: SubRange, | ||
| 3522 | }; | 3975 | }; |
| 3523 | 3976 | ||
| 3524 | pub const LocalVarDecl = struct { | 3977 | pub const LocalVarDecl = struct { |
| ... | @@ -3532,24 +3985,24 @@ pub const Node = struct { | ... | @@ -3532,24 +3985,24 @@ pub const Node = struct { |
| 3532 | }; | 3985 | }; |
| 3533 | 3986 | ||
| 3534 | pub const PtrType = struct { | 3987 | pub const PtrType = struct { |
| 3535 | sentinel: Index, | 3988 | sentinel: OptionalIndex, |
| 3536 | align_node: Index, | 3989 | align_node: OptionalIndex, |
| 3537 | addrspace_node: Index, | 3990 | addrspace_node: OptionalIndex, |
| 3538 | }; | 3991 | }; |
| 3539 | 3992 | ||
| 3540 | pub const PtrTypeBitRange = struct { | 3993 | pub const PtrTypeBitRange = struct { |
| 3541 | sentinel: Index, | 3994 | sentinel: OptionalIndex, |
| 3542 | align_node: Index, | 3995 | align_node: Index, |
| 3543 | addrspace_node: Index, | 3996 | addrspace_node: OptionalIndex, |
| 3544 | bit_range_start: Index, | 3997 | bit_range_start: Index, |
| 3545 | bit_range_end: Index, | 3998 | bit_range_end: Index, |
| 3546 | }; | 3999 | }; |
| 3547 | 4000 | ||
| 3548 | pub const SubRange = struct { | 4001 | pub const SubRange = struct { |
| 3549 | /// Index into sub_list. | 4002 | /// Index into extra_data. |
| 3550 | start: Index, | 4003 | start: ExtraIndex, |
| 3551 | /// Index into sub_list. | 4004 | /// Index into extra_data. |
| 3552 | end: Index, | 4005 | end: ExtraIndex, |
| 3553 | }; | 4006 | }; |
| 3554 | 4007 | ||
| 3555 | pub const If = struct { | 4008 | pub const If = struct { |
| ... | @@ -3564,13 +4017,13 @@ pub const Node = struct { | ... | @@ -3564,13 +4017,13 @@ pub const Node = struct { |
| 3564 | 4017 | ||
| 3565 | pub const GlobalVarDecl = struct { | 4018 | pub const GlobalVarDecl = struct { |
| 3566 | /// Populated if there is an explicit type ascription. | 4019 | /// Populated if there is an explicit type ascription. |
| 3567 | type_node: Index, | 4020 | type_node: OptionalIndex, |
| 3568 | /// Populated if align(A) is present. | 4021 | /// Populated if align(A) is present. |
| 3569 | align_node: Index, | 4022 | align_node: OptionalIndex, |
| 3570 | /// Populated if addrspace(A) is present. | 4023 | /// Populated if addrspace(A) is present. |
| 3571 | addrspace_node: Index, | 4024 | addrspace_node: OptionalIndex, |
| 3572 | /// Populated if linksection(A) is present. | 4025 | /// Populated if linksection(A) is present. |
| 3573 | section_node: Index, | 4026 | section_node: OptionalIndex, |
| 3574 | }; | 4027 | }; |
| 3575 | 4028 | ||
| 3576 | pub const Slice = struct { | 4029 | pub const Slice = struct { |
| ... | @@ -3580,13 +4033,13 @@ pub const Node = struct { | ... | @@ -3580,13 +4033,13 @@ pub const Node = struct { |
| 3580 | 4033 | ||
| 3581 | pub const SliceSentinel = struct { | 4034 | pub const SliceSentinel = struct { |
| 3582 | start: Index, | 4035 | start: Index, |
| 3583 | /// May be 0 if the slice is "open" | 4036 | /// May be .none if the slice is "open" |
| 3584 | end: Index, | 4037 | end: OptionalIndex, |
| 3585 | sentinel: Index, | 4038 | sentinel: Index, |
| 3586 | }; | 4039 | }; |
| 3587 | 4040 | ||
| 3588 | pub const While = struct { | 4041 | pub const While = struct { |
| 3589 | cont_expr: Index, | 4042 | cont_expr: OptionalIndex, |
| 3590 | then_expr: Index, | 4043 | then_expr: Index, |
| 3591 | else_expr: Index, | 4044 | else_expr: Index, |
| 3592 | }; | 4045 | }; |
| ... | @@ -3603,44 +4056,44 @@ pub const Node = struct { | ... | @@ -3603,44 +4056,44 @@ pub const Node = struct { |
| 3603 | 4056 | ||
| 3604 | pub const FnProtoOne = struct { | 4057 | pub const FnProtoOne = struct { |
| 3605 | /// Populated if there is exactly 1 parameter. Otherwise there are 0 parameters. | 4058 | /// Populated if there is exactly 1 parameter. Otherwise there are 0 parameters. |
| 3606 | param: Index, | 4059 | param: OptionalIndex, |
| 3607 | /// Populated if align(A) is present. | 4060 | /// Populated if align(A) is present. |
| 3608 | align_expr: Index, | 4061 | align_expr: OptionalIndex, |
| 3609 | /// Populated if addrspace(A) is present. | 4062 | /// Populated if addrspace(A) is present. |
| 3610 | addrspace_expr: Index, | 4063 | addrspace_expr: OptionalIndex, |
| 3611 | /// Populated if linksection(A) is present. | 4064 | /// Populated if linksection(A) is present. |
| 3612 | section_expr: Index, | 4065 | section_expr: OptionalIndex, |
| 3613 | /// Populated if callconv(A) is present. | 4066 | /// Populated if callconv(A) is present. |
| 3614 | callconv_expr: Index, | 4067 | callconv_expr: OptionalIndex, |
| 3615 | }; | 4068 | }; |
| 3616 | 4069 | ||
| 3617 | pub const FnProto = struct { | 4070 | pub const FnProto = struct { |
| 3618 | params_start: Index, | 4071 | params_start: ExtraIndex, |
| 3619 | params_end: Index, | 4072 | params_end: ExtraIndex, |
| 3620 | /// Populated if align(A) is present. | 4073 | /// Populated if align(A) is present. |
| 3621 | align_expr: Index, | 4074 | align_expr: OptionalIndex, |
| 3622 | /// Populated if addrspace(A) is present. | 4075 | /// Populated if addrspace(A) is present. |
| 3623 | addrspace_expr: Index, | 4076 | addrspace_expr: OptionalIndex, |
| 3624 | /// Populated if linksection(A) is present. | 4077 | /// Populated if linksection(A) is present. |
| 3625 | section_expr: Index, | 4078 | section_expr: OptionalIndex, |
| 3626 | /// Populated if callconv(A) is present. | 4079 | /// Populated if callconv(A) is present. |
| 3627 | callconv_expr: Index, | 4080 | callconv_expr: OptionalIndex, |
| 3628 | }; | 4081 | }; |
| 3629 | 4082 | ||
| 3630 | pub const Asm = struct { | 4083 | pub const Asm = struct { |
| 3631 | items_start: Index, | 4084 | items_start: ExtraIndex, |
| 3632 | items_end: Index, | 4085 | items_end: ExtraIndex, |
| 3633 | /// Needed to make lastToken() work. | 4086 | /// Needed to make lastToken() work. |
| 3634 | rparen: TokenIndex, | 4087 | rparen: TokenIndex, |
| 3635 | }; | 4088 | }; |
| 3636 | }; | 4089 | }; |
| 3637 | 4090 | ||
| 3638 | pub fn nodeToSpan(tree: *const Ast, node: u32) Span { | 4091 | pub fn nodeToSpan(tree: *const Ast, node: Ast.Node.Index) Span { |
| 3639 | return tokensToSpan( | 4092 | return tokensToSpan( |
| 3640 | tree, | 4093 | tree, |
| 3641 | tree.firstToken(node), | 4094 | tree.firstToken(node), |
| 3642 | tree.lastToken(node), | 4095 | tree.lastToken(node), |
| 3643 | tree.nodes.items(.main_token)[node], | 4096 | tree.nodeMainToken(node), |
| 3644 | ); | 4097 | ); |
| 3645 | } | 4098 | } |
| 3646 | 4099 | ||
| ... | @@ -3649,7 +4102,6 @@ pub fn tokenToSpan(tree: *const Ast, token: Ast.TokenIndex) Span { | ... | @@ -3649,7 +4102,6 @@ pub fn tokenToSpan(tree: *const Ast, token: Ast.TokenIndex) Span { |
| 3649 | } | 4102 | } |
| 3650 | 4103 | ||
| 3651 | pub fn tokensToSpan(tree: *const Ast, start: Ast.TokenIndex, end: Ast.TokenIndex, main: Ast.TokenIndex) Span { | 4104 | pub fn tokensToSpan(tree: *const Ast, start: Ast.TokenIndex, end: Ast.TokenIndex, main: Ast.TokenIndex) Span { |
| 3652 | const token_starts = tree.tokens.items(.start); | ||
| 3653 | var start_tok = start; | 4105 | var start_tok = start; |
| 3654 | var end_tok = end; | 4106 | var end_tok = end; |
| 3655 | 4107 | ||
| ... | @@ -3663,9 +4115,9 @@ pub fn tokensToSpan(tree: *const Ast, start: Ast.TokenIndex, end: Ast.TokenIndex | ... | @@ -3663,9 +4115,9 @@ pub fn tokensToSpan(tree: *const Ast, start: Ast.TokenIndex, end: Ast.TokenIndex |
| 3663 | start_tok = main; | 4115 | start_tok = main; |
| 3664 | end_tok = main; | 4116 | end_tok = main; |
| 3665 | } | 4117 | } |
| 3666 | const start_off = token_starts[start_tok]; | 4118 | const start_off = tree.tokenStart(start_tok); |
| 3667 | const end_off = token_starts[end_tok] + @as(u32, @intCast(tree.tokenSlice(end_tok).len)); | 4119 | const end_off = tree.tokenStart(end_tok) + @as(u32, @intCast(tree.tokenSlice(end_tok).len)); |
| 3668 | return Span{ .start = start_off, .end = end_off, .main = token_starts[main] }; | 4120 | return Span{ .start = start_off, .end = end_off, .main = tree.tokenStart(main) }; |
| 3669 | } | 4121 | } |
| 3670 | 4122 | ||
| 3671 | const std = @import("../std.zig"); | 4123 | const std = @import("../std.zig"); |
lib/std/zig/AstGen.zig+650-835| ... | @@ -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 | ||
| ... | @@ -824,20 +830,13 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -824,20 +830,13 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 824 | .number_literal => return numberLiteral(gz, ri, node, node, .positive), | 830 | .number_literal => return numberLiteral(gz, ri, node, node, .positive), |
| 825 | // zig fmt: on | 831 | // zig fmt: on |
| 826 | 832 | ||
| 827 | .builtin_call_two, .builtin_call_two_comma => { | 833 | .builtin_call_two, |
| 828 | if (node_datas[node].lhs == 0) { | 834 | .builtin_call_two_comma, |
| 829 | const params = [_]Ast.Node.Index{}; | 835 | .builtin_call, |
| 830 | return builtinCall(gz, scope, ri, node, &params, false); | 836 | .builtin_call_comma, |
| 831 | } else if (node_datas[node].rhs == 0) { | 837 | => { |
| 832 | const params = [_]Ast.Node.Index{node_datas[node].lhs}; | 838 | var buf: [2]Ast.Node.Index = undefined; |
| 833 | return builtinCall(gz, scope, ri, node, &params, false); | 839 | const params = tree.builtinCallParams(&buf, node).?; |
| 834 | } else { | ||
| 835 | const params = [_]Ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs }; | ||
| 836 | return builtinCall(gz, scope, ri, node, &params, false); | ||
| 837 | } | ||
| 838 | }, | ||
| 839 | .builtin_call, .builtin_call_comma => { | ||
| 840 | const params = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; | ||
| 841 | return builtinCall(gz, scope, ri, node, params, false); | 840 | return builtinCall(gz, scope, ri, node, params, false); |
| 842 | }, | 841 | }, |
| 843 | 842 | ||
| ... | @@ -873,10 +872,11 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -873,10 +872,11 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 873 | const if_full = tree.fullIf(node).?; | 872 | const if_full = tree.fullIf(node).?; |
| 874 | no_switch_on_err: { | 873 | no_switch_on_err: { |
| 875 | 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; |
| 876 | 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; | ||
| 877 | if (full_switch.label_token != null) break :no_switch_on_err; | 877 | if (full_switch.label_token != null) break :no_switch_on_err; |
| 878 | 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; |
| 879 | 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; |
| 880 | return switchExprErrUnion(gz, scope, ri.br(), node, .@"if"); | 880 | return switchExprErrUnion(gz, scope, ri.br(), node, .@"if"); |
| 881 | } | 881 | } |
| 882 | return ifExpr(gz, scope, ri.br(), node, if_full); | 882 | return ifExpr(gz, scope, ri.br(), node, if_full); |
| ... | @@ -894,8 +894,8 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -894,8 +894,8 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 894 | .slice_sentinel, | 894 | .slice_sentinel, |
| 895 | => { | 895 | => { |
| 896 | const full = tree.fullSlice(node).?; | 896 | const full = tree.fullSlice(node).?; |
| 897 | if (full.ast.end != 0 and | 897 | if (full.ast.end != .none and |
| 898 | node_tags[full.ast.sliced] == .slice_open and | 898 | tree.nodeTag(full.ast.sliced) == .slice_open and |
| 899 | nodeIsTriviallyZero(tree, full.ast.start)) | 899 | nodeIsTriviallyZero(tree, full.ast.start)) |
| 900 | { | 900 | { |
| 901 | const lhs_extra = tree.sliceOpen(full.ast.sliced).ast; | 901 | const lhs_extra = tree.sliceOpen(full.ast.sliced).ast; |
| ... | @@ -903,8 +903,8 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -903,8 +903,8 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 903 | const lhs = try expr(gz, scope, .{ .rl = .ref }, lhs_extra.sliced); | 903 | const lhs = try expr(gz, scope, .{ .rl = .ref }, lhs_extra.sliced); |
| 904 | 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); |
| 905 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | 905 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); |
| 906 | 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().?); |
| 907 | 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; |
| 908 | try emitDbgStmt(gz, cursor); | 908 | try emitDbgStmt(gz, cursor); |
| 909 | const result = try gz.addPlNode(.slice_length, node, Zir.Inst.SliceLength{ | 909 | const result = try gz.addPlNode(.slice_length, node, Zir.Inst.SliceLength{ |
| 910 | .lhs = lhs, | 910 | .lhs = lhs, |
| ... | @@ -919,10 +919,10 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -919,10 +919,10 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 919 | 919 | ||
| 920 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | 920 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); |
| 921 | 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); |
| 922 | 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; |
| 923 | const sentinel = if (full.ast.sentinel != 0) s: { | 923 | const sentinel = if (full.ast.sentinel.unwrap()) |sentinel| s: { |
| 924 | const sentinel_ty = try gz.addUnNode(.slice_sentinel_ty, lhs, node); | 924 | const sentinel_ty = try gz.addUnNode(.slice_sentinel_ty, lhs, node); |
| 925 | 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); |
| 926 | } else .none; | 926 | } else .none; |
| 927 | try emitDbgStmt(gz, cursor); | 927 | try emitDbgStmt(gz, cursor); |
| 928 | if (sentinel != .none) { | 928 | if (sentinel != .none) { |
| ... | @@ -950,7 +950,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -950,7 +950,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 950 | }, | 950 | }, |
| 951 | 951 | ||
| 952 | .deref => { | 952 | .deref => { |
| 953 | 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); |
| 954 | _ = try gz.addUnNode(.validate_deref, lhs, node); | 954 | _ = try gz.addUnNode(.validate_deref, lhs, node); |
| 955 | switch (ri.rl) { | 955 | switch (ri.rl) { |
| 956 | .ref, .ref_coerced_ty => return lhs, | 956 | .ref, .ref_coerced_ty => return lhs, |
| ... | @@ -965,17 +965,17 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -965,17 +965,17 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 965 | _ = 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)); |
| 966 | break :rl .{ .ref_coerced_ty = res_ty_inst }; | 966 | break :rl .{ .ref_coerced_ty = res_ty_inst }; |
| 967 | } else .ref; | 967 | } else .ref; |
| 968 | 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); |
| 969 | return rvalue(gz, ri, result, node); | 969 | return rvalue(gz, ri, result, node); |
| 970 | }, | 970 | }, |
| 971 | .optional_type => { | 971 | .optional_type => { |
| 972 | const operand = try typeExpr(gz, scope, node_datas[node].lhs); | 972 | const operand = try typeExpr(gz, scope, tree.nodeData(node).node); |
| 973 | const result = try gz.addUnNode(.optional_type, operand, node); | 973 | const result = try gz.addUnNode(.optional_type, operand, node); |
| 974 | return rvalue(gz, ri, result, node); | 974 | return rvalue(gz, ri, result, node); |
| 975 | }, | 975 | }, |
| 976 | .unwrap_optional => switch (ri.rl) { | 976 | .unwrap_optional => switch (ri.rl) { |
| 977 | .ref, .ref_coerced_ty => { | 977 | .ref, .ref_coerced_ty => { |
| 978 | 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]); |
| 979 | 979 | ||
| 980 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | 980 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); |
| 981 | try emitDbgStmt(gz, cursor); | 981 | try emitDbgStmt(gz, cursor); |
| ... | @@ -983,7 +983,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -983,7 +983,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 983 | return gz.addUnNode(.optional_payload_safe_ptr, lhs, node); | 983 | return gz.addUnNode(.optional_payload_safe_ptr, lhs, node); |
| 984 | }, | 984 | }, |
| 985 | else => { | 985 | else => { |
| 986 | 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]); |
| 987 | 987 | ||
| 988 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | 988 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); |
| 989 | try emitDbgStmt(gz, cursor); | 989 | try emitDbgStmt(gz, cursor); |
| ... | @@ -991,22 +991,17 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -991,22 +991,17 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 991 | return rvalue(gz, ri, try gz.addUnNode(.optional_payload_safe, lhs, node), node); | 991 | return rvalue(gz, ri, try gz.addUnNode(.optional_payload_safe, lhs, node), node); |
| 992 | }, | 992 | }, |
| 993 | }, | 993 | }, |
| 994 | .block_two, .block_two_semicolon => { | 994 | .block_two, |
| 995 | const statements = [2]Ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs }; | 995 | .block_two_semicolon, |
| 996 | if (node_datas[node].lhs == 0) { | 996 | .block, |
| 997 | return blockExpr(gz, scope, ri, node, statements[0..0], .normal); | 997 | .block_semicolon, |
| 998 | } else if (node_datas[node].rhs == 0) { | 998 | => { |
| 999 | return blockExpr(gz, scope, ri, node, statements[0..1], .normal); | 999 | var buf: [2]Ast.Node.Index = undefined; |
| 1000 | } else { | 1000 | const statements = tree.blockStatements(&buf, node).?; |
| 1001 | return blockExpr(gz, scope, ri, node, statements[0..2], .normal); | ||
| 1002 | } | ||
| 1003 | }, | ||
| 1004 | .block, .block_semicolon => { | ||
| 1005 | const statements = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; | ||
| 1006 | return blockExpr(gz, scope, ri, node, statements, .normal); | 1001 | return blockExpr(gz, scope, ri, node, statements, .normal); |
| 1007 | }, | 1002 | }, |
| 1008 | .enum_literal => if (try ri.rl.resultType(gz, node)) |res_ty| { | 1003 | .enum_literal => if (try ri.rl.resultType(gz, node)) |res_ty| { |
| 1009 | const str_index = try astgen.identAsString(main_tokens[node]); | 1004 | const str_index = try astgen.identAsString(tree.nodeMainToken(node)); |
| 1010 | const res = try gz.addPlNode(.decl_literal, node, Zir.Inst.Field{ | 1005 | const res = try gz.addPlNode(.decl_literal, node, Zir.Inst.Field{ |
| 1011 | .lhs = res_ty, | 1006 | .lhs = res_ty, |
| 1012 | .field_name_start = str_index, | 1007 | .field_name_start = str_index, |
| ... | @@ -1016,8 +1011,8 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -1016,8 +1011,8 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 1016 | .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 |
| 1017 | .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), |
| 1018 | } | 1013 | } |
| 1019 | } else return simpleStrTok(gz, ri, main_tokens[node], node, .enum_literal), | 1014 | } else return simpleStrTok(gz, ri, tree.nodeMainToken(node), node, .enum_literal), |
| 1020 | .error_value => return simpleStrTok(gz, ri, node_datas[node].rhs, node, .error_value), | 1015 | .error_value => return simpleStrTok(gz, ri, tree.nodeMainToken(node) + 2, node, .error_value), |
| 1021 | // 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 |
| 1022 | // .anyframe_literal => return rvalue(gz, ri, .anyframe_type, node), | 1017 | // .anyframe_literal => return rvalue(gz, ri, .anyframe_type, node), |
| 1023 | .anyframe_literal => { | 1018 | .anyframe_literal => { |
| ... | @@ -1025,22 +1020,22 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -1025,22 +1020,22 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 1025 | return rvalue(gz, ri, result, node); | 1020 | return rvalue(gz, ri, result, node); |
| 1026 | }, | 1021 | }, |
| 1027 | .anyframe_type => { | 1022 | .anyframe_type => { |
| 1028 | 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]); |
| 1029 | const result = try gz.addUnNode(.anyframe_type, return_type, node); | 1024 | const result = try gz.addUnNode(.anyframe_type, return_type, node); |
| 1030 | return rvalue(gz, ri, result, node); | 1025 | return rvalue(gz, ri, result, node); |
| 1031 | }, | 1026 | }, |
| 1032 | .@"catch" => { | 1027 | .@"catch" => { |
| 1033 | const catch_token = main_tokens[node]; | 1028 | const catch_token = tree.nodeMainToken(node); |
| 1034 | 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) |
| 1035 | catch_token + 2 | 1030 | catch_token + 2 |
| 1036 | else | 1031 | else |
| 1037 | null; | 1032 | null; |
| 1038 | no_switch_on_err: { | 1033 | no_switch_on_err: { |
| 1039 | const capture_token = payload_token orelse break :no_switch_on_err; | 1034 | const capture_token = payload_token orelse break :no_switch_on_err; |
| 1040 | 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; |
| 1041 | if (full_switch.label_token != null) break :no_switch_on_err; | 1036 | if (full_switch.label_token != null) break :no_switch_on_err; |
| 1042 | 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; |
| 1043 | 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; |
| 1044 | return switchExprErrUnion(gz, scope, ri.br(), node, .@"catch"); | 1039 | return switchExprErrUnion(gz, scope, ri.br(), node, .@"catch"); |
| 1045 | } | 1040 | } |
| 1046 | switch (ri.rl) { | 1041 | switch (ri.rl) { |
| ... | @@ -1049,11 +1044,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -1049,11 +1044,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 1049 | scope, | 1044 | scope, |
| 1050 | ri, | 1045 | ri, |
| 1051 | node, | 1046 | node, |
| 1052 | node_datas[node].lhs, | ||
| 1053 | .is_non_err_ptr, | 1047 | .is_non_err_ptr, |
| 1054 | .err_union_payload_unsafe_ptr, | 1048 | .err_union_payload_unsafe_ptr, |
| 1055 | .err_union_code_ptr, | 1049 | .err_union_code_ptr, |
| 1056 | node_datas[node].rhs, | ||
| 1057 | payload_token, | 1050 | payload_token, |
| 1058 | ), | 1051 | ), |
| 1059 | else => return orelseCatchExpr( | 1052 | else => return orelseCatchExpr( |
| ... | @@ -1061,11 +1054,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -1061,11 +1054,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 1061 | scope, | 1054 | scope, |
| 1062 | ri, | 1055 | ri, |
| 1063 | node, | 1056 | node, |
| 1064 | node_datas[node].lhs, | ||
| 1065 | .is_non_err, | 1057 | .is_non_err, |
| 1066 | .err_union_payload_unsafe, | 1058 | .err_union_payload_unsafe, |
| 1067 | .err_union_code, | 1059 | .err_union_code, |
| 1068 | node_datas[node].rhs, | ||
| 1069 | payload_token, | 1060 | payload_token, |
| 1070 | ), | 1061 | ), |
| 1071 | } | 1062 | } |
| ... | @@ -1076,11 +1067,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -1076,11 +1067,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 1076 | scope, | 1067 | scope, |
| 1077 | ri, | 1068 | ri, |
| 1078 | node, | 1069 | node, |
| 1079 | node_datas[node].lhs, | ||
| 1080 | .is_non_null_ptr, | 1070 | .is_non_null_ptr, |
| 1081 | .optional_payload_unsafe_ptr, | 1071 | .optional_payload_unsafe_ptr, |
| 1082 | undefined, | 1072 | undefined, |
| 1083 | node_datas[node].rhs, | ||
| 1084 | null, | 1073 | null, |
| 1085 | ), | 1074 | ), |
| 1086 | else => return orelseCatchExpr( | 1075 | else => return orelseCatchExpr( |
| ... | @@ -1088,11 +1077,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -1088,11 +1077,9 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 1088 | scope, | 1077 | scope, |
| 1089 | ri, | 1078 | ri, |
| 1090 | node, | 1079 | node, |
| 1091 | node_datas[node].lhs, | ||
| 1092 | .is_non_null, | 1080 | .is_non_null, |
| 1093 | .optional_payload_unsafe, | 1081 | .optional_payload_unsafe, |
| 1094 | undefined, | 1082 | undefined, |
| 1095 | node_datas[node].rhs, | ||
| 1096 | null, | 1083 | null, |
| 1097 | ), | 1084 | ), |
| 1098 | }, | 1085 | }, |
| ... | @@ -1122,7 +1109,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -1122,7 +1109,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 1122 | 1109 | ||
| 1123 | .@"break" => return breakExpr(gz, scope, node), | 1110 | .@"break" => return breakExpr(gz, scope, node), |
| 1124 | .@"continue" => return continueExpr(gz, scope, node), | 1111 | .@"continue" => return continueExpr(gz, scope, node), |
| 1125 | .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]), |
| 1126 | .array_type => return arrayType(gz, scope, ri, node), | 1113 | .array_type => return arrayType(gz, scope, ri, node), |
| 1127 | .array_type_sentinel => return arrayTypeSentinel(gz, scope, ri, node), | 1114 | .array_type_sentinel => return arrayTypeSentinel(gz, scope, ri, node), |
| 1128 | .char_literal => return charLiteral(gz, ri, node), | 1115 | .char_literal => return charLiteral(gz, ri, node), |
| ... | @@ -1136,7 +1123,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE | ... | @@ -1136,7 +1123,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE |
| 1136 | .@"await" => return awaitExpr(gz, scope, ri, node), | 1123 | .@"await" => return awaitExpr(gz, scope, ri, node), |
| 1137 | .@"resume" => return resumeExpr(gz, scope, ri, node), | 1124 | .@"resume" => return resumeExpr(gz, scope, ri, node), |
| 1138 | 1125 | ||
| 1139 | .@"try" => return tryExpr(gz, scope, ri, node, node_datas[node].lhs), | 1126 | .@"try" => return tryExpr(gz, scope, ri, node, tree.nodeData(node).node), |
| 1140 | 1127 | ||
| 1141 | .array_init_one, | 1128 | .array_init_one, |
| 1142 | .array_init_one_comma, | 1129 | .array_init_one_comma, |
| ... | @@ -1183,16 +1170,14 @@ fn nosuspendExpr( | ... | @@ -1183,16 +1170,14 @@ fn nosuspendExpr( |
| 1183 | ) InnerError!Zir.Inst.Ref { | 1170 | ) InnerError!Zir.Inst.Ref { |
| 1184 | const astgen = gz.astgen; | 1171 | const astgen = gz.astgen; |
| 1185 | const tree = astgen.tree; | 1172 | const tree = astgen.tree; |
| 1186 | const node_datas = tree.nodes.items(.data); | 1173 | const body_node = tree.nodeData(node).node; |
| 1187 | const body_node = node_datas[node].lhs; | 1174 | if (gz.nosuspend_node.unwrap()) |nosuspend_node| { |
| 1188 | assert(body_node != 0); | ||
| 1189 | if (gz.nosuspend_node != 0) { | ||
| 1190 | try astgen.appendErrorNodeNotes(node, "redundant nosuspend block", .{}, &[_]u32{ | 1175 | try astgen.appendErrorNodeNotes(node, "redundant nosuspend block", .{}, &[_]u32{ |
| 1191 | try astgen.errNoteNode(gz.nosuspend_node, "other nosuspend block here", .{}), | 1176 | try astgen.errNoteNode(nosuspend_node, "other nosuspend block here", .{}), |
| 1192 | }); | 1177 | }); |
| 1193 | } | 1178 | } |
| 1194 | gz.nosuspend_node = node; | 1179 | gz.nosuspend_node = node.toOptional(); |
| 1195 | defer gz.nosuspend_node = 0; | 1180 | defer gz.nosuspend_node = .none; |
| 1196 | return expr(gz, scope, ri, body_node); | 1181 | return expr(gz, scope, ri, body_node); |
| 1197 | } | 1182 | } |
| 1198 | 1183 | ||
| ... | @@ -1204,26 +1189,24 @@ fn suspendExpr( | ... | @@ -1204,26 +1189,24 @@ fn suspendExpr( |
| 1204 | const astgen = gz.astgen; | 1189 | const astgen = gz.astgen; |
| 1205 | const gpa = astgen.gpa; | 1190 | const gpa = astgen.gpa; |
| 1206 | const tree = astgen.tree; | 1191 | const tree = astgen.tree; |
| 1207 | const node_datas = tree.nodes.items(.data); | 1192 | const body_node = tree.nodeData(node).node; |
| 1208 | const body_node = node_datas[node].lhs; | ||
| 1209 | 1193 | ||
| 1210 | if (gz.nosuspend_node != 0) { | 1194 | if (gz.nosuspend_node.unwrap()) |nosuspend_node| { |
| 1211 | return astgen.failNodeNotes(node, "suspend inside nosuspend block", .{}, &[_]u32{ | 1195 | return astgen.failNodeNotes(node, "suspend inside nosuspend block", .{}, &[_]u32{ |
| 1212 | try astgen.errNoteNode(gz.nosuspend_node, "nosuspend block here", .{}), | 1196 | try astgen.errNoteNode(nosuspend_node, "nosuspend block here", .{}), |
| 1213 | }); | 1197 | }); |
| 1214 | } | 1198 | } |
| 1215 | if (gz.suspend_node != 0) { | 1199 | if (gz.suspend_node.unwrap()) |suspend_node| { |
| 1216 | return astgen.failNodeNotes(node, "cannot suspend inside suspend block", .{}, &[_]u32{ | 1200 | return astgen.failNodeNotes(node, "cannot suspend inside suspend block", .{}, &[_]u32{ |
| 1217 | try astgen.errNoteNode(gz.suspend_node, "other suspend block here", .{}), | 1201 | try astgen.errNoteNode(suspend_node, "other suspend block here", .{}), |
| 1218 | }); | 1202 | }); |
| 1219 | } | 1203 | } |
| 1220 | assert(body_node != 0); | ||
| 1221 | 1204 | ||
| 1222 | const suspend_inst = try gz.makeBlockInst(.suspend_block, node); | 1205 | const suspend_inst = try gz.makeBlockInst(.suspend_block, node); |
| 1223 | try gz.instructions.append(gpa, suspend_inst); | 1206 | try gz.instructions.append(gpa, suspend_inst); |
| 1224 | 1207 | ||
| 1225 | var suspend_scope = gz.makeSubBlock(scope); | 1208 | var suspend_scope = gz.makeSubBlock(scope); |
| 1226 | suspend_scope.suspend_node = node; | 1209 | suspend_scope.suspend_node = node.toOptional(); |
| 1227 | defer suspend_scope.unstack(); | 1210 | defer suspend_scope.unstack(); |
| 1228 | 1211 | ||
| 1229 | 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); |
| ... | @@ -1243,16 +1226,15 @@ fn awaitExpr( | ... | @@ -1243,16 +1226,15 @@ fn awaitExpr( |
| 1243 | ) InnerError!Zir.Inst.Ref { | 1226 | ) InnerError!Zir.Inst.Ref { |
| 1244 | const astgen = gz.astgen; | 1227 | const astgen = gz.astgen; |
| 1245 | const tree = astgen.tree; | 1228 | const tree = astgen.tree; |
| 1246 | const node_datas = tree.nodes.items(.data); | 1229 | const rhs_node = tree.nodeData(node).node; |
| 1247 | const rhs_node = node_datas[node].lhs; | ||
| 1248 | 1230 | ||
| 1249 | if (gz.suspend_node != 0) { | 1231 | if (gz.suspend_node.unwrap()) |suspend_node| { |
| 1250 | return astgen.failNodeNotes(node, "cannot await inside suspend block", .{}, &[_]u32{ | 1232 | return astgen.failNodeNotes(node, "cannot await inside suspend block", .{}, &[_]u32{ |
| 1251 | try astgen.errNoteNode(gz.suspend_node, "suspend block here", .{}), | 1233 | try astgen.errNoteNode(suspend_node, "suspend block here", .{}), |
| 1252 | }); | 1234 | }); |
| 1253 | } | 1235 | } |
| 1254 | const operand = try expr(gz, scope, .{ .rl = .ref }, rhs_node); | 1236 | const operand = try expr(gz, scope, .{ .rl = .ref }, rhs_node); |
| 1255 | const result = if (gz.nosuspend_node != 0) | 1237 | const result = if (gz.nosuspend_node != .none) |
| 1256 | try gz.addExtendedPayload(.await_nosuspend, Zir.Inst.UnNode{ | 1238 | try gz.addExtendedPayload(.await_nosuspend, Zir.Inst.UnNode{ |
| 1257 | .node = gz.nodeIndexToRelative(node), | 1239 | .node = gz.nodeIndexToRelative(node), |
| 1258 | .operand = operand, | 1240 | .operand = operand, |
| ... | @@ -1271,8 +1253,7 @@ fn resumeExpr( | ... | @@ -1271,8 +1253,7 @@ fn resumeExpr( |
| 1271 | ) InnerError!Zir.Inst.Ref { | 1253 | ) InnerError!Zir.Inst.Ref { |
| 1272 | const astgen = gz.astgen; | 1254 | const astgen = gz.astgen; |
| 1273 | const tree = astgen.tree; | 1255 | const tree = astgen.tree; |
| 1274 | const node_datas = tree.nodes.items(.data); | 1256 | const rhs_node = tree.nodeData(node).node; |
| 1275 | const rhs_node = node_datas[node].lhs; | ||
| 1276 | const operand = try expr(gz, scope, .{ .rl = .ref }, rhs_node); | 1257 | const operand = try expr(gz, scope, .{ .rl = .ref }, rhs_node); |
| 1277 | const result = try gz.addUnNode(.@"resume", operand, node); | 1258 | const result = try gz.addUnNode(.@"resume", operand, node); |
| 1278 | return rvalue(gz, ri, result, node); | 1259 | return rvalue(gz, ri, result, node); |
| ... | @@ -1287,33 +1268,33 @@ fn fnProtoExpr( | ... | @@ -1287,33 +1268,33 @@ fn fnProtoExpr( |
| 1287 | ) InnerError!Zir.Inst.Ref { | 1268 | ) InnerError!Zir.Inst.Ref { |
| 1288 | const astgen = gz.astgen; | 1269 | const astgen = gz.astgen; |
| 1289 | const tree = astgen.tree; | 1270 | const tree = astgen.tree; |
| 1290 | const token_tags = tree.tokens.items(.tag); | ||
| 1291 | 1271 | ||
| 1292 | if (fn_proto.name_token) |some| { | 1272 | if (fn_proto.name_token) |some| { |
| 1293 | return astgen.failTok(some, "function type cannot have a name", .{}); | 1273 | return astgen.failTok(some, "function type cannot have a name", .{}); |
| 1294 | } | 1274 | } |
| 1295 | 1275 | ||
| 1296 | if (fn_proto.ast.align_expr != 0) { | 1276 | if (fn_proto.ast.align_expr.unwrap()) |align_expr| { |
| 1297 | 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", .{}); |
| 1298 | } | 1278 | } |
| 1299 | 1279 | ||
| 1300 | if (fn_proto.ast.addrspace_expr != 0) { | 1280 | if (fn_proto.ast.addrspace_expr.unwrap()) |addrspace_expr| { |
| 1301 | 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", .{}); |
| 1302 | } | 1282 | } |
| 1303 | 1283 | ||
| 1304 | if (fn_proto.ast.section_expr != 0) { | 1284 | if (fn_proto.ast.section_expr.unwrap()) |section_expr| { |
| 1305 | 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", .{}); |
| 1306 | } | 1286 | } |
| 1307 | 1287 | ||
| 1308 | const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1; | 1288 | const return_type = fn_proto.ast.return_type.unwrap().?; |
| 1309 | 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; | ||
| 1310 | if (is_inferred_error) { | 1291 | if (is_inferred_error) { |
| 1311 | 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", .{}); |
| 1312 | } | 1293 | } |
| 1313 | 1294 | ||
| 1314 | const is_extern = blk: { | 1295 | const is_extern = blk: { |
| 1315 | 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; |
| 1316 | break :blk token_tags[maybe_extern_token] == .keyword_extern; | 1297 | break :blk tree.tokenTag(maybe_extern_token) == .keyword_extern; |
| 1317 | }; | 1298 | }; |
| 1318 | assert(!is_extern); | 1299 | assert(!is_extern); |
| 1319 | 1300 | ||
| ... | @@ -1330,7 +1311,6 @@ fn fnProtoExprInner( | ... | @@ -1330,7 +1311,6 @@ fn fnProtoExprInner( |
| 1330 | ) InnerError!Zir.Inst.Ref { | 1311 | ) InnerError!Zir.Inst.Ref { |
| 1331 | const astgen = gz.astgen; | 1312 | const astgen = gz.astgen; |
| 1332 | const tree = astgen.tree; | 1313 | const tree = astgen.tree; |
| 1333 | const token_tags = tree.tokens.items(.tag); | ||
| 1334 | 1314 | ||
| 1335 | var block_scope = gz.makeSubBlock(scope); | 1315 | var block_scope = gz.makeSubBlock(scope); |
| 1336 | defer block_scope.unstack(); | 1316 | defer block_scope.unstack(); |
| ... | @@ -1342,7 +1322,7 @@ fn fnProtoExprInner( | ... | @@ -1342,7 +1322,7 @@ fn fnProtoExprInner( |
| 1342 | var param_type_i: usize = 0; | 1322 | var param_type_i: usize = 0; |
| 1343 | var it = fn_proto.iterate(tree); | 1323 | var it = fn_proto.iterate(tree); |
| 1344 | while (it.next()) |param| : (param_type_i += 1) { | 1324 | while (it.next()) |param| : (param_type_i += 1) { |
| 1345 | 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)) { |
| 1346 | .keyword_noalias => is_comptime: { | 1326 | .keyword_noalias => is_comptime: { |
| 1347 | 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 |
| 1348 | 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", .{})); |
| ... | @@ -1353,7 +1333,7 @@ fn fnProtoExprInner( | ... | @@ -1353,7 +1333,7 @@ fn fnProtoExprInner( |
| 1353 | } else false; | 1333 | } else false; |
| 1354 | 1334 | ||
| 1355 | const is_anytype = if (param.anytype_ellipsis3) |token| blk: { | 1335 | const is_anytype = if (param.anytype_ellipsis3) |token| blk: { |
| 1356 | switch (token_tags[token]) { | 1336 | switch (tree.tokenTag(token)) { |
| 1357 | .keyword_anytype => break :blk true, | 1337 | .keyword_anytype => break :blk true, |
| 1358 | .ellipsis3 => break :is_var_args true, | 1338 | .ellipsis3 => break :is_var_args true, |
| 1359 | else => unreachable, | 1339 | else => unreachable, |
| ... | @@ -1376,16 +1356,14 @@ fn fnProtoExprInner( | ... | @@ -1376,16 +1356,14 @@ fn fnProtoExprInner( |
| 1376 | .param_anytype; | 1356 | .param_anytype; |
| 1377 | _ = try block_scope.addStrTok(tag, param_name, name_token); | 1357 | _ = try block_scope.addStrTok(tag, param_name, name_token); |
| 1378 | } else { | 1358 | } else { |
| 1379 | const param_type_node = param.type_expr; | 1359 | const param_type_node = param.type_expr.?; |
| 1380 | assert(param_type_node != 0); | ||
| 1381 | var param_gz = block_scope.makeSubBlock(scope); | 1360 | var param_gz = block_scope.makeSubBlock(scope); |
| 1382 | defer param_gz.unstack(); | 1361 | defer param_gz.unstack(); |
| 1383 | param_gz.is_comptime = true; | 1362 | param_gz.is_comptime = true; |
| 1384 | 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); |
| 1385 | 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); |
| 1386 | _ = 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); |
| 1387 | const main_tokens = tree.nodes.items(.main_token); | 1366 | const name_token = param.name_token orelse tree.nodeMainToken(param_type_node); |
| 1388 | const name_token = param.name_token orelse main_tokens[param_type_node]; | ||
| 1389 | 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; |
| 1390 | // 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 |
| 1391 | // arguments (we haven't set up scopes here). | 1369 | // arguments (we haven't set up scopes here). |
| ... | @@ -1396,12 +1374,12 @@ fn fnProtoExprInner( | ... | @@ -1396,12 +1374,12 @@ fn fnProtoExprInner( |
| 1396 | break :is_var_args false; | 1374 | break :is_var_args false; |
| 1397 | }; | 1375 | }; |
| 1398 | 1376 | ||
| 1399 | 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| |
| 1400 | try comptimeExpr( | 1378 | try comptimeExpr( |
| 1401 | &block_scope, | 1379 | &block_scope, |
| 1402 | scope, | 1380 | scope, |
| 1403 | .{ .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) } }, |
| 1404 | fn_proto.ast.callconv_expr, | 1382 | callconv_expr, |
| 1405 | .@"callconv", | 1383 | .@"callconv", |
| 1406 | ) | 1384 | ) |
| 1407 | else if (implicit_ccc) | 1385 | else if (implicit_ccc) |
| ... | @@ -1409,7 +1387,8 @@ fn fnProtoExprInner( | ... | @@ -1409,7 +1387,8 @@ fn fnProtoExprInner( |
| 1409 | else | 1387 | else |
| 1410 | .none; | 1388 | .none; |
| 1411 | 1389 | ||
| 1412 | 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); | ||
| 1413 | 1392 | ||
| 1414 | const result = try block_scope.addFunc(.{ | 1393 | const result = try block_scope.addFunc(.{ |
| 1415 | .src_node = fn_proto.ast.proto_node, | 1394 | .src_node = fn_proto.ast.proto_node, |
| ... | @@ -1449,33 +1428,32 @@ fn arrayInitExpr( | ... | @@ -1449,33 +1428,32 @@ fn arrayInitExpr( |
| 1449 | ) InnerError!Zir.Inst.Ref { | 1428 | ) InnerError!Zir.Inst.Ref { |
| 1450 | const astgen = gz.astgen; | 1429 | const astgen = gz.astgen; |
| 1451 | const tree = astgen.tree; | 1430 | const tree = astgen.tree; |
| 1452 | const node_tags = tree.nodes.items(.tag); | ||
| 1453 | const main_tokens = tree.nodes.items(.main_token); | ||
| 1454 | 1431 | ||
| 1455 | 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. |
| 1456 | 1433 | ||
| 1457 | 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: { |
| 1458 | 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 }; |
| 1459 | 1436 | ||
| 1460 | infer: { | 1437 | infer: { |
| 1461 | 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; |
| 1462 | // This intentionally does not support `@"_"` syntax. | 1439 | // This intentionally does not support `@"_"` syntax. |
| 1463 | if (node_tags[array_type.ast.elem_count] == .identifier and | 1440 | if (tree.nodeTag(array_type.ast.elem_count) == .identifier and |
| 1464 | 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)), "_")) |
| 1465 | { | 1442 | { |
| 1466 | const len_inst = try gz.addInt(array_init.ast.elements.len); | 1443 | const len_inst = try gz.addInt(array_init.ast.elements.len); |
| 1467 | 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); |
| 1468 | if (array_type.ast.sentinel == 0) { | 1445 | if (array_type.ast.sentinel == .none) { |
| 1469 | 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{ |
| 1470 | .lhs = len_inst, | 1447 | .lhs = len_inst, |
| 1471 | .rhs = elem_type, | 1448 | .rhs = elem_type, |
| 1472 | }); | 1449 | }); |
| 1473 | break :inst .{ array_type_inst, elem_type }; | 1450 | break :inst .{ array_type_inst, elem_type }; |
| 1474 | } else { | 1451 | } else { |
| 1475 | 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); | ||
| 1476 | const array_type_inst = try gz.addPlNode( | 1454 | const array_type_inst = try gz.addPlNode( |
| 1477 | .array_type_sentinel, | 1455 | .array_type_sentinel, |
| 1478 | array_init.ast.type_expr, | 1456 | type_expr, |
| 1479 | Zir.Inst.ArrayTypeSentinel{ | 1457 | Zir.Inst.ArrayTypeSentinel{ |
| 1480 | .len = len_inst, | 1458 | .len = len_inst, |
| 1481 | .elem_type = elem_type, | 1459 | .elem_type = elem_type, |
| ... | @@ -1486,7 +1464,7 @@ fn arrayInitExpr( | ... | @@ -1486,7 +1464,7 @@ fn arrayInitExpr( |
| 1486 | } | 1464 | } |
| 1487 | } | 1465 | } |
| 1488 | } | 1466 | } |
| 1489 | const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr); | 1467 | const array_type_inst = try typeExpr(gz, scope, type_expr); |
| 1490 | _ = try gz.addPlNode(.validate_array_init_ty, node, Zir.Inst.ArrayInit{ | 1468 | _ = try gz.addPlNode(.validate_array_init_ty, node, Zir.Inst.ArrayInit{ |
| 1491 | .ty = array_type_inst, | 1469 | .ty = array_type_inst, |
| 1492 | .init_count = @intCast(array_init.ast.elements.len), | 1470 | .init_count = @intCast(array_init.ast.elements.len), |
| ... | @@ -1694,7 +1672,7 @@ fn structInitExpr( | ... | @@ -1694,7 +1672,7 @@ fn structInitExpr( |
| 1694 | const astgen = gz.astgen; | 1672 | const astgen = gz.astgen; |
| 1695 | const tree = astgen.tree; | 1673 | const tree = astgen.tree; |
| 1696 | 1674 | ||
| 1697 | if (struct_init.ast.type_expr == 0) { | 1675 | if (struct_init.ast.type_expr == .none) { |
| 1698 | if (struct_init.ast.fields.len == 0) { | 1676 | if (struct_init.ast.fields.len == 0) { |
| 1699 | // Anonymous init with no fields. | 1677 | // Anonymous init with no fields. |
| 1700 | switch (ri.rl) { | 1678 | switch (ri.rl) { |
| ... | @@ -1718,32 +1696,32 @@ fn structInitExpr( | ... | @@ -1718,32 +1696,32 @@ fn structInitExpr( |
| 1718 | } | 1696 | } |
| 1719 | } | 1697 | } |
| 1720 | } else array: { | 1698 | } else array: { |
| 1721 | const node_tags = tree.nodes.items(.tag); | 1699 | const type_expr = struct_init.ast.type_expr.unwrap().?; |
| 1722 | const main_tokens = tree.nodes.items(.main_token); | 1700 | const array_type: Ast.full.ArrayType = tree.fullArrayType(type_expr) orelse { |
| 1723 | const array_type: Ast.full.ArrayType = tree.fullArrayType(struct_init.ast.type_expr) orelse { | ||
| 1724 | if (struct_init.ast.fields.len == 0) { | 1701 | if (struct_init.ast.fields.len == 0) { |
| 1725 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); | 1702 | const ty_inst = try typeExpr(gz, scope, type_expr); |
| 1726 | const result = try gz.addUnNode(.struct_init_empty, ty_inst, node); | 1703 | const result = try gz.addUnNode(.struct_init_empty, ty_inst, node); |
| 1727 | return rvalue(gz, ri, result, node); | 1704 | return rvalue(gz, ri, result, node); |
| 1728 | } | 1705 | } |
| 1729 | break :array; | 1706 | break :array; |
| 1730 | }; | 1707 | }; |
| 1731 | 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 |
| 1732 | // This intentionally does not support `@"_"` syntax. | 1709 | // This intentionally does not support `@"_"` syntax. |
| 1733 | 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)), "_"); |
| 1734 | if (struct_init.ast.fields.len == 0) { | 1711 | if (struct_init.ast.fields.len == 0) { |
| 1735 | if (is_inferred_array_len) { | 1712 | if (is_inferred_array_len) { |
| 1736 | 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); |
| 1737 | const array_type_inst = if (array_type.ast.sentinel == 0) blk: { | 1714 | const array_type_inst = if (array_type.ast.sentinel == .none) blk: { |
| 1738 | 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{ |
| 1739 | .lhs = .zero_usize, | 1716 | .lhs = .zero_usize, |
| 1740 | .rhs = elem_type, | 1717 | .rhs = elem_type, |
| 1741 | }); | 1718 | }); |
| 1742 | } else blk: { | 1719 | } else blk: { |
| 1743 | 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); | ||
| 1744 | break :blk try gz.addPlNode( | 1722 | break :blk try gz.addPlNode( |
| 1745 | .array_type_sentinel, | 1723 | .array_type_sentinel, |
| 1746 | struct_init.ast.type_expr, | 1724 | type_expr, |
| 1747 | Zir.Inst.ArrayTypeSentinel{ | 1725 | Zir.Inst.ArrayTypeSentinel{ |
| 1748 | .len = .zero_usize, | 1726 | .len = .zero_usize, |
| 1749 | .elem_type = elem_type, | 1727 | .elem_type = elem_type, |
| ... | @@ -1754,12 +1732,12 @@ fn structInitExpr( | ... | @@ -1754,12 +1732,12 @@ fn structInitExpr( |
| 1754 | 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); |
| 1755 | return rvalue(gz, ri, result, node); | 1733 | return rvalue(gz, ri, result, node); |
| 1756 | } | 1734 | } |
| 1757 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); | 1735 | const ty_inst = try typeExpr(gz, scope, type_expr); |
| 1758 | const result = try gz.addUnNode(.struct_init_empty, ty_inst, node); | 1736 | const result = try gz.addUnNode(.struct_init_empty, ty_inst, node); |
| 1759 | return rvalue(gz, ri, result, node); | 1737 | return rvalue(gz, ri, result, node); |
| 1760 | } else { | 1738 | } else { |
| 1761 | return astgen.failNode( | 1739 | return astgen.failNode( |
| 1762 | struct_init.ast.type_expr, | 1740 | type_expr, |
| 1763 | "initializing array with struct syntax", | 1741 | "initializing array with struct syntax", |
| 1764 | .{}, | 1742 | .{}, |
| 1765 | ); | 1743 | ); |
| ... | @@ -1818,9 +1796,9 @@ fn structInitExpr( | ... | @@ -1818,9 +1796,9 @@ fn structInitExpr( |
| 1818 | } | 1796 | } |
| 1819 | } | 1797 | } |
| 1820 | 1798 | ||
| 1821 | if (struct_init.ast.type_expr != 0) { | 1799 | if (struct_init.ast.type_expr.unwrap()) |type_expr| { |
| 1822 | // Typed inits do not use RLS for language simplicity. | 1800 | // Typed inits do not use RLS for language simplicity. |
| 1823 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); | 1801 | const ty_inst = try typeExpr(gz, scope, type_expr); |
| 1824 | _ = try gz.addUnNode(.validate_struct_init_ty, ty_inst, node); | 1802 | _ = try gz.addUnNode(.validate_struct_init_ty, ty_inst, node); |
| 1825 | switch (ri.rl) { | 1803 | switch (ri.rl) { |
| 1826 | .ref => return structInitExprTyped(gz, scope, node, struct_init, ty_inst, true), | 1804 | .ref => return structInitExprTyped(gz, scope, node, struct_init, ty_inst, true), |
| ... | @@ -2009,9 +1987,7 @@ fn comptimeExpr2( | ... | @@ -2009,9 +1987,7 @@ fn comptimeExpr2( |
| 2009 | // 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 |
| 2010 | // 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. |
| 2011 | const tree = gz.astgen.tree; | 1989 | const tree = gz.astgen.tree; |
| 2012 | const main_tokens = tree.nodes.items(.main_token); | 1990 | switch (tree.nodeTag(node)) { |
| 2013 | const node_tags = tree.nodes.items(.tag); | ||
| 2014 | switch (node_tags[node]) { | ||
| 2015 | .identifier => { | 1991 | .identifier => { |
| 2016 | // 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 |
| 2017 | // special handling for this case. | 1993 | // special handling for this case. |
| ... | @@ -2064,8 +2040,7 @@ fn comptimeExpr2( | ... | @@ -2064,8 +2040,7 @@ fn comptimeExpr2( |
| 2064 | // 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 |
| 2065 | // 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`). |
| 2066 | .block_two, .block_two_semicolon, .block, .block_semicolon => { | 2042 | .block_two, .block_two_semicolon, .block, .block_semicolon => { |
| 2067 | const token_tags = tree.tokens.items(.tag); | 2043 | const lbrace = tree.nodeMainToken(node); |
| 2068 | const lbrace = main_tokens[node]; | ||
| 2069 | // 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 |
| 2070 | // 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 |
| 2071 | // 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 |
| ... | @@ -2077,31 +2052,13 @@ fn comptimeExpr2( | ... | @@ -2077,31 +2052,13 @@ fn comptimeExpr2( |
| 2077 | else | 2052 | else |
| 2078 | .none, | 2053 | .none, |
| 2079 | }; | 2054 | }; |
| 2080 | if (token_tags[lbrace - 1] == .colon and | 2055 | if (tree.isTokenPrecededByTags(lbrace, &.{ .identifier, .colon })) { |
| 2081 | token_tags[lbrace - 2] == .identifier) | 2056 | var buf: [2]Ast.Node.Index = undefined; |
| 2082 | { | 2057 | const stmts = tree.blockStatements(&buf, node).?; |
| 2083 | const node_datas = tree.nodes.items(.data); | ||
| 2084 | switch (node_tags[node]) { | ||
| 2085 | .block_two, .block_two_semicolon => { | ||
| 2086 | const stmts: [2]Ast.Node.Index = .{ node_datas[node].lhs, node_datas[node].rhs }; | ||
| 2087 | const stmt_slice = if (stmts[0] == 0) | ||
| 2088 | stmts[0..0] | ||
| 2089 | else if (stmts[1] == 0) | ||
| 2090 | stmts[0..1] | ||
| 2091 | else | ||
| 2092 | stmts[0..2]; | ||
| 2093 | 2058 | ||
| 2094 | const block_ref = try labeledBlockExpr(gz, scope, ty_only_ri, node, stmt_slice, true, .normal); | 2059 | // Replace result location and copy back later - see above. |
| 2095 | return rvalue(gz, ri, block_ref, node); | 2060 | const block_ref = try labeledBlockExpr(gz, scope, ty_only_ri, node, stmts, true, .normal); |
| 2096 | }, | 2061 | return rvalue(gz, ri, block_ref, node); |
| 2097 | .block, .block_semicolon => { | ||
| 2098 | const stmts = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; | ||
| 2099 | // Replace result location and copy back later - see above. | ||
| 2100 | const block_ref = try labeledBlockExpr(gz, scope, ty_only_ri, node, stmts, true, .normal); | ||
| 2101 | return rvalue(gz, ri, block_ref, node); | ||
| 2102 | }, | ||
| 2103 | else => unreachable, | ||
| 2104 | } | ||
| 2105 | } | 2062 | } |
| 2106 | }, | 2063 | }, |
| 2107 | 2064 | ||
| ... | @@ -2146,8 +2103,7 @@ fn comptimeExprAst( | ... | @@ -2146,8 +2103,7 @@ fn comptimeExprAst( |
| 2146 | try astgen.appendErrorNode(node, "redundant comptime keyword in already comptime scope", .{}); | 2103 | try astgen.appendErrorNode(node, "redundant comptime keyword in already comptime scope", .{}); |
| 2147 | } | 2104 | } |
| 2148 | const tree = astgen.tree; | 2105 | const tree = astgen.tree; |
| 2149 | const node_datas = tree.nodes.items(.data); | 2106 | const body_node = tree.nodeData(node).node; |
| 2150 | const body_node = node_datas[node].lhs; | ||
| 2151 | return comptimeExpr2(gz, scope, ri, body_node, node, .comptime_keyword); | 2107 | return comptimeExpr2(gz, scope, ri, body_node, node, .comptime_keyword); |
| 2152 | } | 2108 | } |
| 2153 | 2109 | ||
| ... | @@ -2185,9 +2141,7 @@ fn restoreErrRetIndex( | ... | @@ -2185,9 +2141,7 @@ fn restoreErrRetIndex( |
| 2185 | 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 { |
| 2186 | const astgen = parent_gz.astgen; | 2142 | const astgen = parent_gz.astgen; |
| 2187 | const tree = astgen.tree; | 2143 | const tree = astgen.tree; |
| 2188 | const node_datas = tree.nodes.items(.data); | 2144 | const opt_break_label, const opt_rhs = tree.nodeData(node).opt_token_and_opt_node; |
| 2189 | const break_label = node_datas[node].lhs; | ||
| 2190 | const rhs = node_datas[node].rhs; | ||
| 2191 | 2145 | ||
| 2192 | // Look for the label in the scope. | 2146 | // Look for the label in the scope. |
| 2193 | var scope = parent_scope; | 2147 | var scope = parent_scope; |
| ... | @@ -2196,11 +2150,11 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -2196,11 +2150,11 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 2196 | .gen_zir => { | 2150 | .gen_zir => { |
| 2197 | const block_gz = scope.cast(GenZir).?; | 2151 | const block_gz = scope.cast(GenZir).?; |
| 2198 | 2152 | ||
| 2199 | if (block_gz.cur_defer_node != 0) { | 2153 | if (block_gz.cur_defer_node.unwrap()) |cur_defer_node| { |
| 2200 | // We are breaking out of a `defer` block. | 2154 | // We are breaking out of a `defer` block. |
| 2201 | return astgen.failNodeNotes(node, "cannot break out of defer expression", .{}, &.{ | 2155 | return astgen.failNodeNotes(node, "cannot break out of defer expression", .{}, &.{ |
| 2202 | try astgen.errNoteNode( | 2156 | try astgen.errNoteNode( |
| 2203 | block_gz.cur_defer_node, | 2157 | cur_defer_node, |
| 2204 | "defer expression here", | 2158 | "defer expression here", |
| 2205 | .{}, | 2159 | .{}, |
| 2206 | ), | 2160 | ), |
| ... | @@ -2208,7 +2162,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -2208,7 +2162,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 2208 | } | 2162 | } |
| 2209 | 2163 | ||
| 2210 | const block_inst = blk: { | 2164 | const block_inst = blk: { |
| 2211 | if (break_label != 0) { | 2165 | if (opt_break_label.unwrap()) |break_label| { |
| 2212 | if (block_gz.label) |*label| { | 2166 | if (block_gz.label) |*label| { |
| 2213 | if (try astgen.tokenIdentEql(label.token, break_label)) { | 2167 | if (try astgen.tokenIdentEql(label.token, break_label)) { |
| 2214 | label.used = true; | 2168 | label.used = true; |
| ... | @@ -2229,7 +2183,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -2229,7 +2183,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 2229 | else | 2183 | else |
| 2230 | .@"break"; | 2184 | .@"break"; |
| 2231 | 2185 | ||
| 2232 | if (rhs == 0) { | 2186 | const rhs = opt_rhs.unwrap() orelse { |
| 2233 | _ = 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); |
| 2234 | 2188 | ||
| 2235 | try genDefers(parent_gz, scope, parent_scope, .normal_only); | 2189 | try genDefers(parent_gz, scope, parent_scope, .normal_only); |
| ... | @@ -2240,7 +2194,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -2240,7 +2194,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 2240 | 2194 | ||
| 2241 | _ = try parent_gz.addBreak(break_tag, block_inst, .void_value); | 2195 | _ = try parent_gz.addBreak(break_tag, block_inst, .void_value); |
| 2242 | return Zir.Inst.Ref.unreachable_value; | 2196 | return Zir.Inst.Ref.unreachable_value; |
| 2243 | } | 2197 | }; |
| 2244 | 2198 | ||
| 2245 | 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); |
| 2246 | 2200 | ||
| ... | @@ -2272,7 +2226,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -2272,7 +2226,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 2272 | .top => unreachable, | 2226 | .top => unreachable, |
| 2273 | } | 2227 | } |
| 2274 | } | 2228 | } |
| 2275 | if (break_label != 0) { | 2229 | if (opt_break_label.unwrap()) |break_label| { |
| 2276 | const label_name = try astgen.identifierTokenString(break_label); | 2230 | const label_name = try astgen.identifierTokenString(break_label); |
| 2277 | return astgen.failTok(break_label, "label not found: '{s}'", .{label_name}); | 2231 | return astgen.failTok(break_label, "label not found: '{s}'", .{label_name}); |
| 2278 | } else { | 2232 | } else { |
| ... | @@ -2283,11 +2237,9 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -2283,11 +2237,9 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 2283 | 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 { |
| 2284 | const astgen = parent_gz.astgen; | 2238 | const astgen = parent_gz.astgen; |
| 2285 | const tree = astgen.tree; | 2239 | const tree = astgen.tree; |
| 2286 | const node_datas = tree.nodes.items(.data); | 2240 | const opt_break_label, const opt_rhs = tree.nodeData(node).opt_token_and_opt_node; |
| 2287 | const break_label = node_datas[node].lhs; | ||
| 2288 | const rhs = node_datas[node].rhs; | ||
| 2289 | 2241 | ||
| 2290 | if (break_label == 0 and rhs != 0) { | 2242 | if (opt_break_label == .none and opt_rhs != .none) { |
| 2291 | return astgen.failNode(node, "cannot continue with operand without label", .{}); | 2243 | return astgen.failNode(node, "cannot continue with operand without label", .{}); |
| 2292 | } | 2244 | } |
| 2293 | 2245 | ||
| ... | @@ -2298,10 +2250,10 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) | ... | @@ -2298,10 +2250,10 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) |
| 2298 | .gen_zir => { | 2250 | .gen_zir => { |
| 2299 | const gen_zir = scope.cast(GenZir).?; | 2251 | const gen_zir = scope.cast(GenZir).?; |
| 2300 | 2252 | ||
| 2301 | if (gen_zir.cur_defer_node != 0) { | 2253 | if (gen_zir.cur_defer_node.unwrap()) |cur_defer_node| { |
| 2302 | return astgen.failNodeNotes(node, "cannot continue out of defer expression", .{}, &.{ | 2254 | return astgen.failNodeNotes(node, "cannot continue out of defer expression", .{}, &.{ |
| 2303 | try astgen.errNoteNode( | 2255 | try astgen.errNoteNode( |
| 2304 | gen_zir.cur_defer_node, | 2256 | cur_defer_node, |
| 2305 | "defer expression here", | 2257 | "defer expression here", |
| 2306 | .{}, | 2258 | .{}, |
| 2307 | ), | 2259 | ), |
| ... | @@ -2311,11 +2263,11 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) | ... | @@ -2311,11 +2263,11 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) |
| 2311 | scope = gen_zir.parent; | 2263 | scope = gen_zir.parent; |
| 2312 | continue; | 2264 | continue; |
| 2313 | }; | 2265 | }; |
| 2314 | if (break_label != 0) blk: { | 2266 | if (opt_break_label.unwrap()) |break_label| blk: { |
| 2315 | if (gen_zir.label) |*label| { | 2267 | if (gen_zir.label) |*label| { |
| 2316 | if (try astgen.tokenIdentEql(label.token, break_label)) { | 2268 | if (try astgen.tokenIdentEql(label.token, break_label)) { |
| 2317 | 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)]; |
| 2318 | if (rhs != 0) switch (maybe_switch_tag) { | 2270 | if (opt_rhs != .none) switch (maybe_switch_tag) { |
| 2319 | .switch_block, .switch_block_ref => {}, | 2271 | .switch_block, .switch_block_ref => {}, |
| 2320 | else => return astgen.failNode(node, "cannot continue loop with operand", .{}), | 2272 | else => return astgen.failNode(node, "cannot continue loop with operand", .{}), |
| 2321 | } else switch (maybe_switch_tag) { | 2273 | } else switch (maybe_switch_tag) { |
| ... | @@ -2343,7 +2295,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) | ... | @@ -2343,7 +2295,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) |
| 2343 | } | 2295 | } |
| 2344 | } | 2296 | } |
| 2345 | 2297 | ||
| 2346 | if (rhs != 0) { | 2298 | if (opt_rhs.unwrap()) |rhs| { |
| 2347 | // We need to figure out the result info to use. | 2299 | // We need to figure out the result info to use. |
| 2348 | // The type should match | 2300 | // The type should match |
| 2349 | 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); |
| ... | @@ -2382,7 +2334,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) | ... | @@ -2382,7 +2334,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) |
| 2382 | .top => unreachable, | 2334 | .top => unreachable, |
| 2383 | } | 2335 | } |
| 2384 | } | 2336 | } |
| 2385 | if (break_label != 0) { | 2337 | if (opt_break_label.unwrap()) |break_label| { |
| 2386 | const label_name = try astgen.identifierTokenString(break_label); | 2338 | const label_name = try astgen.identifierTokenString(break_label); |
| 2387 | return astgen.failTok(break_label, "label not found: '{s}'", .{label_name}); | 2339 | return astgen.failTok(break_label, "label not found: '{s}'", .{label_name}); |
| 2388 | } else { | 2340 | } else { |
| ... | @@ -2402,30 +2354,14 @@ fn fullBodyExpr( | ... | @@ -2402,30 +2354,14 @@ fn fullBodyExpr( |
| 2402 | block_kind: BlockKind, | 2354 | block_kind: BlockKind, |
| 2403 | ) InnerError!Zir.Inst.Ref { | 2355 | ) InnerError!Zir.Inst.Ref { |
| 2404 | const tree = gz.astgen.tree; | 2356 | const tree = gz.astgen.tree; |
| 2405 | const node_tags = tree.nodes.items(.tag); | 2357 | |
| 2406 | const node_datas = tree.nodes.items(.data); | ||
| 2407 | const main_tokens = tree.nodes.items(.main_token); | ||
| 2408 | const token_tags = tree.tokens.items(.tag); | ||
| 2409 | var stmt_buf: [2]Ast.Node.Index = undefined; | 2358 | var stmt_buf: [2]Ast.Node.Index = undefined; |
| 2410 | const statements: []const Ast.Node.Index = switch (node_tags[node]) { | 2359 | const statements = tree.blockStatements(&stmt_buf, node) orelse |
| 2411 | else => return expr(gz, scope, ri, node), | 2360 | return expr(gz, scope, ri, node); |
| 2412 | .block_two, .block_two_semicolon => if (node_datas[node].lhs == 0) s: { | ||
| 2413 | break :s &.{}; | ||
| 2414 | } else if (node_datas[node].rhs == 0) s: { | ||
| 2415 | stmt_buf[0] = node_datas[node].lhs; | ||
| 2416 | break :s stmt_buf[0..1]; | ||
| 2417 | } else s: { | ||
| 2418 | stmt_buf[0] = node_datas[node].lhs; | ||
| 2419 | stmt_buf[1] = node_datas[node].rhs; | ||
| 2420 | break :s stmt_buf[0..2]; | ||
| 2421 | }, | ||
| 2422 | .block, .block_semicolon => tree.extra_data[node_datas[node].lhs..node_datas[node].rhs], | ||
| 2423 | }; | ||
| 2424 | 2361 | ||
| 2425 | const lbrace = main_tokens[node]; | 2362 | const lbrace = tree.nodeMainToken(node); |
| 2426 | if (token_tags[lbrace - 1] == .colon and | 2363 | |
| 2427 | token_tags[lbrace - 2] == .identifier) | 2364 | if (tree.isTokenPrecededByTags(lbrace, &.{ .identifier, .colon })) { |
| 2428 | { | ||
| 2429 | // 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, |
| 2430 | // 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 |
| 2431 | // 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. |
| ... | @@ -2450,13 +2386,9 @@ fn blockExpr( | ... | @@ -2450,13 +2386,9 @@ fn blockExpr( |
| 2450 | ) InnerError!Zir.Inst.Ref { | 2386 | ) InnerError!Zir.Inst.Ref { |
| 2451 | const astgen = gz.astgen; | 2387 | const astgen = gz.astgen; |
| 2452 | const tree = astgen.tree; | 2388 | const tree = astgen.tree; |
| 2453 | const main_tokens = tree.nodes.items(.main_token); | ||
| 2454 | const token_tags = tree.tokens.items(.tag); | ||
| 2455 | 2389 | ||
| 2456 | const lbrace = main_tokens[block_node]; | 2390 | const lbrace = tree.nodeMainToken(block_node); |
| 2457 | if (token_tags[lbrace - 1] == .colon and | 2391 | if (tree.isTokenPrecededByTags(lbrace, &.{ .identifier, .colon })) { |
| 2458 | token_tags[lbrace - 2] == .identifier) | ||
| 2459 | { | ||
| 2460 | return labeledBlockExpr(gz, scope, ri, block_node, statements, false, kind); | 2392 | return labeledBlockExpr(gz, scope, ri, block_node, statements, false, kind); |
| 2461 | } | 2393 | } |
| 2462 | 2394 | ||
| ... | @@ -2533,12 +2465,10 @@ fn labeledBlockExpr( | ... | @@ -2533,12 +2465,10 @@ fn labeledBlockExpr( |
| 2533 | ) InnerError!Zir.Inst.Ref { | 2465 | ) InnerError!Zir.Inst.Ref { |
| 2534 | const astgen = gz.astgen; | 2466 | const astgen = gz.astgen; |
| 2535 | const tree = astgen.tree; | 2467 | const tree = astgen.tree; |
| 2536 | const main_tokens = tree.nodes.items(.main_token); | ||
| 2537 | const token_tags = tree.tokens.items(.tag); | ||
| 2538 | 2468 | ||
| 2539 | const lbrace = main_tokens[block_node]; | 2469 | const lbrace = tree.nodeMainToken(block_node); |
| 2540 | const label_token = lbrace - 2; | 2470 | const label_token = lbrace - 2; |
| 2541 | assert(token_tags[label_token] == .identifier); | 2471 | assert(tree.tokenTag(label_token) == .identifier); |
| 2542 | 2472 | ||
| 2543 | try astgen.checkLabelRedefinition(parent_scope, label_token); | 2473 | try astgen.checkLabelRedefinition(parent_scope, label_token); |
| 2544 | 2474 | ||
| ... | @@ -2599,8 +2529,6 @@ fn labeledBlockExpr( | ... | @@ -2599,8 +2529,6 @@ fn labeledBlockExpr( |
| 2599 | 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 { |
| 2600 | const astgen = gz.astgen; | 2530 | const astgen = gz.astgen; |
| 2601 | const tree = astgen.tree; | 2531 | const tree = astgen.tree; |
| 2602 | const node_tags = tree.nodes.items(.tag); | ||
| 2603 | const node_data = tree.nodes.items(.data); | ||
| 2604 | 2532 | ||
| 2605 | if (statements.len == 0) return; | 2533 | if (statements.len == 0) return; |
| 2606 | 2534 | ||
| ... | @@ -2608,17 +2536,17 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod | ... | @@ -2608,17 +2536,17 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod |
| 2608 | defer block_arena.deinit(); | 2536 | defer block_arena.deinit(); |
| 2609 | const block_arena_allocator = block_arena.allocator(); | 2537 | const block_arena_allocator = block_arena.allocator(); |
| 2610 | 2538 | ||
| 2611 | var noreturn_src_node: Ast.Node.Index = 0; | 2539 | var noreturn_src_node: Ast.Node.OptionalIndex = .none; |
| 2612 | var scope = parent_scope; | 2540 | var scope = parent_scope; |
| 2613 | for (statements, 0..) |statement, stmt_idx| { | 2541 | for (statements, 0..) |statement, stmt_idx| { |
| 2614 | if (noreturn_src_node != 0) { | 2542 | if (noreturn_src_node.unwrap()) |src_node| { |
| 2615 | try astgen.appendErrorNodeNotes( | 2543 | try astgen.appendErrorNodeNotes( |
| 2616 | statement, | 2544 | statement, |
| 2617 | "unreachable code", | 2545 | "unreachable code", |
| 2618 | .{}, | 2546 | .{}, |
| 2619 | &[_]u32{ | 2547 | &[_]u32{ |
| 2620 | try astgen.errNoteNode( | 2548 | try astgen.errNoteNode( |
| 2621 | noreturn_src_node, | 2549 | src_node, |
| 2622 | "control flow is diverted here", | 2550 | "control flow is diverted here", |
| 2623 | .{}, | 2551 | .{}, |
| 2624 | ), | 2552 | ), |
| ... | @@ -2631,7 +2559,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod | ... | @@ -2631,7 +2559,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod |
| 2631 | }; | 2559 | }; |
| 2632 | var inner_node = statement; | 2560 | var inner_node = statement; |
| 2633 | while (true) { | 2561 | while (true) { |
| 2634 | switch (node_tags[inner_node]) { | 2562 | switch (tree.nodeTag(inner_node)) { |
| 2635 | // zig fmt: off | 2563 | // zig fmt: off |
| 2636 | .global_var_decl, | 2564 | .global_var_decl, |
| 2637 | .local_var_decl, | 2565 | .local_var_decl, |
| ... | @@ -2661,7 +2589,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod | ... | @@ -2661,7 +2589,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod |
| 2661 | .assign_mul_wrap => try assignOp(gz, scope, statement, .mulwrap), | 2589 | .assign_mul_wrap => try assignOp(gz, scope, statement, .mulwrap), |
| 2662 | 2590 | ||
| 2663 | .grouped_expression => { | 2591 | .grouped_expression => { |
| 2664 | inner_node = node_data[statement].lhs; | 2592 | inner_node = tree.nodeData(statement).node_and_token[0]; |
| 2665 | continue; | 2593 | continue; |
| 2666 | }, | 2594 | }, |
| 2667 | 2595 | ||
| ... | @@ -2671,47 +2599,37 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod | ... | @@ -2671,47 +2599,37 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod |
| 2671 | 2599 | ||
| 2672 | .for_simple, | 2600 | .for_simple, |
| 2673 | .@"for", => _ = try forExpr(gz, scope, .{ .rl = .none }, inner_node, tree.fullFor(inner_node).?, true), | 2601 | .@"for", => _ = try forExpr(gz, scope, .{ .rl = .none }, inner_node, tree.fullFor(inner_node).?, true), |
| 2602 | // zig fmt: on | ||
| 2674 | 2603 | ||
| 2675 | // These cases are here to allow branch hints. | 2604 | // These cases are here to allow branch hints. |
| 2676 | .builtin_call_two, .builtin_call_two_comma => { | 2605 | .builtin_call_two, |
| 2677 | try emitDbgNode(gz, inner_node); | 2606 | .builtin_call_two_comma, |
| 2678 | const ri: ResultInfo = .{ .rl = .none }; | 2607 | .builtin_call, |
| 2679 | const result = if (node_data[inner_node].lhs == 0) r: { | 2608 | .builtin_call_comma, |
| 2680 | break :r try builtinCall(gz, scope, ri, inner_node, &.{}, allow_branch_hint); | 2609 | => { |
| 2681 | } else if (node_data[inner_node].rhs == 0) r: { | 2610 | var buf: [2]Ast.Node.Index = undefined; |
| 2682 | break :r try builtinCall(gz, scope, ri, inner_node, &.{node_data[inner_node].lhs}, allow_branch_hint); | 2611 | const params = tree.builtinCallParams(&buf, inner_node).?; |
| 2683 | } else r: { | 2612 | |
| 2684 | break :r try builtinCall(gz, scope, ri, inner_node, &.{ | ||
| 2685 | node_data[inner_node].lhs, | ||
| 2686 | node_data[inner_node].rhs, | ||
| 2687 | }, allow_branch_hint); | ||
| 2688 | }; | ||
| 2689 | noreturn_src_node = try addEnsureResult(gz, result, inner_node); | ||
| 2690 | }, | ||
| 2691 | .builtin_call, .builtin_call_comma => { | ||
| 2692 | try emitDbgNode(gz, inner_node); | 2613 | try emitDbgNode(gz, inner_node); |
| 2693 | const ri: ResultInfo = .{ .rl = .none }; | 2614 | const result = try builtinCall(gz, scope, .{ .rl = .none }, inner_node, params, allow_branch_hint); |
| 2694 | const params = tree.extra_data[node_data[inner_node].lhs..node_data[inner_node].rhs]; | ||
| 2695 | const result = try builtinCall(gz, scope, ri, inner_node, params, allow_branch_hint); | ||
| 2696 | noreturn_src_node = try addEnsureResult(gz, result, inner_node); | 2615 | noreturn_src_node = try addEnsureResult(gz, result, inner_node); |
| 2697 | }, | 2616 | }, |
| 2698 | 2617 | ||
| 2699 | else => noreturn_src_node = try unusedResultExpr(gz, scope, inner_node), | 2618 | else => noreturn_src_node = try unusedResultExpr(gz, scope, inner_node), |
| 2700 | // zig fmt: on | ||
| 2701 | } | 2619 | } |
| 2702 | break; | 2620 | break; |
| 2703 | } | 2621 | } |
| 2704 | } | 2622 | } |
| 2705 | 2623 | ||
| 2706 | if (noreturn_src_node == 0) { | 2624 | if (noreturn_src_node == .none) { |
| 2707 | try genDefers(gz, parent_scope, scope, .normal_only); | 2625 | try genDefers(gz, parent_scope, scope, .normal_only); |
| 2708 | } | 2626 | } |
| 2709 | try checkUsed(gz, parent_scope, scope); | 2627 | try checkUsed(gz, parent_scope, scope); |
| 2710 | } | 2628 | } |
| 2711 | 2629 | ||
| 2712 | /// 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 |
| 2713 | /// definitely `noreturn`. Otherwise returns 0. | 2631 | /// definitely `noreturn`. Otherwise returns .none. |
| 2714 | 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 { |
| 2715 | try emitDbgNode(gz, statement); | 2633 | try emitDbgNode(gz, statement); |
| 2716 | // 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 |
| 2717 | // 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. |
| ... | @@ -2719,8 +2637,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner | ... | @@ -2719,8 +2637,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner |
| 2719 | return addEnsureResult(gz, maybe_unused_result, statement); | 2637 | return addEnsureResult(gz, maybe_unused_result, statement); |
| 2720 | } | 2638 | } |
| 2721 | 2639 | ||
| 2722 | 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 { |
| 2723 | var noreturn_src_node: Ast.Node.Index = 0; | 2641 | var noreturn_src_node: Ast.Node.OptionalIndex = .none; |
| 2724 | const elide_check = if (maybe_unused_result.toIndex()) |inst| b: { | 2642 | const elide_check = if (maybe_unused_result.toIndex()) |inst| b: { |
| 2725 | // 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 |
| 2726 | // in the above while loop. | 2644 | // in the above while loop. |
| ... | @@ -2981,7 +2899,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As | ... | @@ -2981,7 +2899,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2981 | .check_comptime_control_flow, | 2899 | .check_comptime_control_flow, |
| 2982 | .switch_continue, | 2900 | .switch_continue, |
| 2983 | => { | 2901 | => { |
| 2984 | noreturn_src_node = statement; | 2902 | noreturn_src_node = statement.toOptional(); |
| 2985 | break :b true; | 2903 | break :b true; |
| 2986 | }, | 2904 | }, |
| 2987 | 2905 | ||
| ... | @@ -3023,7 +2941,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As | ... | @@ -3023,7 +2941,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 3023 | .none => unreachable, | 2941 | .none => unreachable, |
| 3024 | 2942 | ||
| 3025 | .unreachable_value => b: { | 2943 | .unreachable_value => b: { |
| 3026 | noreturn_src_node = statement; | 2944 | noreturn_src_node = statement.toOptional(); |
| 3027 | break :b true; | 2945 | break :b true; |
| 3028 | }, | 2946 | }, |
| 3029 | 2947 | ||
| ... | @@ -3152,23 +3070,23 @@ fn checkUsed(gz: *GenZir, outer_scope: *Scope, inner_scope: *Scope) InnerError!v | ... | @@ -3152,23 +3070,23 @@ fn checkUsed(gz: *GenZir, outer_scope: *Scope, inner_scope: *Scope) InnerError!v |
| 3152 | .gen_zir => scope = scope.cast(GenZir).?.parent, | 3070 | .gen_zir => scope = scope.cast(GenZir).?.parent, |
| 3153 | .local_val => { | 3071 | .local_val => { |
| 3154 | const s = scope.cast(Scope.LocalVal).?; | 3072 | const s = scope.cast(Scope.LocalVal).?; |
| 3155 | if (s.used == 0 and s.discarded == 0) { | 3073 | if (s.used == .none and s.discarded == .none) { |
| 3156 | 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)}); |
| 3157 | } else if (s.used != 0 and s.discarded != 0) { | 3075 | } else if (s.used != .none and s.discarded != .none) { |
| 3158 | 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{ |
| 3159 | try gz.astgen.errNoteTok(s.used, "used here", .{}), | 3077 | try gz.astgen.errNoteTok(s.used.unwrap().?, "used here", .{}), |
| 3160 | }); | 3078 | }); |
| 3161 | } | 3079 | } |
| 3162 | scope = s.parent; | 3080 | scope = s.parent; |
| 3163 | }, | 3081 | }, |
| 3164 | .local_ptr => { | 3082 | .local_ptr => { |
| 3165 | const s = scope.cast(Scope.LocalPtr).?; | 3083 | const s = scope.cast(Scope.LocalPtr).?; |
| 3166 | if (s.used == 0 and s.discarded == 0) { | 3084 | if (s.used == .none and s.discarded == .none) { |
| 3167 | 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)}); |
| 3168 | } else { | 3086 | } else { |
| 3169 | if (s.used != 0 and s.discarded != 0) { | 3087 | if (s.used != .none and s.discarded != .none) { |
| 3170 | 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{ |
| 3171 | try astgen.errNoteTok(s.used, "used here", .{}), | 3089 | try astgen.errNoteTok(s.used.unwrap().?, "used here", .{}), |
| 3172 | }); | 3090 | }); |
| 3173 | } | 3091 | } |
| 3174 | if (s.id_cat == .@"local variable" and !s.used_as_lvalue) { | 3092 | if (s.id_cat == .@"local variable" and !s.used_as_lvalue) { |
| ... | @@ -3195,19 +3113,15 @@ fn deferStmt( | ... | @@ -3195,19 +3113,15 @@ fn deferStmt( |
| 3195 | scope_tag: Scope.Tag, | 3113 | scope_tag: Scope.Tag, |
| 3196 | ) InnerError!*Scope { | 3114 | ) InnerError!*Scope { |
| 3197 | var defer_gen = gz.makeSubBlock(scope); | 3115 | var defer_gen = gz.makeSubBlock(scope); |
| 3198 | defer_gen.cur_defer_node = node; | 3116 | defer_gen.cur_defer_node = node.toOptional(); |
| 3199 | defer_gen.any_defer_node = node; | 3117 | defer_gen.any_defer_node = node.toOptional(); |
| 3200 | defer defer_gen.unstack(); | 3118 | defer defer_gen.unstack(); |
| 3201 | 3119 | ||
| 3202 | const tree = gz.astgen.tree; | 3120 | const tree = gz.astgen.tree; |
| 3203 | const node_datas = tree.nodes.items(.data); | ||
| 3204 | const expr_node = node_datas[node].rhs; | ||
| 3205 | |||
| 3206 | const payload_token = node_datas[node].lhs; | ||
| 3207 | var local_val_scope: Scope.LocalVal = undefined; | 3121 | var local_val_scope: Scope.LocalVal = undefined; |
| 3208 | var opt_remapped_err_code: Zir.Inst.OptionalIndex = .none; | 3122 | var opt_remapped_err_code: Zir.Inst.OptionalIndex = .none; |
| 3209 | 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: { |
| 3210 | 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; |
| 3211 | const ident_name = try gz.astgen.identAsString(payload_token); | 3125 | const ident_name = try gz.astgen.identAsString(payload_token); |
| 3212 | if (std.mem.eql(u8, tree.tokenSlice(payload_token), "_")) { | 3126 | if (std.mem.eql(u8, tree.tokenSlice(payload_token), "_")) { |
| 3213 | 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", .{}); |
| ... | @@ -3235,6 +3149,11 @@ fn deferStmt( | ... | @@ -3235,6 +3149,11 @@ fn deferStmt( |
| 3235 | 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); |
| 3236 | break :blk &local_val_scope.base; | 3150 | break :blk &local_val_scope.base; |
| 3237 | }; | 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 | }; | ||
| 3238 | _ = try unusedResultExpr(&defer_gen, sub_scope, expr_node); | 3157 | _ = try unusedResultExpr(&defer_gen, sub_scope, expr_node); |
| 3239 | try checkUsed(gz, scope, sub_scope); | 3158 | try checkUsed(gz, scope, sub_scope); |
| 3240 | _ = try defer_gen.addBreak(.break_inline, @enumFromInt(0), .void_value); | 3159 | _ = try defer_gen.addBreak(.break_inline, @enumFromInt(0), .void_value); |
| ... | @@ -3269,8 +3188,6 @@ fn varDecl( | ... | @@ -3269,8 +3188,6 @@ fn varDecl( |
| 3269 | try emitDbgNode(gz, node); | 3188 | try emitDbgNode(gz, node); |
| 3270 | const astgen = gz.astgen; | 3189 | const astgen = gz.astgen; |
| 3271 | const tree = astgen.tree; | 3190 | const tree = astgen.tree; |
| 3272 | const token_tags = tree.tokens.items(.tag); | ||
| 3273 | const main_tokens = tree.nodes.items(.main_token); | ||
| 3274 | 3191 | ||
| 3275 | const name_token = var_decl.ast.mut_token + 1; | 3192 | const name_token = var_decl.ast.mut_token + 1; |
| 3276 | const ident_name_raw = tree.tokenSlice(name_token); | 3193 | const ident_name_raw = tree.tokenSlice(name_token); |
| ... | @@ -3284,27 +3201,27 @@ fn varDecl( | ... | @@ -3284,27 +3201,27 @@ fn varDecl( |
| 3284 | ident_name, | 3201 | ident_name, |
| 3285 | name_token, | 3202 | name_token, |
| 3286 | ident_name_raw, | 3203 | ident_name_raw, |
| 3287 | 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", |
| 3288 | ); | 3205 | ); |
| 3289 | 3206 | ||
| 3290 | if (var_decl.ast.init_node == 0) { | 3207 | const init_node = var_decl.ast.init_node.unwrap() orelse { |
| 3291 | return astgen.failNode(node, "variables must be initialized", .{}); | 3208 | return astgen.failNode(node, "variables must be initialized", .{}); |
| 3292 | } | 3209 | }; |
| 3293 | 3210 | ||
| 3294 | if (var_decl.ast.addrspace_node != 0) { | 3211 | if (var_decl.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 3295 | 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}); |
| 3296 | } | 3213 | } |
| 3297 | 3214 | ||
| 3298 | if (var_decl.ast.section_node != 0) { | 3215 | if (var_decl.ast.section_node.unwrap()) |section_node| { |
| 3299 | 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}); |
| 3300 | } | 3217 | } |
| 3301 | 3218 | ||
| 3302 | 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| |
| 3303 | try expr(gz, scope, coerced_align_ri, var_decl.ast.align_node) | 3220 | try expr(gz, scope, coerced_align_ri, align_node) |
| 3304 | else | 3221 | else |
| 3305 | .none; | 3222 | .none; |
| 3306 | 3223 | ||
| 3307 | switch (token_tags[var_decl.ast.mut_token]) { | 3224 | switch (tree.tokenTag(var_decl.ast.mut_token)) { |
| 3308 | .keyword_const => { | 3225 | .keyword_const => { |
| 3309 | if (var_decl.comptime_token) |comptime_token| { | 3226 | if (var_decl.comptime_token) |comptime_token| { |
| 3310 | 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'", .{}); |
| ... | @@ -3316,25 +3233,24 @@ fn varDecl( | ... | @@ -3316,25 +3233,24 @@ fn varDecl( |
| 3316 | // 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 |
| 3317 | // 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 |
| 3318 | // the variable, no memory location needed. | 3235 | // the variable, no memory location needed. |
| 3319 | const type_node = var_decl.ast.type_node; | ||
| 3320 | if (align_inst == .none and | 3236 | if (align_inst == .none and |
| 3321 | !astgen.nodes_need_rl.contains(node)) | 3237 | !astgen.nodes_need_rl.contains(node)) |
| 3322 | { | 3238 | { |
| 3323 | const result_info: ResultInfo = if (type_node != 0) .{ | 3239 | const result_info: ResultInfo = if (var_decl.ast.type_node.unwrap()) |type_node| .{ |
| 3324 | .rl = .{ .ty = try typeExpr(gz, scope, type_node) }, | 3240 | .rl = .{ .ty = try typeExpr(gz, scope, type_node) }, |
| 3325 | .ctx = .const_init, | 3241 | .ctx = .const_init, |
| 3326 | } else .{ .rl = .none, .ctx = .const_init }; | 3242 | } else .{ .rl = .none, .ctx = .const_init }; |
| 3327 | const prev_anon_name_strategy = gz.anon_name_strategy; | 3243 | const prev_anon_name_strategy = gz.anon_name_strategy; |
| 3328 | gz.anon_name_strategy = .dbg_var; | 3244 | gz.anon_name_strategy = .dbg_var; |
| 3329 | 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); |
| 3330 | gz.anon_name_strategy = prev_anon_name_strategy; | 3246 | gz.anon_name_strategy = prev_anon_name_strategy; |
| 3331 | 3247 | ||
| 3332 | _ = try gz.addUnNode(.validate_const, init_inst, var_decl.ast.init_node); | 3248 | _ = try gz.addUnNode(.validate_const, init_inst, init_node); |
| 3333 | try gz.addDbgVar(.dbg_var_val, ident_name, init_inst); | 3249 | try gz.addDbgVar(.dbg_var_val, ident_name, init_inst); |
| 3334 | 3250 | ||
| 3335 | // 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 |
| 3336 | // 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. |
| 3337 | if (nodeMayAppendToErrorTrace(tree, var_decl.ast.init_node)) | 3253 | if (nodeMayAppendToErrorTrace(tree, init_node)) |
| 3338 | _ = try gz.addSaveErrRetIndex(.{ .if_of_error_type = init_inst }); | 3254 | _ = try gz.addSaveErrRetIndex(.{ .if_of_error_type = init_inst }); |
| 3339 | 3255 | ||
| 3340 | const sub_scope = try block_arena.create(Scope.LocalVal); | 3256 | const sub_scope = try block_arena.create(Scope.LocalVal); |
| ... | @@ -3350,9 +3266,9 @@ fn varDecl( | ... | @@ -3350,9 +3266,9 @@ fn varDecl( |
| 3350 | } | 3266 | } |
| 3351 | 3267 | ||
| 3352 | const is_comptime = gz.is_comptime or | 3268 | const is_comptime = gz.is_comptime or |
| 3353 | tree.nodes.items(.tag)[var_decl.ast.init_node] == .@"comptime"; | 3269 | tree.nodeTag(init_node) == .@"comptime"; |
| 3354 | 3270 | ||
| 3355 | 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: { |
| 3356 | const type_inst = try typeExpr(gz, scope, type_node); | 3272 | const type_inst = try typeExpr(gz, scope, type_node); |
| 3357 | if (align_inst == .none) { | 3273 | if (align_inst == .none) { |
| 3358 | 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) } }; |
| ... | @@ -3393,11 +3309,11 @@ fn varDecl( | ... | @@ -3393,11 +3309,11 @@ fn varDecl( |
| 3393 | const prev_anon_name_strategy = gz.anon_name_strategy; | 3309 | const prev_anon_name_strategy = gz.anon_name_strategy; |
| 3394 | gz.anon_name_strategy = .dbg_var; | 3310 | gz.anon_name_strategy = .dbg_var; |
| 3395 | defer gz.anon_name_strategy = prev_anon_name_strategy; | 3311 | defer gz.anon_name_strategy = prev_anon_name_strategy; |
| 3396 | 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); |
| 3397 | 3313 | ||
| 3398 | // 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 |
| 3399 | // 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. |
| 3400 | if (nodeMayAppendToErrorTrace(tree, var_decl.ast.init_node)) | 3316 | if (nodeMayAppendToErrorTrace(tree, init_node)) |
| 3401 | _ = try gz.addSaveErrRetIndex(.{ .if_of_error_type = init_inst }); | 3317 | _ = try gz.addSaveErrRetIndex(.{ .if_of_error_type = init_inst }); |
| 3402 | 3318 | ||
| 3403 | const const_ptr = if (resolve_inferred) | 3319 | const const_ptr = if (resolve_inferred) |
| ... | @@ -3423,8 +3339,8 @@ fn varDecl( | ... | @@ -3423,8 +3339,8 @@ fn varDecl( |
| 3423 | if (var_decl.comptime_token != null and gz.is_comptime) | 3339 | if (var_decl.comptime_token != null and gz.is_comptime) |
| 3424 | 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", .{}); |
| 3425 | 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; |
| 3426 | 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: { |
| 3427 | const type_inst = try typeExpr(gz, scope, var_decl.ast.type_node); | 3343 | const type_inst = try typeExpr(gz, scope, type_node); |
| 3428 | const alloc = alloc: { | 3344 | const alloc = alloc: { |
| 3429 | if (align_inst == .none) { | 3345 | if (align_inst == .none) { |
| 3430 | const tag: Zir.Inst.Tag = if (is_comptime) | 3346 | const tag: Zir.Inst.Tag = if (is_comptime) |
| ... | @@ -3469,7 +3385,7 @@ fn varDecl( | ... | @@ -3469,7 +3385,7 @@ fn varDecl( |
| 3469 | gz, | 3385 | gz, |
| 3470 | scope, | 3386 | scope, |
| 3471 | result_info, | 3387 | result_info, |
| 3472 | var_decl.ast.init_node, | 3388 | init_node, |
| 3473 | node, | 3389 | node, |
| 3474 | if (var_decl.comptime_token != null) .comptime_keyword else null, | 3390 | if (var_decl.comptime_token != null) .comptime_keyword else null, |
| 3475 | ); | 3391 | ); |
| ... | @@ -3512,15 +3428,11 @@ fn assign(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerError!voi | ... | @@ -3512,15 +3428,11 @@ fn assign(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerError!voi |
| 3512 | try emitDbgNode(gz, infix_node); | 3428 | try emitDbgNode(gz, infix_node); |
| 3513 | const astgen = gz.astgen; | 3429 | const astgen = gz.astgen; |
| 3514 | const tree = astgen.tree; | 3430 | const tree = astgen.tree; |
| 3515 | const node_datas = tree.nodes.items(.data); | ||
| 3516 | const main_tokens = tree.nodes.items(.main_token); | ||
| 3517 | const node_tags = tree.nodes.items(.tag); | ||
| 3518 | 3431 | ||
| 3519 | const lhs = node_datas[infix_node].lhs; | 3432 | const lhs, const rhs = tree.nodeData(infix_node).node_and_node; |
| 3520 | const rhs = node_datas[infix_node].rhs; | 3433 | if (tree.nodeTag(lhs) == .identifier) { |
| 3521 | if (node_tags[lhs] == .identifier) { | ||
| 3522 | // This intentionally does not support `@"_"` syntax. | 3434 | // This intentionally does not support `@"_"` syntax. |
| 3523 | const ident_name = tree.tokenSlice(main_tokens[lhs]); | 3435 | const ident_name = tree.tokenSlice(tree.nodeMainToken(lhs)); |
| 3524 | if (mem.eql(u8, ident_name, "_")) { | 3436 | if (mem.eql(u8, ident_name, "_")) { |
| 3525 | _ = try expr(gz, scope, .{ .rl = .discard, .ctx = .assignment }, rhs); | 3437 | _ = try expr(gz, scope, .{ .rl = .discard, .ctx = .assignment }, rhs); |
| 3526 | return; | 3438 | return; |
| ... | @@ -3538,8 +3450,6 @@ fn assignDestructure(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerErro | ... | @@ -3538,8 +3450,6 @@ fn assignDestructure(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerErro |
| 3538 | try emitDbgNode(gz, node); | 3450 | try emitDbgNode(gz, node); |
| 3539 | const astgen = gz.astgen; | 3451 | const astgen = gz.astgen; |
| 3540 | const tree = astgen.tree; | 3452 | const tree = astgen.tree; |
| 3541 | const main_tokens = tree.nodes.items(.main_token); | ||
| 3542 | const node_tags = tree.nodes.items(.tag); | ||
| 3543 | 3453 | ||
| 3544 | const full = tree.assignDestructure(node); | 3454 | const full = tree.assignDestructure(node); |
| 3545 | if (full.comptime_token != null and gz.is_comptime) { | 3455 | if (full.comptime_token != null and gz.is_comptime) { |
| ... | @@ -3557,9 +3467,9 @@ fn assignDestructure(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerErro | ... | @@ -3557,9 +3467,9 @@ fn assignDestructure(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerErro |
| 3557 | 3467 | ||
| 3558 | 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); |
| 3559 | for (rl_components, full.ast.variables) |*variable_rl, variable_node| { | 3469 | for (rl_components, full.ast.variables) |*variable_rl, variable_node| { |
| 3560 | if (node_tags[variable_node] == .identifier) { | 3470 | if (tree.nodeTag(variable_node) == .identifier) { |
| 3561 | // This intentionally does not support `@"_"` syntax. | 3471 | // This intentionally does not support `@"_"` syntax. |
| 3562 | const ident_name = tree.tokenSlice(main_tokens[variable_node]); | 3472 | const ident_name = tree.tokenSlice(tree.nodeMainToken(variable_node)); |
| 3563 | if (mem.eql(u8, ident_name, "_")) { | 3473 | if (mem.eql(u8, ident_name, "_")) { |
| 3564 | variable_rl.* = .discard; | 3474 | variable_rl.* = .discard; |
| 3565 | continue; | 3475 | continue; |
| ... | @@ -3596,9 +3506,6 @@ fn assignDestructureMaybeDecls( | ... | @@ -3596,9 +3506,6 @@ fn assignDestructureMaybeDecls( |
| 3596 | try emitDbgNode(gz, node); | 3506 | try emitDbgNode(gz, node); |
| 3597 | const astgen = gz.astgen; | 3507 | const astgen = gz.astgen; |
| 3598 | const tree = astgen.tree; | 3508 | const tree = astgen.tree; |
| 3599 | const token_tags = tree.tokens.items(.tag); | ||
| 3600 | const main_tokens = tree.nodes.items(.main_token); | ||
| 3601 | const node_tags = tree.nodes.items(.tag); | ||
| 3602 | 3509 | ||
| 3603 | const full = tree.assignDestructure(node); | 3510 | const full = tree.assignDestructure(node); |
| 3604 | if (full.comptime_token != null and gz.is_comptime) { | 3511 | if (full.comptime_token != null and gz.is_comptime) { |
| ... | @@ -3606,7 +3513,7 @@ fn assignDestructureMaybeDecls( | ... | @@ -3606,7 +3513,7 @@ fn assignDestructureMaybeDecls( |
| 3606 | } | 3513 | } |
| 3607 | 3514 | ||
| 3608 | const is_comptime = full.comptime_token != null or gz.is_comptime; | 3515 | const is_comptime = full.comptime_token != null or gz.is_comptime; |
| 3609 | const value_is_comptime = node_tags[full.ast.value_expr] == .@"comptime"; | 3516 | const value_is_comptime = tree.nodeTag(full.ast.value_expr) == .@"comptime"; |
| 3610 | 3517 | ||
| 3611 | // 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. |
| 3612 | // 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 |
| ... | @@ -3619,10 +3526,10 @@ fn assignDestructureMaybeDecls( | ... | @@ -3619,10 +3526,10 @@ fn assignDestructureMaybeDecls( |
| 3619 | var any_non_const_variables = false; | 3526 | var any_non_const_variables = false; |
| 3620 | var any_lvalue_expr = false; | 3527 | var any_lvalue_expr = false; |
| 3621 | for (rl_components, full.ast.variables) |*variable_rl, variable_node| { | 3528 | for (rl_components, full.ast.variables) |*variable_rl, variable_node| { |
| 3622 | switch (node_tags[variable_node]) { | 3529 | switch (tree.nodeTag(variable_node)) { |
| 3623 | .identifier => { | 3530 | .identifier => { |
| 3624 | // This intentionally does not support `@"_"` syntax. | 3531 | // This intentionally does not support `@"_"` syntax. |
| 3625 | const ident_name = tree.tokenSlice(main_tokens[variable_node]); | 3532 | const ident_name = tree.tokenSlice(tree.nodeMainToken(variable_node)); |
| 3626 | if (mem.eql(u8, ident_name, "_")) { | 3533 | if (mem.eql(u8, ident_name, "_")) { |
| 3627 | any_non_const_variables = true; | 3534 | any_non_const_variables = true; |
| 3628 | variable_rl.* = .discard; | 3535 | variable_rl.* = .discard; |
| ... | @@ -3640,14 +3547,14 @@ fn assignDestructureMaybeDecls( | ... | @@ -3640,14 +3547,14 @@ fn assignDestructureMaybeDecls( |
| 3640 | 3547 | ||
| 3641 | // 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. |
| 3642 | 3549 | ||
| 3643 | if (full_var_decl.ast.addrspace_node != 0) { | 3550 | if (full_var_decl.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 3644 | 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}); |
| 3645 | } | 3552 | } |
| 3646 | if (full_var_decl.ast.section_node != 0) { | 3553 | if (full_var_decl.ast.section_node.unwrap()) |section_node| { |
| 3647 | 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}); |
| 3648 | } | 3555 | } |
| 3649 | 3556 | ||
| 3650 | 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)) { |
| 3651 | .keyword_var => false, | 3558 | .keyword_var => false, |
| 3652 | .keyword_const => true, | 3559 | .keyword_const => true, |
| 3653 | else => unreachable, | 3560 | else => unreachable, |
| ... | @@ -3657,14 +3564,14 @@ fn assignDestructureMaybeDecls( | ... | @@ -3657,14 +3564,14 @@ fn assignDestructureMaybeDecls( |
| 3657 | // 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. |
| 3658 | 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); |
| 3659 | 3566 | ||
| 3660 | 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| |
| 3661 | try expr(gz, scope, coerced_align_ri, full_var_decl.ast.align_node) | 3568 | try expr(gz, scope, coerced_align_ri, align_node) |
| 3662 | else | 3569 | else |
| 3663 | .none; | 3570 | .none; |
| 3664 | 3571 | ||
| 3665 | if (full_var_decl.ast.type_node != 0) { | 3572 | if (full_var_decl.ast.type_node.unwrap()) |type_node| { |
| 3666 | // Typed alloc | 3573 | // Typed alloc |
| 3667 | const type_inst = try typeExpr(gz, scope, full_var_decl.ast.type_node); | 3574 | const type_inst = try typeExpr(gz, scope, type_node); |
| 3668 | const ptr = if (align_inst == .none) ptr: { | 3575 | const ptr = if (align_inst == .none) ptr: { |
| 3669 | const tag: Zir.Inst.Tag = if (is_const) | 3576 | const tag: Zir.Inst.Tag = if (is_const) |
| 3670 | .alloc | 3577 | .alloc |
| ... | @@ -3733,7 +3640,7 @@ fn assignDestructureMaybeDecls( | ... | @@ -3733,7 +3640,7 @@ fn assignDestructureMaybeDecls( |
| 3733 | // evaluate the lvalues from within the possible block_comptime. | 3640 | // evaluate the lvalues from within the possible block_comptime. |
| 3734 | for (rl_components, full.ast.variables) |*variable_rl, variable_node| { | 3641 | for (rl_components, full.ast.variables) |*variable_rl, variable_node| { |
| 3735 | if (variable_rl.* != .typed_ptr) continue; | 3642 | if (variable_rl.* != .typed_ptr) continue; |
| 3736 | switch (node_tags[variable_node]) { | 3643 | switch (tree.nodeTag(variable_node)) { |
| 3737 | .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, |
| 3738 | else => {}, | 3645 | else => {}, |
| 3739 | } | 3646 | } |
| ... | @@ -3762,7 +3669,7 @@ fn assignDestructureMaybeDecls( | ... | @@ -3762,7 +3669,7 @@ fn assignDestructureMaybeDecls( |
| 3762 | // If there were any `const` decls, make the pointer constant. | 3669 | // If there were any `const` decls, make the pointer constant. |
| 3763 | var cur_scope = scope; | 3670 | var cur_scope = scope; |
| 3764 | for (rl_components, full.ast.variables) |variable_rl, variable_node| { | 3671 | for (rl_components, full.ast.variables) |variable_rl, variable_node| { |
| 3765 | switch (node_tags[variable_node]) { | 3672 | switch (tree.nodeTag(variable_node)) { |
| 3766 | .local_var_decl, .simple_var_decl, .aligned_var_decl => {}, | 3673 | .local_var_decl, .simple_var_decl, .aligned_var_decl => {}, |
| 3767 | else => continue, // We were mutating an existing lvalue - nothing to do | 3674 | else => continue, // We were mutating an existing lvalue - nothing to do |
| 3768 | } | 3675 | } |
| ... | @@ -3772,7 +3679,7 @@ fn assignDestructureMaybeDecls( | ... | @@ -3772,7 +3679,7 @@ fn assignDestructureMaybeDecls( |
| 3772 | .typed_ptr => |typed_ptr| .{ typed_ptr.inst, false }, | 3679 | .typed_ptr => |typed_ptr| .{ typed_ptr.inst, false }, |
| 3773 | .inferred_ptr => |ptr_inst| .{ ptr_inst, true }, | 3680 | .inferred_ptr => |ptr_inst| .{ ptr_inst, true }, |
| 3774 | }; | 3681 | }; |
| 3775 | 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)) { |
| 3776 | .keyword_var => false, | 3683 | .keyword_var => false, |
| 3777 | .keyword_const => true, | 3684 | .keyword_const => true, |
| 3778 | else => unreachable, | 3685 | else => unreachable, |
| ... | @@ -3823,9 +3730,9 @@ fn assignOp( | ... | @@ -3823,9 +3730,9 @@ fn assignOp( |
| 3823 | try emitDbgNode(gz, infix_node); | 3730 | try emitDbgNode(gz, infix_node); |
| 3824 | const astgen = gz.astgen; | 3731 | const astgen = gz.astgen; |
| 3825 | const tree = astgen.tree; | 3732 | const tree = astgen.tree; |
| 3826 | const node_datas = tree.nodes.items(.data); | ||
| 3827 | 3733 | ||
| 3828 | 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); | ||
| 3829 | 3736 | ||
| 3830 | const cursor = switch (op_inst_tag) { | 3737 | const cursor = switch (op_inst_tag) { |
| 3831 | .add, .sub, .mul, .div, .mod_rem => maybeAdvanceSourceCursorToMainToken(gz, infix_node), | 3738 | .add, .sub, .mul, .div, .mod_rem => maybeAdvanceSourceCursorToMainToken(gz, infix_node), |
| ... | @@ -3851,7 +3758,7 @@ fn assignOp( | ... | @@ -3851,7 +3758,7 @@ fn assignOp( |
| 3851 | 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 |
| 3852 | }; | 3759 | }; |
| 3853 | // 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. |
| 3854 | 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); |
| 3855 | 3762 | ||
| 3856 | switch (op_inst_tag) { | 3763 | switch (op_inst_tag) { |
| 3857 | .add, .sub, .mul, .div, .mod_rem => { | 3764 | .add, .sub, .mul, .div, .mod_rem => { |
| ... | @@ -3878,12 +3785,12 @@ fn assignShift( | ... | @@ -3878,12 +3785,12 @@ fn assignShift( |
| 3878 | try emitDbgNode(gz, infix_node); | 3785 | try emitDbgNode(gz, infix_node); |
| 3879 | const astgen = gz.astgen; | 3786 | const astgen = gz.astgen; |
| 3880 | const tree = astgen.tree; | 3787 | const tree = astgen.tree; |
| 3881 | const node_datas = tree.nodes.items(.data); | ||
| 3882 | 3788 | ||
| 3883 | 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); | ||
| 3884 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); | 3791 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); |
| 3885 | 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); |
| 3886 | 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); |
| 3887 | 3794 | ||
| 3888 | 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{ |
| 3889 | .lhs = lhs, | 3796 | .lhs = lhs, |
| ... | @@ -3899,12 +3806,12 @@ fn assignShiftSat(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerE | ... | @@ -3899,12 +3806,12 @@ fn assignShiftSat(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerE |
| 3899 | try emitDbgNode(gz, infix_node); | 3806 | try emitDbgNode(gz, infix_node); |
| 3900 | const astgen = gz.astgen; | 3807 | const astgen = gz.astgen; |
| 3901 | const tree = astgen.tree; | 3808 | const tree = astgen.tree; |
| 3902 | const node_datas = tree.nodes.items(.data); | ||
| 3903 | 3809 | ||
| 3904 | 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); | ||
| 3905 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); | 3812 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); |
| 3906 | // 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. |
| 3907 | const rhs = try expr(gz, scope, .{ .rl = .none }, node_datas[infix_node].rhs); | 3814 | const rhs = try expr(gz, scope, .{ .rl = .none }, rhs_node); |
| 3908 | 3815 | ||
| 3909 | 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{ |
| 3910 | .lhs = lhs, | 3817 | .lhs = lhs, |
| ... | @@ -3939,7 +3846,7 @@ fn ptrType( | ... | @@ -3939,7 +3846,7 @@ fn ptrType( |
| 3939 | var bit_end_ref: Zir.Inst.Ref = .none; | 3846 | var bit_end_ref: Zir.Inst.Ref = .none; |
| 3940 | var trailing_count: u32 = 0; | 3847 | var trailing_count: u32 = 0; |
| 3941 | 3848 | ||
| 3942 | if (ptr_info.ast.sentinel != 0) { | 3849 | if (ptr_info.ast.sentinel.unwrap()) |sentinel| { |
| 3943 | // 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 |
| 3944 | // 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. |
| 3945 | gz.astgen.source_offset = source_offset; | 3852 | gz.astgen.source_offset = source_offset; |
| ... | @@ -3950,7 +3857,7 @@ fn ptrType( | ... | @@ -3950,7 +3857,7 @@ fn ptrType( |
| 3950 | gz, | 3857 | gz, |
| 3951 | scope, | 3858 | scope, |
| 3952 | .{ .rl = .{ .ty = elem_type } }, | 3859 | .{ .rl = .{ .ty = elem_type } }, |
| 3953 | ptr_info.ast.sentinel, | 3860 | sentinel, |
| 3954 | switch (ptr_info.size) { | 3861 | switch (ptr_info.size) { |
| 3955 | .slice => .slice_sentinel, | 3862 | .slice => .slice_sentinel, |
| 3956 | else => .pointer_sentinel, | 3863 | else => .pointer_sentinel, |
| ... | @@ -3958,27 +3865,27 @@ fn ptrType( | ... | @@ -3958,27 +3865,27 @@ fn ptrType( |
| 3958 | ); | 3865 | ); |
| 3959 | trailing_count += 1; | 3866 | trailing_count += 1; |
| 3960 | } | 3867 | } |
| 3961 | if (ptr_info.ast.addrspace_node != 0) { | 3868 | if (ptr_info.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 3962 | gz.astgen.source_offset = source_offset; | 3869 | gz.astgen.source_offset = source_offset; |
| 3963 | gz.astgen.source_line = source_line; | 3870 | gz.astgen.source_line = source_line; |
| 3964 | gz.astgen.source_column = source_column; | 3871 | gz.astgen.source_column = source_column; |
| 3965 | 3872 | ||
| 3966 | const addrspace_ty = try gz.addBuiltinValue(ptr_info.ast.addrspace_node, .address_space); | 3873 | const addrspace_ty = try gz.addBuiltinValue(addrspace_node, .address_space); |
| 3967 | 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"); |
| 3968 | trailing_count += 1; | 3875 | trailing_count += 1; |
| 3969 | } | 3876 | } |
| 3970 | if (ptr_info.ast.align_node != 0) { | 3877 | if (ptr_info.ast.align_node.unwrap()) |align_node| { |
| 3971 | gz.astgen.source_offset = source_offset; | 3878 | gz.astgen.source_offset = source_offset; |
| 3972 | gz.astgen.source_line = source_line; | 3879 | gz.astgen.source_line = source_line; |
| 3973 | gz.astgen.source_column = source_column; | 3880 | gz.astgen.source_column = source_column; |
| 3974 | 3881 | ||
| 3975 | 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"); |
| 3976 | trailing_count += 1; | 3883 | trailing_count += 1; |
| 3977 | } | 3884 | } |
| 3978 | if (ptr_info.ast.bit_range_start != 0) { | 3885 | if (ptr_info.ast.bit_range_start.unwrap()) |bit_range_start| { |
| 3979 | assert(ptr_info.ast.bit_range_end != 0); | 3886 | const bit_range_end = ptr_info.ast.bit_range_end.unwrap().?; |
| 3980 | 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); |
| 3981 | 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); |
| 3982 | trailing_count += 2; | 3889 | trailing_count += 2; |
| 3983 | } | 3890 | } |
| 3984 | 3891 | ||
| ... | @@ -4031,18 +3938,15 @@ fn ptrType( | ... | @@ -4031,18 +3938,15 @@ fn ptrType( |
| 4031 | 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 { |
| 4032 | const astgen = gz.astgen; | 3939 | const astgen = gz.astgen; |
| 4033 | const tree = astgen.tree; | 3940 | const tree = astgen.tree; |
| 4034 | const node_datas = tree.nodes.items(.data); | ||
| 4035 | const node_tags = tree.nodes.items(.tag); | ||
| 4036 | const main_tokens = tree.nodes.items(.main_token); | ||
| 4037 | 3941 | ||
| 4038 | const len_node = node_datas[node].lhs; | 3942 | const len_node, const elem_type_node = tree.nodeData(node).node_and_node; |
| 4039 | if (node_tags[len_node] == .identifier and | 3943 | if (tree.nodeTag(len_node) == .identifier and |
| 4040 | mem.eql(u8, tree.tokenSlice(main_tokens[len_node]), "_")) | 3944 | mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(len_node)), "_")) |
| 4041 | { | 3945 | { |
| 4042 | return astgen.failNode(len_node, "unable to infer array size", .{}); | 3946 | return astgen.failNode(len_node, "unable to infer array size", .{}); |
| 4043 | } | 3947 | } |
| 4044 | 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); |
| 4045 | const elem_type = try typeExpr(gz, scope, node_datas[node].rhs); | 3949 | const elem_type = try typeExpr(gz, scope, elem_type_node); |
| 4046 | 3950 | ||
| 4047 | const result = try gz.addPlNode(.array_type, node, Zir.Inst.Bin{ | 3951 | const result = try gz.addPlNode(.array_type, node, Zir.Inst.Bin{ |
| 4048 | .lhs = len, | 3952 | .lhs = len, |
| ... | @@ -4054,14 +3958,12 @@ fn arrayType(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) ! | ... | @@ -4054,14 +3958,12 @@ fn arrayType(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) ! |
| 4054 | 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 { |
| 4055 | const astgen = gz.astgen; | 3959 | const astgen = gz.astgen; |
| 4056 | const tree = astgen.tree; | 3960 | const tree = astgen.tree; |
| 4057 | const node_datas = tree.nodes.items(.data); | 3961 | |
| 4058 | const node_tags = tree.nodes.items(.tag); | 3962 | const len_node, const extra_index = tree.nodeData(node).node_and_extra; |
| 4059 | const main_tokens = tree.nodes.items(.main_token); | 3963 | const extra = tree.extraData(extra_index, Ast.Node.ArrayTypeSentinel); |
| 4060 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.ArrayTypeSentinel); | 3964 | |
| 4061 | 3965 | if (tree.nodeTag(len_node) == .identifier and | |
| 4062 | const len_node = node_datas[node].lhs; | 3966 | mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(len_node)), "_")) |
| 4063 | if (node_tags[len_node] == .identifier and | ||
| 4064 | mem.eql(u8, tree.tokenSlice(main_tokens[len_node]), "_")) | ||
| 4065 | { | 3967 | { |
| 4066 | return astgen.failNode(len_node, "unable to infer array size", .{}); | 3968 | return astgen.failNode(len_node, "unable to infer array size", .{}); |
| 4067 | } | 3969 | } |
| ... | @@ -4161,11 +4063,10 @@ fn fnDecl( | ... | @@ -4161,11 +4063,10 @@ fn fnDecl( |
| 4161 | scope: *Scope, | 4063 | scope: *Scope, |
| 4162 | wip_members: *WipMembers, | 4064 | wip_members: *WipMembers, |
| 4163 | decl_node: Ast.Node.Index, | 4065 | decl_node: Ast.Node.Index, |
| 4164 | body_node: Ast.Node.Index, | 4066 | body_node: Ast.Node.OptionalIndex, |
| 4165 | fn_proto: Ast.full.FnProto, | 4067 | fn_proto: Ast.full.FnProto, |
| 4166 | ) InnerError!void { | 4068 | ) InnerError!void { |
| 4167 | const tree = astgen.tree; | 4069 | const tree = astgen.tree; |
| 4168 | const token_tags = tree.tokens.items(.tag); | ||
| 4169 | 4070 | ||
| 4170 | const old_hasher = astgen.src_hasher; | 4071 | const old_hasher = astgen.src_hasher; |
| 4171 | defer astgen.src_hasher = old_hasher; | 4072 | defer astgen.src_hasher = old_hasher; |
| ... | @@ -4194,15 +4095,15 @@ fn fnDecl( | ... | @@ -4194,15 +4095,15 @@ fn fnDecl( |
| 4194 | const is_pub = fn_proto.visib_token != null; | 4095 | const is_pub = fn_proto.visib_token != null; |
| 4195 | const is_export = blk: { | 4096 | const is_export = blk: { |
| 4196 | 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; |
| 4197 | break :blk token_tags[maybe_export_token] == .keyword_export; | 4098 | break :blk tree.tokenTag(maybe_export_token) == .keyword_export; |
| 4198 | }; | 4099 | }; |
| 4199 | const is_extern = blk: { | 4100 | const is_extern = blk: { |
| 4200 | 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; |
| 4201 | break :blk token_tags[maybe_extern_token] == .keyword_extern; | 4102 | break :blk tree.tokenTag(maybe_extern_token) == .keyword_extern; |
| 4202 | }; | 4103 | }; |
| 4203 | const has_inline_keyword = blk: { | 4104 | const has_inline_keyword = blk: { |
| 4204 | 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; |
| 4205 | break :blk token_tags[maybe_inline_token] == .keyword_inline; | 4106 | break :blk tree.tokenTag(maybe_inline_token) == .keyword_inline; |
| 4206 | }; | 4107 | }; |
| 4207 | 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: { |
| 4208 | const lib_name_str = try astgen.strLitAsString(lib_name_token); | 4109 | const lib_name_str = try astgen.strLitAsString(lib_name_token); |
| ... | @@ -4214,16 +4115,18 @@ fn fnDecl( | ... | @@ -4214,16 +4115,18 @@ fn fnDecl( |
| 4214 | } | 4115 | } |
| 4215 | break :blk lib_name_str.index; | 4116 | break :blk lib_name_str.index; |
| 4216 | } else .empty; | 4117 | } else .empty; |
| 4217 | if (fn_proto.ast.callconv_expr != 0 and has_inline_keyword) { | 4118 | if (fn_proto.ast.callconv_expr != .none and has_inline_keyword) { |
| 4218 | return astgen.failNode( | 4119 | return astgen.failNode( |
| 4219 | fn_proto.ast.callconv_expr, | 4120 | fn_proto.ast.callconv_expr.unwrap().?, |
| 4220 | "explicit callconv incompatible with inline keyword", | 4121 | "explicit callconv incompatible with inline keyword", |
| 4221 | .{}, | 4122 | .{}, |
| 4222 | ); | 4123 | ); |
| 4223 | } | 4124 | } |
| 4224 | const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1; | 4125 | |
| 4225 | const is_inferred_error = token_tags[maybe_bang] == .bang; | 4126 | const return_type = fn_proto.ast.return_type.unwrap().?; |
| 4226 | 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) { | ||
| 4227 | if (!is_extern) { | 4130 | if (!is_extern) { |
| 4228 | 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", .{}); |
| 4229 | } | 4132 | } |
| ... | @@ -4256,28 +4159,28 @@ fn fnDecl( | ... | @@ -4256,28 +4159,28 @@ fn fnDecl( |
| 4256 | var align_gz = type_gz.makeSubBlock(scope); | 4159 | var align_gz = type_gz.makeSubBlock(scope); |
| 4257 | defer align_gz.unstack(); | 4160 | defer align_gz.unstack(); |
| 4258 | 4161 | ||
| 4259 | if (fn_proto.ast.align_expr != 0) { | 4162 | if (fn_proto.ast.align_expr.unwrap()) |align_expr| { |
| 4260 | astgen.restoreSourceCursor(saved_cursor); | 4163 | astgen.restoreSourceCursor(saved_cursor); |
| 4261 | 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); |
| 4262 | _ = try align_gz.addBreakWithSrcNode(.break_inline, decl_inst, inst, decl_node); | 4165 | _ = try align_gz.addBreakWithSrcNode(.break_inline, decl_inst, inst, decl_node); |
| 4263 | } | 4166 | } |
| 4264 | 4167 | ||
| 4265 | var linksection_gz = align_gz.makeSubBlock(scope); | 4168 | var linksection_gz = align_gz.makeSubBlock(scope); |
| 4266 | defer linksection_gz.unstack(); | 4169 | defer linksection_gz.unstack(); |
| 4267 | 4170 | ||
| 4268 | if (fn_proto.ast.section_expr != 0) { | 4171 | if (fn_proto.ast.section_expr.unwrap()) |section_expr| { |
| 4269 | astgen.restoreSourceCursor(saved_cursor); | 4172 | astgen.restoreSourceCursor(saved_cursor); |
| 4270 | 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); |
| 4271 | _ = try linksection_gz.addBreakWithSrcNode(.break_inline, decl_inst, inst, decl_node); | 4174 | _ = try linksection_gz.addBreakWithSrcNode(.break_inline, decl_inst, inst, decl_node); |
| 4272 | } | 4175 | } |
| 4273 | 4176 | ||
| 4274 | var addrspace_gz = linksection_gz.makeSubBlock(scope); | 4177 | var addrspace_gz = linksection_gz.makeSubBlock(scope); |
| 4275 | defer addrspace_gz.unstack(); | 4178 | defer addrspace_gz.unstack(); |
| 4276 | 4179 | ||
| 4277 | if (fn_proto.ast.addrspace_expr != 0) { | 4180 | if (fn_proto.ast.addrspace_expr.unwrap()) |addrspace_expr| { |
| 4278 | astgen.restoreSourceCursor(saved_cursor); | 4181 | astgen.restoreSourceCursor(saved_cursor); |
| 4279 | 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); |
| 4280 | 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); |
| 4281 | _ = try addrspace_gz.addBreakWithSrcNode(.break_inline, decl_inst, inst, decl_node); | 4184 | _ = try addrspace_gz.addBreakWithSrcNode(.break_inline, decl_inst, inst, decl_node); |
| 4282 | } | 4185 | } |
| 4283 | 4186 | ||
| ... | @@ -4287,7 +4190,7 @@ fn fnDecl( | ... | @@ -4287,7 +4190,7 @@ fn fnDecl( |
| 4287 | if (!is_extern) { | 4190 | if (!is_extern) { |
| 4288 | // We include a function *value*, not a type. | 4191 | // We include a function *value*, not a type. |
| 4289 | astgen.restoreSourceCursor(saved_cursor); | 4192 | astgen.restoreSourceCursor(saved_cursor); |
| 4290 | 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); |
| 4291 | } | 4194 | } |
| 4292 | 4195 | ||
| 4293 | // *Now* we can incorporate the full source code into the hasher. | 4196 | // *Now* we can incorporate the full source code into the hasher. |
| ... | @@ -4326,18 +4229,19 @@ fn fnDeclInner( | ... | @@ -4326,18 +4229,19 @@ fn fnDeclInner( |
| 4326 | fn_proto: Ast.full.FnProto, | 4229 | fn_proto: Ast.full.FnProto, |
| 4327 | ) InnerError!void { | 4230 | ) InnerError!void { |
| 4328 | const tree = astgen.tree; | 4231 | const tree = astgen.tree; |
| 4329 | const token_tags = tree.tokens.items(.tag); | ||
| 4330 | 4232 | ||
| 4331 | const is_noinline = blk: { | 4233 | const is_noinline = blk: { |
| 4332 | 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; |
| 4333 | break :blk token_tags[maybe_noinline_token] == .keyword_noinline; | 4235 | break :blk tree.tokenTag(maybe_noinline_token) == .keyword_noinline; |
| 4334 | }; | 4236 | }; |
| 4335 | const has_inline_keyword = blk: { | 4237 | const has_inline_keyword = blk: { |
| 4336 | 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; |
| 4337 | break :blk token_tags[maybe_inline_token] == .keyword_inline; | 4239 | break :blk tree.tokenTag(maybe_inline_token) == .keyword_inline; |
| 4338 | }; | 4240 | }; |
| 4339 | const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1; | 4241 | |
| 4340 | 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; | ||
| 4341 | 4245 | ||
| 4342 | // 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. |
| 4343 | 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); |
| ... | @@ -4351,7 +4255,7 @@ fn fnDeclInner( | ... | @@ -4351,7 +4255,7 @@ fn fnDeclInner( |
| 4351 | var param_type_i: usize = 0; | 4255 | var param_type_i: usize = 0; |
| 4352 | var it = fn_proto.iterate(tree); | 4256 | var it = fn_proto.iterate(tree); |
| 4353 | while (it.next()) |param| : (param_type_i += 1) { | 4257 | while (it.next()) |param| : (param_type_i += 1) { |
| 4354 | 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)) { |
| 4355 | .keyword_noalias => is_comptime: { | 4259 | .keyword_noalias => is_comptime: { |
| 4356 | 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 |
| 4357 | 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", .{})); |
| ... | @@ -4362,7 +4266,7 @@ fn fnDeclInner( | ... | @@ -4362,7 +4266,7 @@ fn fnDeclInner( |
| 4362 | } else false; | 4266 | } else false; |
| 4363 | 4267 | ||
| 4364 | const is_anytype = if (param.anytype_ellipsis3) |token| blk: { | 4268 | const is_anytype = if (param.anytype_ellipsis3) |token| blk: { |
| 4365 | switch (token_tags[token]) { | 4269 | switch (tree.tokenTag(token)) { |
| 4366 | .keyword_anytype => break :blk true, | 4270 | .keyword_anytype => break :blk true, |
| 4367 | .ellipsis3 => break :is_var_args true, | 4271 | .ellipsis3 => break :is_var_args true, |
| 4368 | else => unreachable, | 4272 | else => unreachable, |
| ... | @@ -4381,30 +4285,31 @@ fn fnDeclInner( | ... | @@ -4381,30 +4285,31 @@ fn fnDeclInner( |
| 4381 | if (param.anytype_ellipsis3) |tok| { | 4285 | if (param.anytype_ellipsis3) |tok| { |
| 4382 | return astgen.failTok(tok, "missing parameter name", .{}); | 4286 | return astgen.failTok(tok, "missing parameter name", .{}); |
| 4383 | } else { | 4287 | } else { |
| 4288 | const type_expr = param.type_expr.?; | ||
| 4384 | ambiguous: { | 4289 | ambiguous: { |
| 4385 | if (tree.nodes.items(.tag)[param.type_expr] != .identifier) break :ambiguous; | 4290 | if (tree.nodeTag(type_expr) != .identifier) break :ambiguous; |
| 4386 | const main_token = tree.nodes.items(.main_token)[param.type_expr]; | 4291 | const main_token = tree.nodeMainToken(type_expr); |
| 4387 | const identifier_str = tree.tokenSlice(main_token); | 4292 | const identifier_str = tree.tokenSlice(main_token); |
| 4388 | if (isPrimitive(identifier_str)) break :ambiguous; | 4293 | if (isPrimitive(identifier_str)) break :ambiguous; |
| 4389 | return astgen.failNodeNotes( | 4294 | return astgen.failNodeNotes( |
| 4390 | param.type_expr, | 4295 | type_expr, |
| 4391 | "missing parameter name or type", | 4296 | "missing parameter name or type", |
| 4392 | .{}, | 4297 | .{}, |
| 4393 | &[_]u32{ | 4298 | &[_]u32{ |
| 4394 | try astgen.errNoteNode( | 4299 | try astgen.errNoteNode( |
| 4395 | param.type_expr, | 4300 | type_expr, |
| 4396 | "if this is a name, annotate its type '{s}: T'", | 4301 | "if this is a name, annotate its type '{s}: T'", |
| 4397 | .{identifier_str}, | 4302 | .{identifier_str}, |
| 4398 | ), | 4303 | ), |
| 4399 | try astgen.errNoteNode( | 4304 | try astgen.errNoteNode( |
| 4400 | param.type_expr, | 4305 | type_expr, |
| 4401 | "if this is a type, give it a name '<name>: {s}'", | 4306 | "if this is a type, give it a name '<name>: {s}'", |
| 4402 | .{identifier_str}, | 4307 | .{identifier_str}, |
| 4403 | ), | 4308 | ), |
| 4404 | }, | 4309 | }, |
| 4405 | ); | 4310 | ); |
| 4406 | } | 4311 | } |
| 4407 | return astgen.failNode(param.type_expr, "missing parameter name", .{}); | 4312 | return astgen.failNode(type_expr, "missing parameter name", .{}); |
| 4408 | } | 4313 | } |
| 4409 | }; | 4314 | }; |
| 4410 | 4315 | ||
| ... | @@ -4416,8 +4321,7 @@ fn fnDeclInner( | ... | @@ -4416,8 +4321,7 @@ fn fnDeclInner( |
| 4416 | .param_anytype; | 4321 | .param_anytype; |
| 4417 | break :param try decl_gz.addStrTok(tag, param_name, name_token); | 4322 | break :param try decl_gz.addStrTok(tag, param_name, name_token); |
| 4418 | } else param: { | 4323 | } else param: { |
| 4419 | const param_type_node = param.type_expr; | 4324 | const param_type_node = param.type_expr.?; |
| 4420 | assert(param_type_node != 0); | ||
| 4421 | any_param_used = false; // we will check this later | 4325 | any_param_used = false; // we will check this later |
| 4422 | var param_gz = decl_gz.makeSubBlock(scope); | 4326 | var param_gz = decl_gz.makeSubBlock(scope); |
| 4423 | defer param_gz.unstack(); | 4327 | defer param_gz.unstack(); |
| ... | @@ -4426,8 +4330,7 @@ fn fnDeclInner( | ... | @@ -4426,8 +4330,7 @@ fn fnDeclInner( |
| 4426 | _ = 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); |
| 4427 | const param_type_is_generic = any_param_used; | 4331 | const param_type_is_generic = any_param_used; |
| 4428 | 4332 | ||
| 4429 | const main_tokens = tree.nodes.items(.main_token); | 4333 | const name_token = param.name_token orelse tree.nodeMainToken(param_type_node); |
| 4430 | const name_token = param.name_token orelse main_tokens[param_type_node]; | ||
| 4431 | 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; |
| 4432 | 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); |
| 4433 | assert(param_inst_expected == param_inst); | 4336 | assert(param_inst_expected == param_inst); |
| ... | @@ -4463,7 +4366,7 @@ fn fnDeclInner( | ... | @@ -4463,7 +4366,7 @@ fn fnDeclInner( |
| 4463 | // 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. |
| 4464 | // 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`. |
| 4465 | // See #22263 for a proposal to solve the inconsistency here. | 4368 | // See #22263 for a proposal to solve the inconsistency here. |
| 4466 | 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); |
| 4467 | if (ret_gz.instructionsSlice().len == 0) { | 4370 | if (ret_gz.instructionsSlice().len == 0) { |
| 4468 | // 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. |
| 4469 | break :inst inst; | 4372 | break :inst inst; |
| ... | @@ -4480,12 +4383,12 @@ fn fnDeclInner( | ... | @@ -4480,12 +4383,12 @@ fn fnDeclInner( |
| 4480 | var cc_gz = decl_gz.makeSubBlock(scope); | 4383 | var cc_gz = decl_gz.makeSubBlock(scope); |
| 4481 | defer cc_gz.unstack(); | 4384 | defer cc_gz.unstack(); |
| 4482 | const cc_ref: Zir.Inst.Ref = blk: { | 4385 | const cc_ref: Zir.Inst.Ref = blk: { |
| 4483 | if (fn_proto.ast.callconv_expr != 0) { | 4386 | if (fn_proto.ast.callconv_expr.unwrap()) |callconv_expr| { |
| 4484 | const inst = try expr( | 4387 | const inst = try expr( |
| 4485 | &cc_gz, | 4388 | &cc_gz, |
| 4486 | scope, | 4389 | scope, |
| 4487 | .{ .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) } }, |
| 4488 | fn_proto.ast.callconv_expr, | 4391 | callconv_expr, |
| 4489 | ); | 4392 | ); |
| 4490 | if (cc_gz.instructionsSlice().len == 0) { | 4393 | if (cc_gz.instructionsSlice().len == 0) { |
| 4491 | // 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. |
| ... | @@ -4524,7 +4427,7 @@ fn fnDeclInner( | ... | @@ -4524,7 +4427,7 @@ fn fnDeclInner( |
| 4524 | // Leave `astgen.src_hasher` unmodified; this will be used for hashing | 4427 | // Leave `astgen.src_hasher` unmodified; this will be used for hashing |
| 4525 | // the *whole* function declaration, including its body. | 4428 | // the *whole* function declaration, including its body. |
| 4526 | var proto_hasher = astgen.src_hasher; | 4429 | var proto_hasher = astgen.src_hasher; |
| 4527 | const proto_node = tree.nodes.items(.data)[decl_node].lhs; | 4430 | const proto_node = tree.nodeData(decl_node).node_and_node[0]; |
| 4528 | proto_hasher.update(tree.getNodeSource(proto_node)); | 4431 | proto_hasher.update(tree.getNodeSource(proto_node)); |
| 4529 | var proto_hash: std.zig.SrcHash = undefined; | 4432 | var proto_hash: std.zig.SrcHash = undefined; |
| 4530 | proto_hasher.final(&proto_hash); | 4433 | proto_hasher.final(&proto_hash); |
| ... | @@ -4594,7 +4497,6 @@ fn globalVarDecl( | ... | @@ -4594,7 +4497,6 @@ fn globalVarDecl( |
| 4594 | var_decl: Ast.full.VarDecl, | 4497 | var_decl: Ast.full.VarDecl, |
| 4595 | ) InnerError!void { | 4498 | ) InnerError!void { |
| 4596 | const tree = astgen.tree; | 4499 | const tree = astgen.tree; |
| 4597 | const token_tags = tree.tokens.items(.tag); | ||
| 4598 | 4500 | ||
| 4599 | const old_hasher = astgen.src_hasher; | 4501 | const old_hasher = astgen.src_hasher; |
| 4600 | defer astgen.src_hasher = old_hasher; | 4502 | defer astgen.src_hasher = old_hasher; |
| ... | @@ -4602,16 +4504,16 @@ fn globalVarDecl( | ... | @@ -4602,16 +4504,16 @@ fn globalVarDecl( |
| 4602 | astgen.src_hasher.update(tree.getNodeSource(node)); | 4504 | astgen.src_hasher.update(tree.getNodeSource(node)); |
| 4603 | astgen.src_hasher.update(std.mem.asBytes(&astgen.source_column)); | 4505 | astgen.src_hasher.update(std.mem.asBytes(&astgen.source_column)); |
| 4604 | 4506 | ||
| 4605 | 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; |
| 4606 | const name_token = var_decl.ast.mut_token + 1; | 4508 | const name_token = var_decl.ast.mut_token + 1; |
| 4607 | const is_pub = var_decl.visib_token != null; | 4509 | const is_pub = var_decl.visib_token != null; |
| 4608 | const is_export = blk: { | 4510 | const is_export = blk: { |
| 4609 | 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; |
| 4610 | break :blk token_tags[maybe_export_token] == .keyword_export; | 4512 | break :blk tree.tokenTag(maybe_export_token) == .keyword_export; |
| 4611 | }; | 4513 | }; |
| 4612 | const is_extern = blk: { | 4514 | const is_extern = blk: { |
| 4613 | 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; |
| 4614 | break :blk token_tags[maybe_extern_token] == .keyword_extern; | 4516 | break :blk tree.tokenTag(maybe_extern_token) == .keyword_extern; |
| 4615 | }; | 4517 | }; |
| 4616 | const is_threadlocal = if (var_decl.threadlocal_token) |tok| blk: { | 4518 | const is_threadlocal = if (var_decl.threadlocal_token) |tok| blk: { |
| 4617 | if (!is_mutable) { | 4519 | if (!is_mutable) { |
| ... | @@ -4637,10 +4539,10 @@ fn globalVarDecl( | ... | @@ -4637,10 +4539,10 @@ fn globalVarDecl( |
| 4637 | const decl_inst = try gz.makeDeclaration(node); | 4539 | const decl_inst = try gz.makeDeclaration(node); |
| 4638 | wip_members.nextDecl(decl_inst); | 4540 | wip_members.nextDecl(decl_inst); |
| 4639 | 4541 | ||
| 4640 | if (var_decl.ast.init_node != 0) { | 4542 | if (var_decl.ast.init_node.unwrap()) |init_node| { |
| 4641 | if (is_extern) { | 4543 | if (is_extern) { |
| 4642 | return astgen.failNode( | 4544 | return astgen.failNode( |
| 4643 | var_decl.ast.init_node, | 4545 | init_node, |
| 4644 | "extern variables have no initializers", | 4546 | "extern variables have no initializers", |
| 4645 | .{}, | 4547 | .{}, |
| 4646 | ); | 4548 | ); |
| ... | @@ -4651,7 +4553,7 @@ fn globalVarDecl( | ... | @@ -4651,7 +4553,7 @@ fn globalVarDecl( |
| 4651 | } | 4553 | } |
| 4652 | } | 4554 | } |
| 4653 | 4555 | ||
| 4654 | if (is_extern and var_decl.ast.type_node == 0) { | 4556 | if (is_extern and var_decl.ast.type_node == .none) { |
| 4655 | return astgen.failNode(node, "unable to infer variable type", .{}); | 4557 | return astgen.failNode(node, "unable to infer variable type", .{}); |
| 4656 | } | 4558 | } |
| 4657 | 4559 | ||
| ... | @@ -4668,45 +4570,45 @@ fn globalVarDecl( | ... | @@ -4668,45 +4570,45 @@ fn globalVarDecl( |
| 4668 | }; | 4570 | }; |
| 4669 | defer type_gz.unstack(); | 4571 | defer type_gz.unstack(); |
| 4670 | 4572 | ||
| 4671 | if (var_decl.ast.type_node != 0) { | 4573 | if (var_decl.ast.type_node.unwrap()) |type_node| { |
| 4672 | 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); |
| 4673 | _ = try type_gz.addBreakWithSrcNode(.break_inline, decl_inst, type_inst, node); | 4575 | _ = try type_gz.addBreakWithSrcNode(.break_inline, decl_inst, type_inst, node); |
| 4674 | } | 4576 | } |
| 4675 | 4577 | ||
| 4676 | var align_gz = type_gz.makeSubBlock(scope); | 4578 | var align_gz = type_gz.makeSubBlock(scope); |
| 4677 | defer align_gz.unstack(); | 4579 | defer align_gz.unstack(); |
| 4678 | 4580 | ||
| 4679 | if (var_decl.ast.align_node != 0) { | 4581 | if (var_decl.ast.align_node.unwrap()) |align_node| { |
| 4680 | 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); |
| 4681 | _ = try align_gz.addBreakWithSrcNode(.break_inline, decl_inst, align_inst, node); | 4583 | _ = try align_gz.addBreakWithSrcNode(.break_inline, decl_inst, align_inst, node); |
| 4682 | } | 4584 | } |
| 4683 | 4585 | ||
| 4684 | var linksection_gz = type_gz.makeSubBlock(scope); | 4586 | var linksection_gz = type_gz.makeSubBlock(scope); |
| 4685 | defer linksection_gz.unstack(); | 4587 | defer linksection_gz.unstack(); |
| 4686 | 4588 | ||
| 4687 | if (var_decl.ast.section_node != 0) { | 4589 | if (var_decl.ast.section_node.unwrap()) |section_node| { |
| 4688 | 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); |
| 4689 | _ = try linksection_gz.addBreakWithSrcNode(.break_inline, decl_inst, linksection_inst, node); | 4591 | _ = try linksection_gz.addBreakWithSrcNode(.break_inline, decl_inst, linksection_inst, node); |
| 4690 | } | 4592 | } |
| 4691 | 4593 | ||
| 4692 | var addrspace_gz = type_gz.makeSubBlock(scope); | 4594 | var addrspace_gz = type_gz.makeSubBlock(scope); |
| 4693 | defer addrspace_gz.unstack(); | 4595 | defer addrspace_gz.unstack(); |
| 4694 | 4596 | ||
| 4695 | if (var_decl.ast.addrspace_node != 0) { | 4597 | if (var_decl.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 4696 | 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); |
| 4697 | 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); |
| 4698 | _ = try addrspace_gz.addBreakWithSrcNode(.break_inline, decl_inst, addrspace_inst, node); | 4600 | _ = try addrspace_gz.addBreakWithSrcNode(.break_inline, decl_inst, addrspace_inst, node); |
| 4699 | } | 4601 | } |
| 4700 | 4602 | ||
| 4701 | var init_gz = type_gz.makeSubBlock(scope); | 4603 | var init_gz = type_gz.makeSubBlock(scope); |
| 4702 | defer init_gz.unstack(); | 4604 | defer init_gz.unstack(); |
| 4703 | 4605 | ||
| 4704 | if (var_decl.ast.init_node != 0) { | 4606 | if (var_decl.ast.init_node.unwrap()) |init_node| { |
| 4705 | init_gz.anon_name_strategy = .parent; | 4607 | init_gz.anon_name_strategy = .parent; |
| 4706 | const init_ri: ResultInfo = if (var_decl.ast.type_node != 0) .{ | 4608 | const init_ri: ResultInfo = if (var_decl.ast.type_node != .none) .{ |
| 4707 | .rl = .{ .coerced_ty = decl_inst.toRef() }, | 4609 | .rl = .{ .coerced_ty = decl_inst.toRef() }, |
| 4708 | } else .{ .rl = .none }; | 4610 | } else .{ .rl = .none }; |
| 4709 | 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); |
| 4710 | _ = try init_gz.addBreakWithSrcNode(.break_inline, decl_inst, init_inst, node); | 4612 | _ = try init_gz.addBreakWithSrcNode(.break_inline, decl_inst, init_inst, node); |
| 4711 | } | 4613 | } |
| 4712 | 4614 | ||
| ... | @@ -4740,8 +4642,7 @@ fn comptimeDecl( | ... | @@ -4740,8 +4642,7 @@ fn comptimeDecl( |
| 4740 | node: Ast.Node.Index, | 4642 | node: Ast.Node.Index, |
| 4741 | ) InnerError!void { | 4643 | ) InnerError!void { |
| 4742 | const tree = astgen.tree; | 4644 | const tree = astgen.tree; |
| 4743 | const node_datas = tree.nodes.items(.data); | 4645 | const body_node = tree.nodeData(node).node; |
| 4744 | const body_node = node_datas[node].lhs; | ||
| 4745 | 4646 | ||
| 4746 | const old_hasher = astgen.src_hasher; | 4647 | const old_hasher = astgen.src_hasher; |
| 4747 | defer astgen.src_hasher = old_hasher; | 4648 | defer astgen.src_hasher = old_hasher; |
| ... | @@ -4804,7 +4705,6 @@ fn usingnamespaceDecl( | ... | @@ -4804,7 +4705,6 @@ fn usingnamespaceDecl( |
| 4804 | node: Ast.Node.Index, | 4705 | node: Ast.Node.Index, |
| 4805 | ) InnerError!void { | 4706 | ) InnerError!void { |
| 4806 | const tree = astgen.tree; | 4707 | const tree = astgen.tree; |
| 4807 | const node_datas = tree.nodes.items(.data); | ||
| 4808 | 4708 | ||
| 4809 | const old_hasher = astgen.src_hasher; | 4709 | const old_hasher = astgen.src_hasher; |
| 4810 | defer astgen.src_hasher = old_hasher; | 4710 | defer astgen.src_hasher = old_hasher; |
| ... | @@ -4812,13 +4712,9 @@ fn usingnamespaceDecl( | ... | @@ -4812,13 +4712,9 @@ fn usingnamespaceDecl( |
| 4812 | astgen.src_hasher.update(tree.getNodeSource(node)); | 4712 | astgen.src_hasher.update(tree.getNodeSource(node)); |
| 4813 | astgen.src_hasher.update(std.mem.asBytes(&astgen.source_column)); | 4713 | astgen.src_hasher.update(std.mem.asBytes(&astgen.source_column)); |
| 4814 | 4714 | ||
| 4815 | const type_expr = node_datas[node].lhs; | 4715 | const type_expr = tree.nodeData(node).node; |
| 4816 | const is_pub = blk: { | 4716 | const is_pub = tree.isTokenPrecededByTags(tree.nodeMainToken(node), &.{.keyword_pub}); |
| 4817 | const main_tokens = tree.nodes.items(.main_token); | 4717 | |
| 4818 | const token_tags = tree.tokens.items(.tag); | ||
| 4819 | const main_token = main_tokens[node]; | ||
| 4820 | break :blk (main_token > 0 and token_tags[main_token - 1] == .keyword_pub); | ||
| 4821 | }; | ||
| 4822 | // 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 |
| 4823 | // top-level declaration. | 4719 | // top-level declaration. |
| 4824 | const decl_inst = try gz.makeDeclaration(node); | 4720 | const decl_inst = try gz.makeDeclaration(node); |
| ... | @@ -4872,8 +4768,7 @@ fn testDecl( | ... | @@ -4872,8 +4768,7 @@ fn testDecl( |
| 4872 | node: Ast.Node.Index, | 4768 | node: Ast.Node.Index, |
| 4873 | ) InnerError!void { | 4769 | ) InnerError!void { |
| 4874 | const tree = astgen.tree; | 4770 | const tree = astgen.tree; |
| 4875 | const node_datas = tree.nodes.items(.data); | 4771 | _, const body_node = tree.nodeData(node).opt_token_and_node; |
| 4876 | const body_node = node_datas[node].rhs; | ||
| 4877 | 4772 | ||
| 4878 | const old_hasher = astgen.src_hasher; | 4773 | const old_hasher = astgen.src_hasher; |
| 4879 | defer astgen.src_hasher = old_hasher; | 4774 | defer astgen.src_hasher = old_hasher; |
| ... | @@ -4905,12 +4800,10 @@ fn testDecl( | ... | @@ -4905,12 +4800,10 @@ fn testDecl( |
| 4905 | 4800 | ||
| 4906 | const decl_column = astgen.source_column; | 4801 | const decl_column = astgen.source_column; |
| 4907 | 4802 | ||
| 4908 | const main_tokens = tree.nodes.items(.main_token); | 4803 | const test_token = tree.nodeMainToken(node); |
| 4909 | const token_tags = tree.tokens.items(.tag); | ||
| 4910 | const test_token = main_tokens[node]; | ||
| 4911 | 4804 | ||
| 4912 | const test_name_token = test_token + 1; | 4805 | const test_name_token = test_token + 1; |
| 4913 | const test_name: Zir.NullTerminatedString = switch (token_tags[test_name_token]) { | 4806 | const test_name: Zir.NullTerminatedString = switch (tree.tokenTag(test_name_token)) { |
| 4914 | else => .empty, | 4807 | else => .empty, |
| 4915 | .string_literal => name: { | 4808 | .string_literal => name: { |
| 4916 | const name = try astgen.strLitAsString(test_name_token); | 4809 | const name = try astgen.strLitAsString(test_name_token); |
| ... | @@ -4942,7 +4835,7 @@ fn testDecl( | ... | @@ -4942,7 +4835,7 @@ fn testDecl( |
| 4942 | .local_val => { | 4835 | .local_val => { |
| 4943 | const local_val = s.cast(Scope.LocalVal).?; | 4836 | const local_val = s.cast(Scope.LocalVal).?; |
| 4944 | if (local_val.name == name_str_index) { | 4837 | if (local_val.name == name_str_index) { |
| 4945 | local_val.used = test_name_token; | 4838 | local_val.used = .fromToken(test_name_token); |
| 4946 | return astgen.failTokNotes(test_name_token, "cannot test a {s}", .{ | 4839 | return astgen.failTokNotes(test_name_token, "cannot test a {s}", .{ |
| 4947 | @tagName(local_val.id_cat), | 4840 | @tagName(local_val.id_cat), |
| 4948 | }, &[_]u32{ | 4841 | }, &[_]u32{ |
| ... | @@ -4956,7 +4849,7 @@ fn testDecl( | ... | @@ -4956,7 +4849,7 @@ fn testDecl( |
| 4956 | .local_ptr => { | 4849 | .local_ptr => { |
| 4957 | const local_ptr = s.cast(Scope.LocalPtr).?; | 4850 | const local_ptr = s.cast(Scope.LocalPtr).?; |
| 4958 | if (local_ptr.name == name_str_index) { | 4851 | if (local_ptr.name == name_str_index) { |
| 4959 | local_ptr.used = test_name_token; | 4852 | local_ptr.used = .fromToken(test_name_token); |
| 4960 | return astgen.failTokNotes(test_name_token, "cannot test a {s}", .{ | 4853 | return astgen.failTokNotes(test_name_token, "cannot test a {s}", .{ |
| 4961 | @tagName(local_ptr.id_cat), | 4854 | @tagName(local_ptr.id_cat), |
| 4962 | }, &[_]u32{ | 4855 | }, &[_]u32{ |
| ... | @@ -5067,7 +4960,7 @@ fn testDecl( | ... | @@ -5067,7 +4960,7 @@ fn testDecl( |
| 5067 | .src_line = decl_block.decl_line, | 4960 | .src_line = decl_block.decl_line, |
| 5068 | .src_column = decl_column, | 4961 | .src_column = decl_column, |
| 5069 | 4962 | ||
| 5070 | .kind = switch (token_tags[test_name_token]) { | 4963 | .kind = switch (tree.tokenTag(test_name_token)) { |
| 5071 | .string_literal => .@"test", | 4964 | .string_literal => .@"test", |
| 5072 | .identifier => .decltest, | 4965 | .identifier => .decltest, |
| 5073 | else => .unnamed_test, | 4966 | else => .unnamed_test, |
| ... | @@ -5091,7 +4984,7 @@ fn structDeclInner( | ... | @@ -5091,7 +4984,7 @@ fn structDeclInner( |
| 5091 | node: Ast.Node.Index, | 4984 | node: Ast.Node.Index, |
| 5092 | container_decl: Ast.full.ContainerDecl, | 4985 | container_decl: Ast.full.ContainerDecl, |
| 5093 | layout: std.builtin.Type.ContainerLayout, | 4986 | layout: std.builtin.Type.ContainerLayout, |
| 5094 | backing_int_node: Ast.Node.Index, | 4987 | backing_int_node: Ast.Node.OptionalIndex, |
| 5095 | ) InnerError!Zir.Inst.Ref { | 4988 | ) InnerError!Zir.Inst.Ref { |
| 5096 | const astgen = gz.astgen; | 4989 | const astgen = gz.astgen; |
| 5097 | const gpa = astgen.gpa; | 4990 | const gpa = astgen.gpa; |
| ... | @@ -5103,7 +4996,7 @@ fn structDeclInner( | ... | @@ -5103,7 +4996,7 @@ fn structDeclInner( |
| 5103 | if (container_field.ast.tuple_like) break member_node; | 4996 | if (container_field.ast.tuple_like) break member_node; |
| 5104 | } else break :is_tuple; | 4997 | } else break :is_tuple; |
| 5105 | 4998 | ||
| 5106 | if (node == 0) { | 4999 | if (node == .root) { |
| 5107 | return astgen.failNode(tuple_field_node, "file cannot be a tuple", .{}); | 5000 | return astgen.failNode(tuple_field_node, "file cannot be a tuple", .{}); |
| 5108 | } else { | 5001 | } else { |
| 5109 | return tupleDecl(gz, scope, node, container_decl, layout, backing_int_node); | 5002 | return tupleDecl(gz, scope, node, container_decl, layout, backing_int_node); |
| ... | @@ -5112,7 +5005,7 @@ fn structDeclInner( | ... | @@ -5112,7 +5005,7 @@ fn structDeclInner( |
| 5112 | 5005 | ||
| 5113 | const decl_inst = try gz.reserveInstructionIndex(); | 5006 | const decl_inst = try gz.reserveInstructionIndex(); |
| 5114 | 5007 | ||
| 5115 | 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) { |
| 5116 | try gz.setStruct(decl_inst, .{ | 5009 | try gz.setStruct(decl_inst, .{ |
| 5117 | .src_node = node, | 5010 | .src_node = node, |
| 5118 | .layout = layout, | 5011 | .layout = layout, |
| ... | @@ -5159,11 +5052,11 @@ fn structDeclInner( | ... | @@ -5159,11 +5052,11 @@ fn structDeclInner( |
| 5159 | 5052 | ||
| 5160 | var backing_int_body_len: usize = 0; | 5053 | var backing_int_body_len: usize = 0; |
| 5161 | const backing_int_ref: Zir.Inst.Ref = blk: { | 5054 | const backing_int_ref: Zir.Inst.Ref = blk: { |
| 5162 | if (backing_int_node != 0) { | 5055 | if (backing_int_node.unwrap()) |arg| { |
| 5163 | if (layout != .@"packed") { | 5056 | if (layout != .@"packed") { |
| 5164 | 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", .{}); |
| 5165 | } else { | 5058 | } else { |
| 5166 | 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); |
| 5167 | if (!block_scope.isEmpty()) { | 5060 | if (!block_scope.isEmpty()) { |
| 5168 | if (!block_scope.endsWithNoReturn()) { | 5061 | if (!block_scope.endsWithNoReturn()) { |
| 5169 | _ = try block_scope.addBreak(.break_inline, decl_inst, backing_int_ref); | 5062 | _ = try block_scope.addBreak(.break_inline, decl_inst, backing_int_ref); |
| ... | @@ -5208,8 +5101,8 @@ fn structDeclInner( | ... | @@ -5208,8 +5101,8 @@ fn structDeclInner( |
| 5208 | defer astgen.src_hasher = old_hasher; | 5101 | defer astgen.src_hasher = old_hasher; |
| 5209 | astgen.src_hasher = std.zig.SrcHasher.init(.{}); | 5102 | astgen.src_hasher = std.zig.SrcHasher.init(.{}); |
| 5210 | astgen.src_hasher.update(@tagName(layout)); | 5103 | astgen.src_hasher.update(@tagName(layout)); |
| 5211 | if (backing_int_node != 0) { | 5104 | if (backing_int_node.unwrap()) |arg| { |
| 5212 | astgen.src_hasher.update(tree.getNodeSource(backing_int_node)); | 5105 | astgen.src_hasher.update(tree.getNodeSource(arg)); |
| 5213 | } | 5106 | } |
| 5214 | 5107 | ||
| 5215 | var known_non_opv = false; | 5108 | var known_non_opv = false; |
| ... | @@ -5226,18 +5119,18 @@ fn structDeclInner( | ... | @@ -5226,18 +5119,18 @@ fn structDeclInner( |
| 5226 | astgen.src_hasher.update(tree.getNodeSource(member_node)); | 5119 | astgen.src_hasher.update(tree.getNodeSource(member_node)); |
| 5227 | 5120 | ||
| 5228 | const field_name = try astgen.identAsString(member.ast.main_token); | 5121 | const field_name = try astgen.identAsString(member.ast.main_token); |
| 5229 | member.convertToNonTupleLike(astgen.tree.nodes); | 5122 | member.convertToNonTupleLike(astgen.tree); |
| 5230 | assert(!member.ast.tuple_like); | 5123 | assert(!member.ast.tuple_like); |
| 5231 | wip_members.appendToField(@intFromEnum(field_name)); | 5124 | wip_members.appendToField(@intFromEnum(field_name)); |
| 5232 | 5125 | ||
| 5233 | if (member.ast.type_expr == 0) { | 5126 | const type_expr = member.ast.type_expr.unwrap() orelse { |
| 5234 | return astgen.failTok(member.ast.main_token, "struct field missing type", .{}); | 5127 | return astgen.failTok(member.ast.main_token, "struct field missing type", .{}); |
| 5235 | } | 5128 | }; |
| 5236 | 5129 | ||
| 5237 | 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); |
| 5238 | const have_type_body = !block_scope.isEmpty(); | 5131 | const have_type_body = !block_scope.isEmpty(); |
| 5239 | const have_align = member.ast.align_expr != 0; | 5132 | const have_align = member.ast.align_expr != .none; |
| 5240 | const have_value = member.ast.value_expr != 0; | 5133 | const have_value = member.ast.value_expr != .none; |
| 5241 | const is_comptime = member.comptime_token != null; | 5134 | const is_comptime = member.comptime_token != null; |
| 5242 | 5135 | ||
| 5243 | if (is_comptime) { | 5136 | if (is_comptime) { |
| ... | @@ -5247,9 +5140,9 @@ fn structDeclInner( | ... | @@ -5247,9 +5140,9 @@ fn structDeclInner( |
| 5247 | } | 5140 | } |
| 5248 | } else { | 5141 | } else { |
| 5249 | known_non_opv = known_non_opv or | 5142 | known_non_opv = known_non_opv or |
| 5250 | nodeImpliesMoreThanOnePossibleValue(tree, member.ast.type_expr); | 5143 | nodeImpliesMoreThanOnePossibleValue(tree, type_expr); |
| 5251 | known_comptime_only = known_comptime_only or | 5144 | known_comptime_only = known_comptime_only or |
| 5252 | nodeImpliesComptimeOnly(tree, member.ast.type_expr); | 5145 | nodeImpliesComptimeOnly(tree, type_expr); |
| 5253 | } | 5146 | } |
| 5254 | 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 }); |
| 5255 | 5148 | ||
| ... | @@ -5267,12 +5160,12 @@ fn structDeclInner( | ... | @@ -5267,12 +5160,12 @@ fn structDeclInner( |
| 5267 | wip_members.appendToField(@intFromEnum(field_type)); | 5160 | wip_members.appendToField(@intFromEnum(field_type)); |
| 5268 | } | 5161 | } |
| 5269 | 5162 | ||
| 5270 | if (have_align) { | 5163 | if (member.ast.align_expr.unwrap()) |align_expr| { |
| 5271 | if (layout == .@"packed") { | 5164 | if (layout == .@"packed") { |
| 5272 | 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", .{}); |
| 5273 | } | 5166 | } |
| 5274 | any_aligned_fields = true; | 5167 | any_aligned_fields = true; |
| 5275 | 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); |
| 5276 | if (!block_scope.endsWithNoReturn()) { | 5169 | if (!block_scope.endsWithNoReturn()) { |
| 5277 | _ = try block_scope.addBreak(.break_inline, decl_inst, align_ref); | 5170 | _ = try block_scope.addBreak(.break_inline, decl_inst, align_ref); |
| 5278 | } | 5171 | } |
| ... | @@ -5284,14 +5177,14 @@ fn structDeclInner( | ... | @@ -5284,14 +5177,14 @@ fn structDeclInner( |
| 5284 | block_scope.instructions.items.len = block_scope.instructions_top; | 5177 | block_scope.instructions.items.len = block_scope.instructions_top; |
| 5285 | } | 5178 | } |
| 5286 | 5179 | ||
| 5287 | if (have_value) { | 5180 | if (member.ast.value_expr.unwrap()) |value_expr| { |
| 5288 | any_default_inits = true; | 5181 | any_default_inits = true; |
| 5289 | 5182 | ||
| 5290 | // 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 |
| 5291 | // 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. |
| 5292 | 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() } }; |
| 5293 | 5186 | ||
| 5294 | 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); |
| 5295 | if (!block_scope.endsWithNoReturn()) { | 5188 | if (!block_scope.endsWithNoReturn()) { |
| 5296 | _ = try block_scope.addBreak(.break_inline, decl_inst, default_inst); | 5189 | _ = try block_scope.addBreak(.break_inline, decl_inst, default_inst); |
| 5297 | } | 5190 | } |
| ... | @@ -5354,21 +5247,19 @@ fn tupleDecl( | ... | @@ -5354,21 +5247,19 @@ fn tupleDecl( |
| 5354 | node: Ast.Node.Index, | 5247 | node: Ast.Node.Index, |
| 5355 | container_decl: Ast.full.ContainerDecl, | 5248 | container_decl: Ast.full.ContainerDecl, |
| 5356 | layout: std.builtin.Type.ContainerLayout, | 5249 | layout: std.builtin.Type.ContainerLayout, |
| 5357 | backing_int_node: Ast.Node.Index, | 5250 | backing_int_node: Ast.Node.OptionalIndex, |
| 5358 | ) InnerError!Zir.Inst.Ref { | 5251 | ) InnerError!Zir.Inst.Ref { |
| 5359 | const astgen = gz.astgen; | 5252 | const astgen = gz.astgen; |
| 5360 | const gpa = astgen.gpa; | 5253 | const gpa = astgen.gpa; |
| 5361 | const tree = astgen.tree; | 5254 | const tree = astgen.tree; |
| 5362 | 5255 | ||
| 5363 | const node_tags = tree.nodes.items(.tag); | ||
| 5364 | |||
| 5365 | switch (layout) { | 5256 | switch (layout) { |
| 5366 | .auto => {}, | 5257 | .auto => {}, |
| 5367 | .@"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)}), |
| 5368 | } | 5259 | } |
| 5369 | 5260 | ||
| 5370 | if (backing_int_node != 0) { | 5261 | if (backing_int_node.unwrap()) |arg| { |
| 5371 | 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", .{}); |
| 5372 | } | 5263 | } |
| 5373 | 5264 | ||
| 5374 | // 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: |
| ... | @@ -5383,7 +5274,7 @@ fn tupleDecl( | ... | @@ -5383,7 +5274,7 @@ fn tupleDecl( |
| 5383 | 5274 | ||
| 5384 | for (container_decl.ast.members) |member_node| { | 5275 | for (container_decl.ast.members) |member_node| { |
| 5385 | const field = tree.fullContainerField(member_node) orelse { | 5276 | const field = tree.fullContainerField(member_node) orelse { |
| 5386 | 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)) { |
| 5387 | .container_field_init, | 5278 | .container_field_init, |
| 5388 | .container_field_align, | 5279 | .container_field_align, |
| 5389 | .container_field, | 5280 | .container_field, |
| ... | @@ -5402,23 +5293,23 @@ fn tupleDecl( | ... | @@ -5402,23 +5293,23 @@ fn tupleDecl( |
| 5402 | 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", .{}); |
| 5403 | } | 5294 | } |
| 5404 | 5295 | ||
| 5405 | if (field.ast.align_expr != 0) { | 5296 | if (field.ast.align_expr != .none) { |
| 5406 | return astgen.failTok(field.ast.main_token, "tuple field has alignment", .{}); | 5297 | return astgen.failTok(field.ast.main_token, "tuple field has alignment", .{}); |
| 5407 | } | 5298 | } |
| 5408 | 5299 | ||
| 5409 | if (field.ast.value_expr != 0 and field.comptime_token == null) { | 5300 | if (field.ast.value_expr != .none and field.comptime_token == null) { |
| 5410 | 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", .{}); |
| 5411 | } | 5302 | } |
| 5412 | 5303 | ||
| 5413 | if (field.ast.value_expr == 0 and field.comptime_token != null) { | 5304 | if (field.ast.value_expr == .none and field.comptime_token != null) { |
| 5414 | 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", .{}); |
| 5415 | } | 5306 | } |
| 5416 | 5307 | ||
| 5417 | 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().?); |
| 5418 | astgen.scratch.appendAssumeCapacity(@intFromEnum(field_type_ref)); | 5309 | astgen.scratch.appendAssumeCapacity(@intFromEnum(field_type_ref)); |
| 5419 | 5310 | ||
| 5420 | if (field.ast.value_expr != 0) { | 5311 | if (field.ast.value_expr.unwrap()) |value_expr| { |
| 5421 | 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); |
| 5422 | astgen.scratch.appendAssumeCapacity(@intFromEnum(field_init_ref)); | 5313 | astgen.scratch.appendAssumeCapacity(@intFromEnum(field_init_ref)); |
| 5423 | } else { | 5314 | } else { |
| 5424 | astgen.scratch.appendAssumeCapacity(@intFromEnum(Zir.Inst.Ref.none)); | 5315 | astgen.scratch.appendAssumeCapacity(@intFromEnum(Zir.Inst.Ref.none)); |
| ... | @@ -5453,7 +5344,7 @@ fn unionDeclInner( | ... | @@ -5453,7 +5344,7 @@ fn unionDeclInner( |
| 5453 | node: Ast.Node.Index, | 5344 | node: Ast.Node.Index, |
| 5454 | members: []const Ast.Node.Index, | 5345 | members: []const Ast.Node.Index, |
| 5455 | layout: std.builtin.Type.ContainerLayout, | 5346 | layout: std.builtin.Type.ContainerLayout, |
| 5456 | arg_node: Ast.Node.Index, | 5347 | opt_arg_node: Ast.Node.OptionalIndex, |
| 5457 | auto_enum_tok: ?Ast.TokenIndex, | 5348 | auto_enum_tok: ?Ast.TokenIndex, |
| 5458 | ) InnerError!Zir.Inst.Ref { | 5349 | ) InnerError!Zir.Inst.Ref { |
| 5459 | const decl_inst = try gz.reserveInstructionIndex(); | 5350 | const decl_inst = try gz.reserveInstructionIndex(); |
| ... | @@ -5488,15 +5379,15 @@ fn unionDeclInner( | ... | @@ -5488,15 +5379,15 @@ fn unionDeclInner( |
| 5488 | const decl_count = try astgen.scanContainer(&namespace, members, .@"union"); | 5379 | const decl_count = try astgen.scanContainer(&namespace, members, .@"union"); |
| 5489 | const field_count: u32 = @intCast(members.len - decl_count); | 5380 | const field_count: u32 = @intCast(members.len - decl_count); |
| 5490 | 5381 | ||
| 5491 | 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)) { |
| 5492 | if (arg_node != 0) { | 5383 | if (opt_arg_node.unwrap()) |arg_node| { |
| 5493 | 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)}); |
| 5494 | } else { | 5385 | } else { |
| 5495 | 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)}); |
| 5496 | } | 5387 | } |
| 5497 | } | 5388 | } |
| 5498 | 5389 | ||
| 5499 | const arg_inst: Zir.Inst.Ref = if (arg_node != 0) | 5390 | const arg_inst: Zir.Inst.Ref = if (opt_arg_node.unwrap()) |arg_node| |
| 5500 | try typeExpr(&block_scope, &namespace.base, arg_node) | 5391 | try typeExpr(&block_scope, &namespace.base, arg_node) |
| 5501 | else | 5392 | else |
| 5502 | .none; | 5393 | .none; |
| ... | @@ -5512,7 +5403,7 @@ fn unionDeclInner( | ... | @@ -5512,7 +5403,7 @@ fn unionDeclInner( |
| 5512 | astgen.src_hasher = std.zig.SrcHasher.init(.{}); | 5403 | astgen.src_hasher = std.zig.SrcHasher.init(.{}); |
| 5513 | astgen.src_hasher.update(@tagName(layout)); | 5404 | astgen.src_hasher.update(@tagName(layout)); |
| 5514 | astgen.src_hasher.update(&.{@intFromBool(auto_enum_tok != null)}); | 5405 | astgen.src_hasher.update(&.{@intFromBool(auto_enum_tok != null)}); |
| 5515 | if (arg_node != 0) { | 5406 | if (opt_arg_node.unwrap()) |arg_node| { |
| 5516 | astgen.src_hasher.update(astgen.tree.getNodeSource(arg_node)); | 5407 | astgen.src_hasher.update(astgen.tree.getNodeSource(arg_node)); |
| 5517 | } | 5408 | } |
| 5518 | 5409 | ||
| ... | @@ -5522,7 +5413,7 @@ fn unionDeclInner( | ... | @@ -5522,7 +5413,7 @@ fn unionDeclInner( |
| 5522 | .field => |field| field, | 5413 | .field => |field| field, |
| 5523 | }; | 5414 | }; |
| 5524 | astgen.src_hasher.update(astgen.tree.getNodeSource(member_node)); | 5415 | astgen.src_hasher.update(astgen.tree.getNodeSource(member_node)); |
| 5525 | member.convertToNonTupleLike(astgen.tree.nodes); | 5416 | member.convertToNonTupleLike(astgen.tree); |
| 5526 | if (member.ast.tuple_like) { | 5417 | if (member.ast.tuple_like) { |
| 5527 | return astgen.failTok(member.ast.main_token, "union field missing name", .{}); | 5418 | return astgen.failTok(member.ast.main_token, "union field missing name", .{}); |
| 5528 | } | 5419 | } |
| ... | @@ -5533,24 +5424,24 @@ fn unionDeclInner( | ... | @@ -5533,24 +5424,24 @@ fn unionDeclInner( |
| 5533 | const field_name = try astgen.identAsString(member.ast.main_token); | 5424 | const field_name = try astgen.identAsString(member.ast.main_token); |
| 5534 | wip_members.appendToField(@intFromEnum(field_name)); | 5425 | wip_members.appendToField(@intFromEnum(field_name)); |
| 5535 | 5426 | ||
| 5536 | const have_type = member.ast.type_expr != 0; | 5427 | const have_type = member.ast.type_expr != .none; |
| 5537 | const have_align = member.ast.align_expr != 0; | 5428 | const have_align = member.ast.align_expr != .none; |
| 5538 | const have_value = member.ast.value_expr != 0; | 5429 | const have_value = member.ast.value_expr != .none; |
| 5539 | const unused = false; | 5430 | const unused = false; |
| 5540 | 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 }); |
| 5541 | 5432 | ||
| 5542 | if (have_type) { | 5433 | if (member.ast.type_expr.unwrap()) |type_expr| { |
| 5543 | 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); |
| 5544 | wip_members.appendToField(@intFromEnum(field_type)); | 5435 | wip_members.appendToField(@intFromEnum(field_type)); |
| 5545 | } else if (arg_inst == .none and auto_enum_tok == null) { | 5436 | } else if (arg_inst == .none and auto_enum_tok == null) { |
| 5546 | return astgen.failNode(member_node, "union field missing type", .{}); | 5437 | return astgen.failNode(member_node, "union field missing type", .{}); |
| 5547 | } | 5438 | } |
| 5548 | if (have_align) { | 5439 | if (member.ast.align_expr.unwrap()) |align_expr| { |
| 5549 | 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); |
| 5550 | wip_members.appendToField(@intFromEnum(align_inst)); | 5441 | wip_members.appendToField(@intFromEnum(align_inst)); |
| 5551 | any_aligned_fields = true; | 5442 | any_aligned_fields = true; |
| 5552 | } | 5443 | } |
| 5553 | if (have_value) { | 5444 | if (member.ast.value_expr.unwrap()) |value_expr| { |
| 5554 | if (arg_inst == .none) { | 5445 | if (arg_inst == .none) { |
| 5555 | return astgen.failNodeNotes( | 5446 | return astgen.failNodeNotes( |
| 5556 | node, | 5447 | node, |
| ... | @@ -5558,7 +5449,7 @@ fn unionDeclInner( | ... | @@ -5558,7 +5449,7 @@ fn unionDeclInner( |
| 5558 | .{}, | 5449 | .{}, |
| 5559 | &[_]u32{ | 5450 | &[_]u32{ |
| 5560 | try astgen.errNoteNode( | 5451 | try astgen.errNoteNode( |
| 5561 | member.ast.value_expr, | 5452 | value_expr, |
| 5562 | "tag value specified here", | 5453 | "tag value specified here", |
| 5563 | .{}, | 5454 | .{}, |
| 5564 | ), | 5455 | ), |
| ... | @@ -5572,14 +5463,14 @@ fn unionDeclInner( | ... | @@ -5572,14 +5463,14 @@ fn unionDeclInner( |
| 5572 | .{}, | 5463 | .{}, |
| 5573 | &[_]u32{ | 5464 | &[_]u32{ |
| 5574 | try astgen.errNoteNode( | 5465 | try astgen.errNoteNode( |
| 5575 | member.ast.value_expr, | 5466 | value_expr, |
| 5576 | "tag value specified here", | 5467 | "tag value specified here", |
| 5577 | .{}, | 5468 | .{}, |
| 5578 | ), | 5469 | ), |
| 5579 | }, | 5470 | }, |
| 5580 | ); | 5471 | ); |
| 5581 | } | 5472 | } |
| 5582 | 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); |
| 5583 | wip_members.appendToField(@intFromEnum(tag_value)); | 5474 | wip_members.appendToField(@intFromEnum(tag_value)); |
| 5584 | } | 5475 | } |
| 5585 | } | 5476 | } |
| ... | @@ -5631,7 +5522,6 @@ fn containerDecl( | ... | @@ -5631,7 +5522,6 @@ fn containerDecl( |
| 5631 | const astgen = gz.astgen; | 5522 | const astgen = gz.astgen; |
| 5632 | const gpa = astgen.gpa; | 5523 | const gpa = astgen.gpa; |
| 5633 | const tree = astgen.tree; | 5524 | const tree = astgen.tree; |
| 5634 | const token_tags = tree.tokens.items(.tag); | ||
| 5635 | 5525 | ||
| 5636 | const prev_fn_block = astgen.fn_block; | 5526 | const prev_fn_block = astgen.fn_block; |
| 5637 | astgen.fn_block = null; | 5527 | astgen.fn_block = null; |
| ... | @@ -5640,9 +5530,9 @@ fn containerDecl( | ... | @@ -5640,9 +5530,9 @@ fn containerDecl( |
| 5640 | // 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 |
| 5641 | // ZIR for all the field types, alignments, and default value expressions. | 5531 | // ZIR for all the field types, alignments, and default value expressions. |
| 5642 | 5532 | ||
| 5643 | switch (token_tags[container_decl.ast.main_token]) { | 5533 | switch (tree.tokenTag(container_decl.ast.main_token)) { |
| 5644 | .keyword_struct => { | 5534 | .keyword_struct => { |
| 5645 | 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)) { |
| 5646 | .keyword_packed => .@"packed", | 5536 | .keyword_packed => .@"packed", |
| 5647 | .keyword_extern => .@"extern", | 5537 | .keyword_extern => .@"extern", |
| 5648 | else => unreachable, | 5538 | else => unreachable, |
| ... | @@ -5652,7 +5542,7 @@ fn containerDecl( | ... | @@ -5652,7 +5542,7 @@ fn containerDecl( |
| 5652 | return rvalue(gz, ri, result, node); | 5542 | return rvalue(gz, ri, result, node); |
| 5653 | }, | 5543 | }, |
| 5654 | .keyword_union => { | 5544 | .keyword_union => { |
| 5655 | 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)) { |
| 5656 | .keyword_packed => .@"packed", | 5546 | .keyword_packed => .@"packed", |
| 5657 | .keyword_extern => .@"extern", | 5547 | .keyword_extern => .@"extern", |
| 5658 | else => unreachable, | 5548 | else => unreachable, |
| ... | @@ -5670,23 +5560,23 @@ fn containerDecl( | ... | @@ -5670,23 +5560,23 @@ fn containerDecl( |
| 5670 | var values: usize = 0; | 5560 | var values: usize = 0; |
| 5671 | var total_fields: usize = 0; | 5561 | var total_fields: usize = 0; |
| 5672 | var decls: usize = 0; | 5562 | var decls: usize = 0; |
| 5673 | var nonexhaustive_node: Ast.Node.Index = 0; | 5563 | var opt_nonexhaustive_node: Ast.Node.OptionalIndex = .none; |
| 5674 | var nonfinal_nonexhaustive = false; | 5564 | var nonfinal_nonexhaustive = false; |
| 5675 | for (container_decl.ast.members) |member_node| { | 5565 | for (container_decl.ast.members) |member_node| { |
| 5676 | var member = tree.fullContainerField(member_node) orelse { | 5566 | var member = tree.fullContainerField(member_node) orelse { |
| 5677 | decls += 1; | 5567 | decls += 1; |
| 5678 | continue; | 5568 | continue; |
| 5679 | }; | 5569 | }; |
| 5680 | member.convertToNonTupleLike(astgen.tree.nodes); | 5570 | member.convertToNonTupleLike(astgen.tree); |
| 5681 | if (member.ast.tuple_like) { | 5571 | if (member.ast.tuple_like) { |
| 5682 | return astgen.failTok(member.ast.main_token, "enum field missing name", .{}); | 5572 | return astgen.failTok(member.ast.main_token, "enum field missing name", .{}); |
| 5683 | } | 5573 | } |
| 5684 | if (member.comptime_token) |comptime_token| { | 5574 | if (member.comptime_token) |comptime_token| { |
| 5685 | return astgen.failTok(comptime_token, "enum fields cannot be marked comptime", .{}); | 5575 | return astgen.failTok(comptime_token, "enum fields cannot be marked comptime", .{}); |
| 5686 | } | 5576 | } |
| 5687 | if (member.ast.type_expr != 0) { | 5577 | if (member.ast.type_expr.unwrap()) |type_expr| { |
| 5688 | return astgen.failNodeNotes( | 5578 | return astgen.failNodeNotes( |
| 5689 | member.ast.type_expr, | 5579 | type_expr, |
| 5690 | "enum fields do not have types", | 5580 | "enum fields do not have types", |
| 5691 | .{}, | 5581 | .{}, |
| 5692 | &[_]u32{ | 5582 | &[_]u32{ |
| ... | @@ -5698,13 +5588,13 @@ fn containerDecl( | ... | @@ -5698,13 +5588,13 @@ fn containerDecl( |
| 5698 | }, | 5588 | }, |
| 5699 | ); | 5589 | ); |
| 5700 | } | 5590 | } |
| 5701 | if (member.ast.align_expr != 0) { | 5591 | if (member.ast.align_expr.unwrap()) |align_expr| { |
| 5702 | return astgen.failNode(member.ast.align_expr, "enum fields cannot be aligned", .{}); | 5592 | return astgen.failNode(align_expr, "enum fields cannot be aligned", .{}); |
| 5703 | } | 5593 | } |
| 5704 | 5594 | ||
| 5705 | const name_token = member.ast.main_token; | 5595 | const name_token = member.ast.main_token; |
| 5706 | if (mem.eql(u8, tree.tokenSlice(name_token), "_")) { | 5596 | if (mem.eql(u8, tree.tokenSlice(name_token), "_")) { |
| 5707 | if (nonexhaustive_node != 0) { | 5597 | if (opt_nonexhaustive_node.unwrap()) |nonexhaustive_node| { |
| 5708 | return astgen.failNodeNotes( | 5598 | return astgen.failNodeNotes( |
| 5709 | member_node, | 5599 | member_node, |
| 5710 | "redundant non-exhaustive enum mark", | 5600 | "redundant non-exhaustive enum mark", |
| ... | @@ -5718,40 +5608,41 @@ fn containerDecl( | ... | @@ -5718,40 +5608,41 @@ fn containerDecl( |
| 5718 | }, | 5608 | }, |
| 5719 | ); | 5609 | ); |
| 5720 | } | 5610 | } |
| 5721 | nonexhaustive_node = member_node; | 5611 | opt_nonexhaustive_node = member_node.toOptional(); |
| 5722 | if (member.ast.value_expr != 0) { | 5612 | if (member.ast.value_expr.unwrap()) |value_expr| { |
| 5723 | 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", .{}); |
| 5724 | } | 5614 | } |
| 5725 | continue; | 5615 | continue; |
| 5726 | } else if (nonexhaustive_node != 0) { | 5616 | } else if (opt_nonexhaustive_node != .none) { |
| 5727 | nonfinal_nonexhaustive = true; | 5617 | nonfinal_nonexhaustive = true; |
| 5728 | } | 5618 | } |
| 5729 | total_fields += 1; | 5619 | total_fields += 1; |
| 5730 | if (member.ast.value_expr != 0) { | 5620 | if (member.ast.value_expr.unwrap()) |value_expr| { |
| 5731 | if (container_decl.ast.arg == 0) { | 5621 | if (container_decl.ast.arg == .none) { |
| 5732 | 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", .{}); |
| 5733 | } | 5623 | } |
| 5734 | values += 1; | 5624 | values += 1; |
| 5735 | } | 5625 | } |
| 5736 | } | 5626 | } |
| 5737 | if (nonfinal_nonexhaustive) { | 5627 | if (nonfinal_nonexhaustive) { |
| 5738 | 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", .{}); |
| 5739 | } | 5629 | } |
| 5740 | break :blk .{ | 5630 | break :blk .{ |
| 5741 | .total_fields = total_fields, | 5631 | .total_fields = total_fields, |
| 5742 | .values = values, | 5632 | .values = values, |
| 5743 | .decls = decls, | 5633 | .decls = decls, |
| 5744 | .nonexhaustive_node = nonexhaustive_node, | 5634 | .nonexhaustive_node = opt_nonexhaustive_node, |
| 5745 | }; | 5635 | }; |
| 5746 | }; | 5636 | }; |
| 5747 | 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().?; | ||
| 5748 | return astgen.failNodeNotes( | 5639 | return astgen.failNodeNotes( |
| 5749 | node, | 5640 | node, |
| 5750 | "non-exhaustive enum missing integer tag type", | 5641 | "non-exhaustive enum missing integer tag type", |
| 5751 | .{}, | 5642 | .{}, |
| 5752 | &[_]u32{ | 5643 | &[_]u32{ |
| 5753 | try astgen.errNoteNode( | 5644 | try astgen.errNoteNode( |
| 5754 | counts.nonexhaustive_node, | 5645 | nonexhaustive_node, |
| 5755 | "marked non-exhaustive here", | 5646 | "marked non-exhaustive here", |
| 5756 | .{}, | 5647 | .{}, |
| 5757 | ), | 5648 | ), |
| ... | @@ -5760,7 +5651,7 @@ fn containerDecl( | ... | @@ -5760,7 +5651,7 @@ fn containerDecl( |
| 5760 | } | 5651 | } |
| 5761 | // 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 |
| 5762 | // how structs are handled above. | 5653 | // how structs are handled above. |
| 5763 | const nonexhaustive = counts.nonexhaustive_node != 0; | 5654 | const nonexhaustive = counts.nonexhaustive_node != .none; |
| 5764 | 5655 | ||
| 5765 | const decl_inst = try gz.reserveInstructionIndex(); | 5656 | const decl_inst = try gz.reserveInstructionIndex(); |
| 5766 | 5657 | ||
| ... | @@ -5790,8 +5681,8 @@ fn containerDecl( | ... | @@ -5790,8 +5681,8 @@ fn containerDecl( |
| 5790 | _ = try astgen.scanContainer(&namespace, container_decl.ast.members, .@"enum"); | 5681 | _ = try astgen.scanContainer(&namespace, container_decl.ast.members, .@"enum"); |
| 5791 | namespace.base.tag = .namespace; | 5682 | namespace.base.tag = .namespace; |
| 5792 | 5683 | ||
| 5793 | 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| |
| 5794 | 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) |
| 5795 | else | 5686 | else |
| 5796 | .none; | 5687 | .none; |
| 5797 | 5688 | ||
| ... | @@ -5803,31 +5694,31 @@ fn containerDecl( | ... | @@ -5803,31 +5694,31 @@ fn containerDecl( |
| 5803 | const old_hasher = astgen.src_hasher; | 5694 | const old_hasher = astgen.src_hasher; |
| 5804 | defer astgen.src_hasher = old_hasher; | 5695 | defer astgen.src_hasher = old_hasher; |
| 5805 | astgen.src_hasher = std.zig.SrcHasher.init(.{}); | 5696 | astgen.src_hasher = std.zig.SrcHasher.init(.{}); |
| 5806 | if (container_decl.ast.arg != 0) { | 5697 | if (container_decl.ast.arg.unwrap()) |arg| { |
| 5807 | astgen.src_hasher.update(tree.getNodeSource(container_decl.ast.arg)); | 5698 | astgen.src_hasher.update(tree.getNodeSource(arg)); |
| 5808 | } | 5699 | } |
| 5809 | astgen.src_hasher.update(&.{@intFromBool(nonexhaustive)}); | 5700 | astgen.src_hasher.update(&.{@intFromBool(nonexhaustive)}); |
| 5810 | 5701 | ||
| 5811 | for (container_decl.ast.members) |member_node| { | 5702 | for (container_decl.ast.members) |member_node| { |
| 5812 | if (member_node == counts.nonexhaustive_node) | 5703 | if (member_node.toOptional() == counts.nonexhaustive_node) |
| 5813 | continue; | 5704 | continue; |
| 5814 | astgen.src_hasher.update(tree.getNodeSource(member_node)); | 5705 | astgen.src_hasher.update(tree.getNodeSource(member_node)); |
| 5815 | 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)) { |
| 5816 | .decl => continue, | 5707 | .decl => continue, |
| 5817 | .field => |field| field, | 5708 | .field => |field| field, |
| 5818 | }; | 5709 | }; |
| 5819 | member.convertToNonTupleLike(astgen.tree.nodes); | 5710 | member.convertToNonTupleLike(astgen.tree); |
| 5820 | assert(member.comptime_token == null); | 5711 | assert(member.comptime_token == null); |
| 5821 | assert(member.ast.type_expr == 0); | 5712 | assert(member.ast.type_expr == .none); |
| 5822 | assert(member.ast.align_expr == 0); | 5713 | assert(member.ast.align_expr == .none); |
| 5823 | 5714 | ||
| 5824 | const field_name = try astgen.identAsString(member.ast.main_token); | 5715 | const field_name = try astgen.identAsString(member.ast.main_token); |
| 5825 | wip_members.appendToField(@intFromEnum(field_name)); | 5716 | wip_members.appendToField(@intFromEnum(field_name)); |
| 5826 | 5717 | ||
| 5827 | const have_value = member.ast.value_expr != 0; | 5718 | const have_value = member.ast.value_expr != .none; |
| 5828 | wip_members.nextField(bits_per_field, .{have_value}); | 5719 | wip_members.nextField(bits_per_field, .{have_value}); |
| 5829 | 5720 | ||
| 5830 | if (have_value) { | 5721 | if (member.ast.value_expr.unwrap()) |value_expr| { |
| 5831 | if (arg_inst == .none) { | 5722 | if (arg_inst == .none) { |
| 5832 | return astgen.failNodeNotes( | 5723 | return astgen.failNodeNotes( |
| 5833 | node, | 5724 | node, |
| ... | @@ -5835,14 +5726,14 @@ fn containerDecl( | ... | @@ -5835,14 +5726,14 @@ fn containerDecl( |
| 5835 | .{}, | 5726 | .{}, |
| 5836 | &[_]u32{ | 5727 | &[_]u32{ |
| 5837 | try astgen.errNoteNode( | 5728 | try astgen.errNoteNode( |
| 5838 | member.ast.value_expr, | 5729 | value_expr, |
| 5839 | "tag value specified here", | 5730 | "tag value specified here", |
| 5840 | .{}, | 5731 | .{}, |
| 5841 | ), | 5732 | ), |
| 5842 | }, | 5733 | }, |
| 5843 | ); | 5734 | ); |
| 5844 | } | 5735 | } |
| 5845 | 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); |
| 5846 | wip_members.appendToField(@intFromEnum(tag_value_inst)); | 5737 | wip_members.appendToField(@intFromEnum(tag_value_inst)); |
| 5847 | } | 5738 | } |
| 5848 | } | 5739 | } |
| ... | @@ -5882,7 +5773,7 @@ fn containerDecl( | ... | @@ -5882,7 +5773,7 @@ fn containerDecl( |
| 5882 | return rvalue(gz, ri, decl_inst.toRef(), node); | 5773 | return rvalue(gz, ri, decl_inst.toRef(), node); |
| 5883 | }, | 5774 | }, |
| 5884 | .keyword_opaque => { | 5775 | .keyword_opaque => { |
| 5885 | assert(container_decl.ast.arg == 0); | 5776 | assert(container_decl.ast.arg == .none); |
| 5886 | 5777 | ||
| 5887 | const decl_inst = try gz.reserveInstructionIndex(); | 5778 | const decl_inst = try gz.reserveInstructionIndex(); |
| 5888 | 5779 | ||
| ... | @@ -5953,9 +5844,7 @@ fn containerMember( | ... | @@ -5953,9 +5844,7 @@ fn containerMember( |
| 5953 | ) InnerError!ContainerMemberResult { | 5844 | ) InnerError!ContainerMemberResult { |
| 5954 | const astgen = gz.astgen; | 5845 | const astgen = gz.astgen; |
| 5955 | const tree = astgen.tree; | 5846 | const tree = astgen.tree; |
| 5956 | const node_tags = tree.nodes.items(.tag); | 5847 | switch (tree.nodeTag(member_node)) { |
| 5957 | const node_datas = tree.nodes.items(.data); | ||
| 5958 | switch (node_tags[member_node]) { | ||
| 5959 | .container_field_init, | 5848 | .container_field_init, |
| 5960 | .container_field_align, | 5849 | .container_field_align, |
| 5961 | .container_field, | 5850 | .container_field, |
| ... | @@ -5969,7 +5858,11 @@ fn containerMember( | ... | @@ -5969,7 +5858,11 @@ fn containerMember( |
| 5969 | => { | 5858 | => { |
| 5970 | var buf: [1]Ast.Node.Index = undefined; | 5859 | var buf: [1]Ast.Node.Index = undefined; |
| 5971 | const full = tree.fullFnProto(&buf, member_node).?; | 5860 | const full = tree.fullFnProto(&buf, member_node).?; |
| 5972 | 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; | ||
| 5973 | 5866 | ||
| 5974 | const prev_decl_index = wip_members.decl_index; | 5867 | const prev_decl_index = wip_members.decl_index; |
| 5975 | 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) { |
| ... | @@ -6040,12 +5933,7 @@ fn containerMember( | ... | @@ -6040,12 +5933,7 @@ fn containerMember( |
| 6040 | .@"usingnamespace", | 5933 | .@"usingnamespace", |
| 6041 | .empty, | 5934 | .empty, |
| 6042 | member_node, | 5935 | member_node, |
| 6043 | is_pub: { | 5936 | tree.isTokenPrecededByTags(tree.nodeMainToken(member_node), &.{.keyword_pub}), |
| 6044 | const main_tokens = tree.nodes.items(.main_token); | ||
| 6045 | const token_tags = tree.tokens.items(.tag); | ||
| 6046 | const main_token = main_tokens[member_node]; | ||
| 6047 | break :is_pub main_token > 0 and token_tags[main_token - 1] == .keyword_pub; | ||
| 6048 | }, | ||
| 6049 | ); | 5937 | ); |
| 6050 | }, | 5938 | }, |
| 6051 | }; | 5939 | }; |
| ... | @@ -6079,8 +5967,6 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi | ... | @@ -6079,8 +5967,6 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi |
| 6079 | const astgen = gz.astgen; | 5967 | const astgen = gz.astgen; |
| 6080 | const gpa = astgen.gpa; | 5968 | const gpa = astgen.gpa; |
| 6081 | const tree = astgen.tree; | 5969 | const tree = astgen.tree; |
| 6082 | const main_tokens = tree.nodes.items(.main_token); | ||
| 6083 | const token_tags = tree.tokens.items(.tag); | ||
| 6084 | 5970 | ||
| 6085 | 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); |
| 6086 | var fields_len: usize = 0; | 5972 | var fields_len: usize = 0; |
| ... | @@ -6088,10 +5974,10 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi | ... | @@ -6088,10 +5974,10 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi |
| 6088 | var idents: std.AutoHashMapUnmanaged(Zir.NullTerminatedString, Ast.TokenIndex) = .empty; | 5974 | var idents: std.AutoHashMapUnmanaged(Zir.NullTerminatedString, Ast.TokenIndex) = .empty; |
| 6089 | defer idents.deinit(gpa); | 5975 | defer idents.deinit(gpa); |
| 6090 | 5976 | ||
| 6091 | const error_token = main_tokens[node]; | 5977 | const lbrace, const rbrace = tree.nodeData(node).token_and_token; |
| 6092 | var tok_i = error_token + 2; | 5978 | for (lbrace + 1..rbrace) |i| { |
| 6093 | while (true) : (tok_i += 1) { | 5979 | const tok_i: Ast.TokenIndex = @intCast(i); |
| 6094 | switch (token_tags[tok_i]) { | 5980 | switch (tree.tokenTag(tok_i)) { |
| 6095 | .doc_comment, .comma => {}, | 5981 | .doc_comment, .comma => {}, |
| 6096 | .identifier => { | 5982 | .identifier => { |
| 6097 | const str_index = try astgen.identAsString(tok_i); | 5983 | const str_index = try astgen.identAsString(tok_i); |
| ... | @@ -6117,7 +6003,6 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi | ... | @@ -6117,7 +6003,6 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi |
| 6117 | try astgen.extra.append(gpa, @intFromEnum(str_index)); | 6003 | try astgen.extra.append(gpa, @intFromEnum(str_index)); |
| 6118 | fields_len += 1; | 6004 | fields_len += 1; |
| 6119 | }, | 6005 | }, |
| 6120 | .r_brace => break, | ||
| 6121 | else => unreachable, | 6006 | else => unreachable, |
| 6122 | } | 6007 | } |
| 6123 | } | 6008 | } |
| ... | @@ -6143,10 +6028,10 @@ fn tryExpr( | ... | @@ -6143,10 +6028,10 @@ fn tryExpr( |
| 6143 | return astgen.failNode(node, "'try' outside function scope", .{}); | 6028 | return astgen.failNode(node, "'try' outside function scope", .{}); |
| 6144 | }; | 6029 | }; |
| 6145 | 6030 | ||
| 6146 | if (parent_gz.any_defer_node != 0) { | 6031 | if (parent_gz.any_defer_node.unwrap()) |any_defer_node| { |
| 6147 | return astgen.failNodeNotes(node, "'try' not allowed inside defer expression", .{}, &.{ | 6032 | return astgen.failNodeNotes(node, "'try' not allowed inside defer expression", .{}, &.{ |
| 6148 | try astgen.errNoteNode( | 6033 | try astgen.errNoteNode( |
| 6149 | parent_gz.any_defer_node, | 6034 | any_defer_node, |
| 6150 | "defer expression here", | 6035 | "defer expression here", |
| 6151 | .{}, | 6036 | .{}, |
| 6152 | ), | 6037 | ), |
| ... | @@ -6209,16 +6094,16 @@ fn orelseCatchExpr( | ... | @@ -6209,16 +6094,16 @@ fn orelseCatchExpr( |
| 6209 | scope: *Scope, | 6094 | scope: *Scope, |
| 6210 | ri: ResultInfo, | 6095 | ri: ResultInfo, |
| 6211 | node: Ast.Node.Index, | 6096 | node: Ast.Node.Index, |
| 6212 | lhs: Ast.Node.Index, | ||
| 6213 | cond_op: Zir.Inst.Tag, | 6097 | cond_op: Zir.Inst.Tag, |
| 6214 | unwrap_op: Zir.Inst.Tag, | 6098 | unwrap_op: Zir.Inst.Tag, |
| 6215 | unwrap_code_op: Zir.Inst.Tag, | 6099 | unwrap_code_op: Zir.Inst.Tag, |
| 6216 | rhs: Ast.Node.Index, | ||
| 6217 | payload_token: ?Ast.TokenIndex, | 6100 | payload_token: ?Ast.TokenIndex, |
| 6218 | ) InnerError!Zir.Inst.Ref { | 6101 | ) InnerError!Zir.Inst.Ref { |
| 6219 | const astgen = parent_gz.astgen; | 6102 | const astgen = parent_gz.astgen; |
| 6220 | const tree = astgen.tree; | 6103 | const tree = astgen.tree; |
| 6221 | 6104 | ||
| 6105 | const lhs, const rhs = tree.nodeData(node).node_and_node; | ||
| 6106 | |||
| 6222 | const need_rl = astgen.nodes_need_rl.contains(node); | 6107 | const need_rl = astgen.nodes_need_rl.contains(node); |
| 6223 | const block_ri: ResultInfo = if (need_rl) ri else .{ | 6108 | const block_ri: ResultInfo = if (need_rl) ri else .{ |
| 6224 | .rl = switch (ri.rl) { | 6109 | .rl = switch (ri.rl) { |
| ... | @@ -6351,12 +6236,8 @@ fn addFieldAccess( | ... | @@ -6351,12 +6236,8 @@ fn addFieldAccess( |
| 6351 | ) InnerError!Zir.Inst.Ref { | 6236 | ) InnerError!Zir.Inst.Ref { |
| 6352 | const astgen = gz.astgen; | 6237 | const astgen = gz.astgen; |
| 6353 | const tree = astgen.tree; | 6238 | const tree = astgen.tree; |
| 6354 | const main_tokens = tree.nodes.items(.main_token); | ||
| 6355 | const node_datas = tree.nodes.items(.data); | ||
| 6356 | 6239 | ||
| 6357 | const object_node = node_datas[node].lhs; | 6240 | const object_node, const field_ident = tree.nodeData(node).node_and_token; |
| 6358 | const dot_token = main_tokens[node]; | ||
| 6359 | const field_ident = dot_token + 1; | ||
| 6360 | const str_index = try astgen.identAsString(field_ident); | 6241 | const str_index = try astgen.identAsString(field_ident); |
| 6361 | const lhs = try expr(gz, scope, lhs_ri, object_node); | 6242 | const lhs = try expr(gz, scope, lhs_ri, object_node); |
| 6362 | 6243 | ||
| ... | @@ -6376,24 +6257,25 @@ fn arrayAccess( | ... | @@ -6376,24 +6257,25 @@ fn arrayAccess( |
| 6376 | node: Ast.Node.Index, | 6257 | node: Ast.Node.Index, |
| 6377 | ) InnerError!Zir.Inst.Ref { | 6258 | ) InnerError!Zir.Inst.Ref { |
| 6378 | const tree = gz.astgen.tree; | 6259 | const tree = gz.astgen.tree; |
| 6379 | const node_datas = tree.nodes.items(.data); | ||
| 6380 | switch (ri.rl) { | 6260 | switch (ri.rl) { |
| 6381 | .ref, .ref_coerced_ty => { | 6261 | .ref, .ref_coerced_ty => { |
| 6382 | const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs); | 6262 | const lhs_node, const rhs_node = tree.nodeData(node).node_and_node; |
| 6263 | const lhs = try expr(gz, scope, .{ .rl = .ref }, lhs_node); | ||
| 6383 | 6264 | ||
| 6384 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | 6265 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); |
| 6385 | 6266 | ||
| 6386 | const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[node].rhs); | 6267 | const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, rhs_node); |
| 6387 | try emitDbgStmt(gz, cursor); | 6268 | try emitDbgStmt(gz, cursor); |
| 6388 | 6269 | ||
| 6389 | return gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }); | 6270 | return gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }); |
| 6390 | }, | 6271 | }, |
| 6391 | else => { | 6272 | else => { |
| 6392 | const lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs); | 6273 | const lhs_node, const rhs_node = tree.nodeData(node).node_and_node; |
| 6274 | const lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node); | ||
| 6393 | 6275 | ||
| 6394 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); | 6276 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); |
| 6395 | 6277 | ||
| 6396 | const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[node].rhs); | 6278 | const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, rhs_node); |
| 6397 | try emitDbgStmt(gz, cursor); | 6279 | try emitDbgStmt(gz, cursor); |
| 6398 | 6280 | ||
| 6399 | return rvalue(gz, ri, try gz.addPlNode(.elem_val_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }), node); | 6281 | return rvalue(gz, ri, try gz.addPlNode(.elem_val_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }), node); |
| ... | @@ -6410,22 +6292,22 @@ fn simpleBinOp( | ... | @@ -6410,22 +6292,22 @@ fn simpleBinOp( |
| 6410 | ) InnerError!Zir.Inst.Ref { | 6292 | ) InnerError!Zir.Inst.Ref { |
| 6411 | const astgen = gz.astgen; | 6293 | const astgen = gz.astgen; |
| 6412 | const tree = astgen.tree; | 6294 | const tree = astgen.tree; |
| 6413 | const node_datas = tree.nodes.items(.data); | 6295 | |
| 6296 | const lhs_node, const rhs_node = tree.nodeData(node).node_and_node; | ||
| 6414 | 6297 | ||
| 6415 | if (op_inst_tag == .cmp_neq or op_inst_tag == .cmp_eq) { | 6298 | if (op_inst_tag == .cmp_neq or op_inst_tag == .cmp_eq) { |
| 6416 | const node_tags = tree.nodes.items(.tag); | ||
| 6417 | const str = if (op_inst_tag == .cmp_eq) "==" else "!="; | 6299 | const str = if (op_inst_tag == .cmp_eq) "==" else "!="; |
| 6418 | if (node_tags[node_datas[node].lhs] == .string_literal or | 6300 | if (tree.nodeTag(lhs_node) == .string_literal or |
| 6419 | node_tags[node_datas[node].rhs] == .string_literal) | 6301 | tree.nodeTag(rhs_node) == .string_literal) |
| 6420 | return astgen.failNode(node, "cannot compare strings with {s}", .{str}); | 6302 | return astgen.failNode(node, "cannot compare strings with {s}", .{str}); |
| 6421 | } | 6303 | } |
| 6422 | 6304 | ||
| 6423 | const lhs = try reachableExpr(gz, scope, .{ .rl = .none }, node_datas[node].lhs, node); | 6305 | const lhs = try reachableExpr(gz, scope, .{ .rl = .none }, lhs_node, node); |
| 6424 | const cursor = switch (op_inst_tag) { | 6306 | const cursor = switch (op_inst_tag) { |
| 6425 | .add, .sub, .mul, .div, .mod_rem => maybeAdvanceSourceCursorToMainToken(gz, node), | 6307 | .add, .sub, .mul, .div, .mod_rem => maybeAdvanceSourceCursorToMainToken(gz, node), |
| 6426 | else => undefined, | 6308 | else => undefined, |
| 6427 | }; | 6309 | }; |
| 6428 | const rhs = try reachableExpr(gz, scope, .{ .rl = .none }, node_datas[node].rhs, node); | 6310 | const rhs = try reachableExpr(gz, scope, .{ .rl = .none }, rhs_node, node); |
| 6429 | 6311 | ||
| 6430 | switch (op_inst_tag) { | 6312 | switch (op_inst_tag) { |
| 6431 | .add, .sub, .mul, .div, .mod_rem => { | 6313 | .add, .sub, .mul, .div, .mod_rem => { |
| ... | @@ -6459,16 +6341,16 @@ fn boolBinOp( | ... | @@ -6459,16 +6341,16 @@ fn boolBinOp( |
| 6459 | ) InnerError!Zir.Inst.Ref { | 6341 | ) InnerError!Zir.Inst.Ref { |
| 6460 | const astgen = gz.astgen; | 6342 | const astgen = gz.astgen; |
| 6461 | const tree = astgen.tree; | 6343 | const tree = astgen.tree; |
| 6462 | const node_datas = tree.nodes.items(.data); | ||
| 6463 | 6344 | ||
| 6464 | const lhs = try expr(gz, scope, coerced_bool_ri, node_datas[node].lhs); | 6345 | const lhs_node, const rhs_node = tree.nodeData(node).node_and_node; |
| 6346 | const lhs = try expr(gz, scope, coerced_bool_ri, lhs_node); | ||
| 6465 | const bool_br = (try gz.addPlNodePayloadIndex(zir_tag, node, undefined)).toIndex().?; | 6347 | const bool_br = (try gz.addPlNodePayloadIndex(zir_tag, node, undefined)).toIndex().?; |
| 6466 | 6348 | ||
| 6467 | var rhs_scope = gz.makeSubBlock(scope); | 6349 | var rhs_scope = gz.makeSubBlock(scope); |
| 6468 | defer rhs_scope.unstack(); | 6350 | defer rhs_scope.unstack(); |
| 6469 | const rhs = try fullBodyExpr(&rhs_scope, &rhs_scope.base, coerced_bool_ri, node_datas[node].rhs, .allow_branch_hint); | 6351 | const rhs = try fullBodyExpr(&rhs_scope, &rhs_scope.base, coerced_bool_ri, rhs_node, .allow_branch_hint); |
| 6470 | if (!gz.refIsNoReturn(rhs)) { | 6352 | if (!gz.refIsNoReturn(rhs)) { |
| 6471 | _ = try rhs_scope.addBreakWithSrcNode(.break_inline, bool_br, rhs, node_datas[node].rhs); | 6353 | _ = try rhs_scope.addBreakWithSrcNode(.break_inline, bool_br, rhs, rhs_node); |
| 6472 | } | 6354 | } |
| 6473 | try rhs_scope.setBoolBrBody(bool_br, lhs); | 6355 | try rhs_scope.setBoolBrBody(bool_br, lhs); |
| 6474 | 6356 | ||
| ... | @@ -6485,7 +6367,6 @@ fn ifExpr( | ... | @@ -6485,7 +6367,6 @@ fn ifExpr( |
| 6485 | ) InnerError!Zir.Inst.Ref { | 6367 | ) InnerError!Zir.Inst.Ref { |
| 6486 | const astgen = parent_gz.astgen; | 6368 | const astgen = parent_gz.astgen; |
| 6487 | const tree = astgen.tree; | 6369 | const tree = astgen.tree; |
| 6488 | const token_tags = tree.tokens.items(.tag); | ||
| 6489 | 6370 | ||
| 6490 | const do_err_trace = astgen.fn_block != null and if_full.error_token != null; | 6371 | const do_err_trace = astgen.fn_block != null and if_full.error_token != null; |
| 6491 | 6372 | ||
| ... | @@ -6508,7 +6389,7 @@ fn ifExpr( | ... | @@ -6508,7 +6389,7 @@ fn ifExpr( |
| 6508 | defer block_scope.unstack(); | 6389 | defer block_scope.unstack(); |
| 6509 | 6390 | ||
| 6510 | const payload_is_ref = if (if_full.payload_token) |payload_token| | 6391 | const payload_is_ref = if (if_full.payload_token) |payload_token| |
| 6511 | token_tags[payload_token] == .asterisk | 6392 | tree.tokenTag(payload_token) == .asterisk |
| 6512 | else | 6393 | else |
| 6513 | false; | 6394 | false; |
| 6514 | 6395 | ||
| ... | @@ -6586,7 +6467,7 @@ fn ifExpr( | ... | @@ -6586,7 +6467,7 @@ fn ifExpr( |
| 6586 | break :s &then_scope.base; | 6467 | break :s &then_scope.base; |
| 6587 | } | 6468 | } |
| 6588 | } else if (if_full.payload_token) |payload_token| { | 6469 | } else if (if_full.payload_token) |payload_token| { |
| 6589 | const ident_token = if (payload_is_ref) payload_token + 1 else payload_token; | 6470 | const ident_token = payload_token + @intFromBool(payload_is_ref); |
| 6590 | const tag: Zir.Inst.Tag = if (payload_is_ref) | 6471 | const tag: Zir.Inst.Tag = if (payload_is_ref) |
| 6591 | .optional_payload_unsafe_ptr | 6472 | .optional_payload_unsafe_ptr |
| 6592 | else | 6473 | else |
| ... | @@ -6628,8 +6509,7 @@ fn ifExpr( | ... | @@ -6628,8 +6509,7 @@ fn ifExpr( |
| 6628 | if (do_err_trace and nodeMayAppendToErrorTrace(tree, if_full.ast.cond_expr)) | 6509 | if (do_err_trace and nodeMayAppendToErrorTrace(tree, if_full.ast.cond_expr)) |
| 6629 | _ = try else_scope.addSaveErrRetIndex(.always); | 6510 | _ = try else_scope.addSaveErrRetIndex(.always); |
| 6630 | 6511 | ||
| 6631 | const else_node = if_full.ast.else_expr; | 6512 | if (if_full.ast.else_expr.unwrap()) |else_node| { |
| 6632 | if (else_node != 0) { | ||
| 6633 | const sub_scope = s: { | 6513 | const sub_scope = s: { |
| 6634 | if (if_full.error_token) |error_token| { | 6514 | if (if_full.error_token) |error_token| { |
| 6635 | const tag: Zir.Inst.Tag = if (payload_is_ref) | 6515 | const tag: Zir.Inst.Tag = if (payload_is_ref) |
| ... | @@ -6717,8 +6597,6 @@ fn whileExpr( | ... | @@ -6717,8 +6597,6 @@ fn whileExpr( |
| 6717 | ) InnerError!Zir.Inst.Ref { | 6597 | ) InnerError!Zir.Inst.Ref { |
| 6718 | const astgen = parent_gz.astgen; | 6598 | const astgen = parent_gz.astgen; |
| 6719 | const tree = astgen.tree; | 6599 | const tree = astgen.tree; |
| 6720 | const token_tags = tree.tokens.items(.tag); | ||
| 6721 | const token_starts = tree.tokens.items(.start); | ||
| 6722 | 6600 | ||
| 6723 | const need_rl = astgen.nodes_need_rl.contains(node); | 6601 | const need_rl = astgen.nodes_need_rl.contains(node); |
| 6724 | const block_ri: ResultInfo = if (need_rl) ri else .{ | 6602 | const block_ri: ResultInfo = if (need_rl) ri else .{ |
| ... | @@ -6755,7 +6633,7 @@ fn whileExpr( | ... | @@ -6755,7 +6633,7 @@ fn whileExpr( |
| 6755 | defer cond_scope.unstack(); | 6633 | defer cond_scope.unstack(); |
| 6756 | 6634 | ||
| 6757 | const payload_is_ref = if (while_full.payload_token) |payload_token| | 6635 | const payload_is_ref = if (while_full.payload_token) |payload_token| |
| 6758 | token_tags[payload_token] == .asterisk | 6636 | tree.tokenTag(payload_token) == .asterisk |
| 6759 | else | 6637 | else |
| 6760 | false; | 6638 | false; |
| 6761 | 6639 | ||
| ... | @@ -6841,7 +6719,6 @@ fn whileExpr( | ... | @@ -6841,7 +6719,6 @@ fn whileExpr( |
| 6841 | break :s &then_scope.base; | 6719 | break :s &then_scope.base; |
| 6842 | } | 6720 | } |
| 6843 | } else if (while_full.payload_token) |payload_token| { | 6721 | } else if (while_full.payload_token) |payload_token| { |
| 6844 | const ident_token = if (payload_is_ref) payload_token + 1 else payload_token; | ||
| 6845 | const tag: Zir.Inst.Tag = if (payload_is_ref) | 6722 | const tag: Zir.Inst.Tag = if (payload_is_ref) |
| 6846 | .optional_payload_unsafe_ptr | 6723 | .optional_payload_unsafe_ptr |
| 6847 | else | 6724 | else |
| ... | @@ -6849,6 +6726,7 @@ fn whileExpr( | ... | @@ -6849,6 +6726,7 @@ fn whileExpr( |
| 6849 | // will add this instruction to then_scope.instructions below | 6726 | // will add this instruction to then_scope.instructions below |
| 6850 | const payload_inst = try then_scope.makeUnNode(tag, cond.inst, while_full.ast.cond_expr); | 6727 | const payload_inst = try then_scope.makeUnNode(tag, cond.inst, while_full.ast.cond_expr); |
| 6851 | opt_payload_inst = payload_inst.toOptional(); | 6728 | opt_payload_inst = payload_inst.toOptional(); |
| 6729 | const ident_token = payload_token + @intFromBool(payload_is_ref); | ||
| 6852 | const ident_name = try astgen.identAsString(ident_token); | 6730 | const ident_name = try astgen.identAsString(ident_token); |
| 6853 | const ident_bytes = tree.tokenSlice(ident_token); | 6731 | const ident_bytes = tree.tokenSlice(ident_token); |
| 6854 | if (mem.eql(u8, "_", ident_bytes)) { | 6732 | if (mem.eql(u8, "_", ident_bytes)) { |
| ... | @@ -6903,8 +6781,8 @@ fn whileExpr( | ... | @@ -6903,8 +6781,8 @@ fn whileExpr( |
| 6903 | // are no jumps to it. This happens when the last statement of a while body is noreturn | 6781 | // are no jumps to it. This happens when the last statement of a while body is noreturn |
| 6904 | // and there are no `continue` statements. | 6782 | // and there are no `continue` statements. |
| 6905 | // Tracking issue: https://github.com/ziglang/zig/issues/9185 | 6783 | // Tracking issue: https://github.com/ziglang/zig/issues/9185 |
| 6906 | if (while_full.ast.cont_expr != 0) { | 6784 | if (while_full.ast.cont_expr.unwrap()) |cont_expr| { |
| 6907 | _ = try unusedResultExpr(&then_scope, then_sub_scope, while_full.ast.cont_expr); | 6785 | _ = try unusedResultExpr(&then_scope, then_sub_scope, cont_expr); |
| 6908 | } | 6786 | } |
| 6909 | 6787 | ||
| 6910 | continue_scope.instructions_top = continue_scope.instructions.items.len; | 6788 | continue_scope.instructions_top = continue_scope.instructions.items.len; |
| ... | @@ -6916,7 +6794,7 @@ fn whileExpr( | ... | @@ -6916,7 +6794,7 @@ fn whileExpr( |
| 6916 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); | 6794 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| 6917 | const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break"; | 6795 | const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break"; |
| 6918 | if (!continue_scope.endsWithNoReturn()) { | 6796 | if (!continue_scope.endsWithNoReturn()) { |
| 6919 | astgen.advanceSourceCursor(token_starts[tree.lastToken(then_node)]); | 6797 | astgen.advanceSourceCursor(tree.tokenStart(tree.lastToken(then_node))); |
| 6920 | try emitDbgStmt(parent_gz, .{ astgen.source_line - parent_gz.decl_line, astgen.source_column }); | 6798 | try emitDbgStmt(parent_gz, .{ astgen.source_line - parent_gz.decl_line, astgen.source_column }); |
| 6921 | _ = try parent_gz.add(.{ | 6799 | _ = try parent_gz.add(.{ |
| 6922 | .tag = .extended, | 6800 | .tag = .extended, |
| ... | @@ -6934,8 +6812,7 @@ fn whileExpr( | ... | @@ -6934,8 +6812,7 @@ fn whileExpr( |
| 6934 | var else_scope = parent_gz.makeSubBlock(&cond_scope.base); | 6812 | var else_scope = parent_gz.makeSubBlock(&cond_scope.base); |
| 6935 | defer else_scope.unstack(); | 6813 | defer else_scope.unstack(); |
| 6936 | 6814 | ||
| 6937 | const else_node = while_full.ast.else_expr; | 6815 | if (while_full.ast.else_expr.unwrap()) |else_node| { |
| 6938 | if (else_node != 0) { | ||
| 6939 | const sub_scope = s: { | 6816 | const sub_scope = s: { |
| 6940 | if (while_full.error_token) |error_token| { | 6817 | if (while_full.error_token) |error_token| { |
| 6941 | const tag: Zir.Inst.Tag = if (payload_is_ref) | 6818 | const tag: Zir.Inst.Tag = if (payload_is_ref) |
| ... | @@ -7033,10 +6910,6 @@ fn forExpr( | ... | @@ -7033,10 +6910,6 @@ fn forExpr( |
| 7033 | try astgen.appendErrorTok(for_full.inline_token.?, "redundant inline keyword in comptime scope", .{}); | 6910 | try astgen.appendErrorTok(for_full.inline_token.?, "redundant inline keyword in comptime scope", .{}); |
| 7034 | } | 6911 | } |
| 7035 | const tree = astgen.tree; | 6912 | const tree = astgen.tree; |
| 7036 | const token_tags = tree.tokens.items(.tag); | ||
| 7037 | const token_starts = tree.tokens.items(.start); | ||
| 7038 | const node_tags = tree.nodes.items(.tag); | ||
| 7039 | const node_data = tree.nodes.items(.data); | ||
| 7040 | const gpa = astgen.gpa; | 6913 | const gpa = astgen.gpa; |
| 7041 | 6914 | ||
| 7042 | // For counters, this is the start value; for indexables, this is the base | 6915 | // For counters, this is the start value; for indexables, this is the base |
| ... | @@ -7066,7 +6939,7 @@ fn forExpr( | ... | @@ -7066,7 +6939,7 @@ fn forExpr( |
| 7066 | { | 6939 | { |
| 7067 | var capture_token = for_full.payload_token; | 6940 | var capture_token = for_full.payload_token; |
| 7068 | for (for_full.ast.inputs, indexables, lens) |input, *indexable_ref, *len_refs| { | 6941 | for (for_full.ast.inputs, indexables, lens) |input, *indexable_ref, *len_refs| { |
| 7069 | const capture_is_ref = token_tags[capture_token] == .asterisk; | 6942 | const capture_is_ref = tree.tokenTag(capture_token) == .asterisk; |
| 7070 | const ident_tok = capture_token + @intFromBool(capture_is_ref); | 6943 | const ident_tok = capture_token + @intFromBool(capture_is_ref); |
| 7071 | const is_discard = mem.eql(u8, tree.tokenSlice(ident_tok), "_"); | 6944 | const is_discard = mem.eql(u8, tree.tokenSlice(ident_tok), "_"); |
| 7072 | 6945 | ||
| ... | @@ -7077,16 +6950,15 @@ fn forExpr( | ... | @@ -7077,16 +6950,15 @@ fn forExpr( |
| 7077 | capture_token = ident_tok + 2; | 6950 | capture_token = ident_tok + 2; |
| 7078 | 6951 | ||
| 7079 | try emitDbgNode(parent_gz, input); | 6952 | try emitDbgNode(parent_gz, input); |
| 7080 | if (node_tags[input] == .for_range) { | 6953 | if (tree.nodeTag(input) == .for_range) { |
| 7081 | if (capture_is_ref) { | 6954 | if (capture_is_ref) { |
| 7082 | return astgen.failTok(ident_tok, "cannot capture reference to range", .{}); | 6955 | return astgen.failTok(ident_tok, "cannot capture reference to range", .{}); |
| 7083 | } | 6956 | } |
| 7084 | const start_node = node_data[input].lhs; | 6957 | const start_node, const end_node = tree.nodeData(input).node_and_opt_node; |
| 7085 | const start_val = try expr(parent_gz, scope, .{ .rl = .{ .ty = .usize_type } }, start_node); | 6958 | const start_val = try expr(parent_gz, scope, .{ .rl = .{ .ty = .usize_type } }, start_node); |
| 7086 | 6959 | ||
| 7087 | const end_node = node_data[input].rhs; | 6960 | const end_val = if (end_node.unwrap()) |end| |
| 7088 | const end_val = if (end_node != 0) | 6961 | try expr(parent_gz, scope, .{ .rl = .{ .ty = .usize_type } }, end) |
| 7089 | try expr(parent_gz, scope, .{ .rl = .{ .ty = .usize_type } }, node_data[input].rhs) | ||
| 7090 | else | 6962 | else |
| 7091 | .none; | 6963 | .none; |
| 7092 | 6964 | ||
| ... | @@ -7179,7 +7051,7 @@ fn forExpr( | ... | @@ -7179,7 +7051,7 @@ fn forExpr( |
| 7179 | var capture_token = for_full.payload_token; | 7051 | var capture_token = for_full.payload_token; |
| 7180 | var capture_sub_scope: *Scope = &then_scope.base; | 7052 | var capture_sub_scope: *Scope = &then_scope.base; |
| 7181 | for (for_full.ast.inputs, indexables, capture_scopes) |input, indexable_ref, *capture_scope| { | 7053 | for (for_full.ast.inputs, indexables, capture_scopes) |input, indexable_ref, *capture_scope| { |
| 7182 | const capture_is_ref = token_tags[capture_token] == .asterisk; | 7054 | const capture_is_ref = tree.tokenTag(capture_token) == .asterisk; |
| 7183 | const ident_tok = capture_token + @intFromBool(capture_is_ref); | 7055 | const ident_tok = capture_token + @intFromBool(capture_is_ref); |
| 7184 | const capture_name = tree.tokenSlice(ident_tok); | 7056 | const capture_name = tree.tokenSlice(ident_tok); |
| 7185 | // Skip over the comma, and on to the next capture (or the ending pipe character). | 7057 | // Skip over the comma, and on to the next capture (or the ending pipe character). |
| ... | @@ -7191,7 +7063,7 @@ fn forExpr( | ... | @@ -7191,7 +7063,7 @@ fn forExpr( |
| 7191 | try astgen.detectLocalShadowing(capture_sub_scope, name_str_index, ident_tok, capture_name, .capture); | 7063 | try astgen.detectLocalShadowing(capture_sub_scope, name_str_index, ident_tok, capture_name, .capture); |
| 7192 | 7064 | ||
| 7193 | const capture_inst = inst: { | 7065 | const capture_inst = inst: { |
| 7194 | const is_counter = node_tags[input] == .for_range; | 7066 | const is_counter = tree.nodeTag(input) == .for_range; |
| 7195 | 7067 | ||
| 7196 | if (indexable_ref == .none) { | 7068 | if (indexable_ref == .none) { |
| 7197 | // Special case: the main index can be used directly. | 7069 | // Special case: the main index can be used directly. |
| ... | @@ -7238,7 +7110,7 @@ fn forExpr( | ... | @@ -7238,7 +7110,7 @@ fn forExpr( |
| 7238 | 7110 | ||
| 7239 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); | 7111 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| 7240 | 7112 | ||
| 7241 | astgen.advanceSourceCursor(token_starts[tree.lastToken(then_node)]); | 7113 | astgen.advanceSourceCursor(tree.tokenStart(tree.lastToken(then_node))); |
| 7242 | try emitDbgStmt(parent_gz, .{ astgen.source_line - parent_gz.decl_line, astgen.source_column }); | 7114 | try emitDbgStmt(parent_gz, .{ astgen.source_line - parent_gz.decl_line, astgen.source_column }); |
| 7243 | _ = try parent_gz.add(.{ | 7115 | _ = try parent_gz.add(.{ |
| 7244 | .tag = .extended, | 7116 | .tag = .extended, |
| ... | @@ -7255,8 +7127,7 @@ fn forExpr( | ... | @@ -7255,8 +7127,7 @@ fn forExpr( |
| 7255 | var else_scope = parent_gz.makeSubBlock(&cond_scope.base); | 7127 | var else_scope = parent_gz.makeSubBlock(&cond_scope.base); |
| 7256 | defer else_scope.unstack(); | 7128 | defer else_scope.unstack(); |
| 7257 | 7129 | ||
| 7258 | const else_node = for_full.ast.else_expr; | 7130 | if (for_full.ast.else_expr.unwrap()) |else_node| { |
| 7259 | if (else_node != 0) { | ||
| 7260 | const sub_scope = &else_scope.base; | 7131 | const sub_scope = &else_scope.base; |
| 7261 | // Remove the continue block and break block so that `continue` and `break` | 7132 | // Remove the continue block and break block so that `continue` and `break` |
| 7262 | // control flow apply to outer loops; not this one. | 7133 | // control flow apply to outer loops; not this one. |
| ... | @@ -7324,10 +7195,6 @@ fn switchExprErrUnion( | ... | @@ -7324,10 +7195,6 @@ fn switchExprErrUnion( |
| 7324 | const astgen = parent_gz.astgen; | 7195 | const astgen = parent_gz.astgen; |
| 7325 | const gpa = astgen.gpa; | 7196 | const gpa = astgen.gpa; |
| 7326 | const tree = astgen.tree; | 7197 | const tree = astgen.tree; |
| 7327 | const node_datas = tree.nodes.items(.data); | ||
| 7328 | const node_tags = tree.nodes.items(.tag); | ||
| 7329 | const main_tokens = tree.nodes.items(.main_token); | ||
| 7330 | const token_tags = tree.tokens.items(.tag); | ||
| 7331 | 7198 | ||
| 7332 | const if_full = switch (node_ty) { | 7199 | const if_full = switch (node_ty) { |
| 7333 | .@"catch" => undefined, | 7200 | .@"catch" => undefined, |
| ... | @@ -7336,23 +7203,19 @@ fn switchExprErrUnion( | ... | @@ -7336,23 +7203,19 @@ fn switchExprErrUnion( |
| 7336 | 7203 | ||
| 7337 | const switch_node, const operand_node, const error_payload = switch (node_ty) { | 7204 | const switch_node, const operand_node, const error_payload = switch (node_ty) { |
| 7338 | .@"catch" => .{ | 7205 | .@"catch" => .{ |
| 7339 | node_datas[catch_or_if_node].rhs, | 7206 | tree.nodeData(catch_or_if_node).node_and_node[1], |
| 7340 | node_datas[catch_or_if_node].lhs, | 7207 | tree.nodeData(catch_or_if_node).node_and_node[0], |
| 7341 | main_tokens[catch_or_if_node] + 2, | 7208 | tree.nodeMainToken(catch_or_if_node) + 2, |
| 7342 | }, | 7209 | }, |
| 7343 | .@"if" => .{ | 7210 | .@"if" => .{ |
| 7344 | if_full.ast.else_expr, | 7211 | if_full.ast.else_expr.unwrap().?, |
| 7345 | if_full.ast.cond_expr, | 7212 | if_full.ast.cond_expr, |
| 7346 | if_full.error_token.?, | 7213 | if_full.error_token.?, |
| 7347 | }, | 7214 | }, |
| 7348 | }; | 7215 | }; |
| 7349 | assert(node_tags[switch_node] == .@"switch" or node_tags[switch_node] == .switch_comma); | 7216 | const switch_full = tree.fullSwitch(switch_node).?; |
| 7350 | 7217 | ||
| 7351 | const do_err_trace = astgen.fn_block != null; | 7218 | const do_err_trace = astgen.fn_block != null; |
| 7352 | |||
| 7353 | const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange); | ||
| 7354 | const case_nodes = tree.extra_data[extra.start..extra.end]; | ||
| 7355 | |||
| 7356 | const need_rl = astgen.nodes_need_rl.contains(catch_or_if_node); | 7219 | const need_rl = astgen.nodes_need_rl.contains(catch_or_if_node); |
| 7357 | const block_ri: ResultInfo = if (need_rl) ri else .{ | 7220 | const block_ri: ResultInfo = if (need_rl) ri else .{ |
| 7358 | .rl = switch (ri.rl) { | 7221 | .rl = switch (ri.rl) { |
| ... | @@ -7364,7 +7227,7 @@ fn switchExprErrUnion( | ... | @@ -7364,7 +7227,7 @@ fn switchExprErrUnion( |
| 7364 | }; | 7227 | }; |
| 7365 | 7228 | ||
| 7366 | const payload_is_ref = switch (node_ty) { | 7229 | const payload_is_ref = switch (node_ty) { |
| 7367 | .@"if" => if_full.payload_token != null and token_tags[if_full.payload_token.?] == .asterisk, | 7230 | .@"if" => if_full.payload_token != null and tree.tokenTag(if_full.payload_token.?) == .asterisk, |
| 7368 | .@"catch" => ri.rl == .ref or ri.rl == .ref_coerced_ty, | 7231 | .@"catch" => ri.rl == .ref or ri.rl == .ref_coerced_ty, |
| 7369 | }; | 7232 | }; |
| 7370 | 7233 | ||
| ... | @@ -7376,9 +7239,9 @@ fn switchExprErrUnion( | ... | @@ -7376,9 +7239,9 @@ fn switchExprErrUnion( |
| 7376 | var multi_cases_len: u32 = 0; | 7239 | var multi_cases_len: u32 = 0; |
| 7377 | var inline_cases_len: u32 = 0; | 7240 | var inline_cases_len: u32 = 0; |
| 7378 | var has_else = false; | 7241 | var has_else = false; |
| 7379 | var else_node: Ast.Node.Index = 0; | 7242 | var else_node: Ast.Node.OptionalIndex = .none; |
| 7380 | var else_src: ?Ast.TokenIndex = null; | 7243 | var else_src: ?Ast.TokenIndex = null; |
| 7381 | for (case_nodes) |case_node| { | 7244 | for (switch_full.ast.cases) |case_node| { |
| 7382 | const case = tree.fullSwitchCase(case_node).?; | 7245 | const case = tree.fullSwitchCase(case_node).?; |
| 7383 | 7246 | ||
| 7384 | if (case.ast.values.len == 0) { | 7247 | if (case.ast.values.len == 0) { |
| ... | @@ -7398,12 +7261,12 @@ fn switchExprErrUnion( | ... | @@ -7398,12 +7261,12 @@ fn switchExprErrUnion( |
| 7398 | ); | 7261 | ); |
| 7399 | } | 7262 | } |
| 7400 | has_else = true; | 7263 | has_else = true; |
| 7401 | else_node = case_node; | 7264 | else_node = case_node.toOptional(); |
| 7402 | else_src = case_src; | 7265 | else_src = case_src; |
| 7403 | continue; | 7266 | continue; |
| 7404 | } else if (case.ast.values.len == 1 and | 7267 | } else if (case.ast.values.len == 1 and |
| 7405 | node_tags[case.ast.values[0]] == .identifier and | 7268 | tree.nodeTag(case.ast.values[0]) == .identifier and |
| 7406 | mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_")) | 7269 | mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(case.ast.values[0])), "_")) |
| 7407 | { | 7270 | { |
| 7408 | const case_src = case.ast.arrow_token - 1; | 7271 | const case_src = case.ast.arrow_token - 1; |
| 7409 | return astgen.failTokNotes( | 7272 | return astgen.failTokNotes( |
| ... | @@ -7421,11 +7284,11 @@ fn switchExprErrUnion( | ... | @@ -7421,11 +7284,11 @@ fn switchExprErrUnion( |
| 7421 | } | 7284 | } |
| 7422 | 7285 | ||
| 7423 | for (case.ast.values) |val| { | 7286 | for (case.ast.values) |val| { |
| 7424 | if (node_tags[val] == .string_literal) | 7287 | if (tree.nodeTag(val) == .string_literal) |
| 7425 | return astgen.failNode(val, "cannot switch on strings", .{}); | 7288 | return astgen.failNode(val, "cannot switch on strings", .{}); |
| 7426 | } | 7289 | } |
| 7427 | 7290 | ||
| 7428 | if (case.ast.values.len == 1 and node_tags[case.ast.values[0]] != .switch_range) { | 7291 | if (case.ast.values.len == 1 and tree.nodeTag(case.ast.values[0]) != .switch_range) { |
| 7429 | scalar_cases_len += 1; | 7292 | scalar_cases_len += 1; |
| 7430 | } else { | 7293 | } else { |
| 7431 | multi_cases_len += 1; | 7294 | multi_cases_len += 1; |
| ... | @@ -7618,11 +7481,11 @@ fn switchExprErrUnion( | ... | @@ -7618,11 +7481,11 @@ fn switchExprErrUnion( |
| 7618 | var multi_case_index: u32 = 0; | 7481 | var multi_case_index: u32 = 0; |
| 7619 | var scalar_case_index: u32 = 0; | 7482 | var scalar_case_index: u32 = 0; |
| 7620 | var any_uses_err_capture = false; | 7483 | var any_uses_err_capture = false; |
| 7621 | for (case_nodes) |case_node| { | 7484 | for (switch_full.ast.cases) |case_node| { |
| 7622 | const case = tree.fullSwitchCase(case_node).?; | 7485 | const case = tree.fullSwitchCase(case_node).?; |
| 7623 | 7486 | ||
| 7624 | const is_multi_case = case.ast.values.len > 1 or | 7487 | const is_multi_case = case.ast.values.len > 1 or |
| 7625 | (case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .switch_range); | 7488 | (case.ast.values.len == 1 and tree.nodeTag(case.ast.values[0]) == .switch_range); |
| 7626 | 7489 | ||
| 7627 | var dbg_var_name: Zir.NullTerminatedString = .empty; | 7490 | var dbg_var_name: Zir.NullTerminatedString = .empty; |
| 7628 | var dbg_var_inst: Zir.Inst.Ref = undefined; | 7491 | var dbg_var_inst: Zir.Inst.Ref = undefined; |
| ... | @@ -7640,7 +7503,7 @@ fn switchExprErrUnion( | ... | @@ -7640,7 +7503,7 @@ fn switchExprErrUnion( |
| 7640 | }; | 7503 | }; |
| 7641 | 7504 | ||
| 7642 | const capture_token = case.payload_token orelse break :blk &err_scope.base; | 7505 | const capture_token = case.payload_token orelse break :blk &err_scope.base; |
| 7643 | if (token_tags[capture_token] != .identifier) { | 7506 | if (tree.tokenTag(capture_token) != .identifier) { |
| 7644 | return astgen.failTok(capture_token + 1, "error set cannot be captured by reference", .{}); | 7507 | return astgen.failTok(capture_token + 1, "error set cannot be captured by reference", .{}); |
| 7645 | } | 7508 | } |
| 7646 | 7509 | ||
| ... | @@ -7676,7 +7539,7 @@ fn switchExprErrUnion( | ... | @@ -7676,7 +7539,7 @@ fn switchExprErrUnion( |
| 7676 | // items | 7539 | // items |
| 7677 | var items_len: u32 = 0; | 7540 | var items_len: u32 = 0; |
| 7678 | for (case.ast.values) |item_node| { | 7541 | for (case.ast.values) |item_node| { |
| 7679 | if (node_tags[item_node] == .switch_range) continue; | 7542 | if (tree.nodeTag(item_node) == .switch_range) continue; |
| 7680 | items_len += 1; | 7543 | items_len += 1; |
| 7681 | 7544 | ||
| 7682 | const item_inst = try comptimeExpr(parent_gz, scope, item_ri, item_node, .switch_item); | 7545 | const item_inst = try comptimeExpr(parent_gz, scope, item_ri, item_node, .switch_item); |
| ... | @@ -7686,11 +7549,12 @@ fn switchExprErrUnion( | ... | @@ -7686,11 +7549,12 @@ fn switchExprErrUnion( |
| 7686 | // ranges | 7549 | // ranges |
| 7687 | var ranges_len: u32 = 0; | 7550 | var ranges_len: u32 = 0; |
| 7688 | for (case.ast.values) |range| { | 7551 | for (case.ast.values) |range| { |
| 7689 | if (node_tags[range] != .switch_range) continue; | 7552 | if (tree.nodeTag(range) != .switch_range) continue; |
| 7690 | ranges_len += 1; | 7553 | ranges_len += 1; |
| 7691 | 7554 | ||
| 7692 | const first = try comptimeExpr(parent_gz, scope, item_ri, node_datas[range].lhs, .switch_item); | 7555 | const first_node, const last_node = tree.nodeData(range).node_and_node; |
| 7693 | const last = try comptimeExpr(parent_gz, scope, item_ri, node_datas[range].rhs, .switch_item); | 7556 | const first = try comptimeExpr(parent_gz, scope, item_ri, first_node, .switch_item); |
| 7557 | const last = try comptimeExpr(parent_gz, scope, item_ri, last_node, .switch_item); | ||
| 7694 | try payloads.appendSlice(gpa, &[_]u32{ | 7558 | try payloads.appendSlice(gpa, &[_]u32{ |
| 7695 | @intFromEnum(first), @intFromEnum(last), | 7559 | @intFromEnum(first), @intFromEnum(last), |
| 7696 | }); | 7560 | }); |
| ... | @@ -7699,7 +7563,7 @@ fn switchExprErrUnion( | ... | @@ -7699,7 +7563,7 @@ fn switchExprErrUnion( |
| 7699 | payloads.items[header_index] = items_len; | 7563 | payloads.items[header_index] = items_len; |
| 7700 | payloads.items[header_index + 1] = ranges_len; | 7564 | payloads.items[header_index + 1] = ranges_len; |
| 7701 | break :blk header_index + 2; | 7565 | break :blk header_index + 2; |
| 7702 | } else if (case_node == else_node) blk: { | 7566 | } else if (case_node.toOptional() == else_node) blk: { |
| 7703 | payloads.items[case_table_start + 1] = header_index; | 7567 | payloads.items[case_table_start + 1] = header_index; |
| 7704 | try payloads.resize(gpa, header_index + 1); // body_len | 7568 | try payloads.resize(gpa, header_index + 1); // body_len |
| 7705 | break :blk header_index; | 7569 | break :blk header_index; |
| ... | @@ -7729,7 +7593,7 @@ fn switchExprErrUnion( | ... | @@ -7729,7 +7593,7 @@ fn switchExprErrUnion( |
| 7729 | const case_result = try fullBodyExpr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node, .allow_branch_hint); | 7593 | const case_result = try fullBodyExpr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node, .allow_branch_hint); |
| 7730 | // check capture_scope, not err_scope to avoid false positive unused error capture | 7594 | // check capture_scope, not err_scope to avoid false positive unused error capture |
| 7731 | try checkUsed(parent_gz, &case_scope.base, err_scope.parent); | 7595 | try checkUsed(parent_gz, &case_scope.base, err_scope.parent); |
| 7732 | const uses_err = err_scope.used != 0 or err_scope.discarded != 0; | 7596 | const uses_err = err_scope.used != .none or err_scope.discarded != .none; |
| 7733 | if (uses_err) { | 7597 | if (uses_err) { |
| 7734 | try case_scope.addDbgVar(.dbg_var_val, err_name, err_inst.toRef()); | 7598 | try case_scope.addDbgVar(.dbg_var_val, err_name, err_inst.toRef()); |
| 7735 | any_uses_err_capture = true; | 7599 | any_uses_err_capture = true; |
| ... | @@ -7829,10 +7693,6 @@ fn switchExpr( | ... | @@ -7829,10 +7693,6 @@ fn switchExpr( |
| 7829 | const astgen = parent_gz.astgen; | 7693 | const astgen = parent_gz.astgen; |
| 7830 | const gpa = astgen.gpa; | 7694 | const gpa = astgen.gpa; |
| 7831 | const tree = astgen.tree; | 7695 | const tree = astgen.tree; |
| 7832 | const node_datas = tree.nodes.items(.data); | ||
| 7833 | const node_tags = tree.nodes.items(.tag); | ||
| 7834 | const main_tokens = tree.nodes.items(.main_token); | ||
| 7835 | const token_tags = tree.tokens.items(.tag); | ||
| 7836 | const operand_node = switch_full.ast.condition; | 7696 | const operand_node = switch_full.ast.condition; |
| 7837 | const case_nodes = switch_full.ast.cases; | 7697 | const case_nodes = switch_full.ast.cases; |
| 7838 | 7698 | ||
| ... | @@ -7864,17 +7724,17 @@ fn switchExpr( | ... | @@ -7864,17 +7724,17 @@ fn switchExpr( |
| 7864 | var multi_cases_len: u32 = 0; | 7724 | var multi_cases_len: u32 = 0; |
| 7865 | var inline_cases_len: u32 = 0; | 7725 | var inline_cases_len: u32 = 0; |
| 7866 | var special_prong: Zir.SpecialProng = .none; | 7726 | var special_prong: Zir.SpecialProng = .none; |
| 7867 | var special_node: Ast.Node.Index = 0; | 7727 | var special_node: Ast.Node.OptionalIndex = .none; |
| 7868 | var else_src: ?Ast.TokenIndex = null; | 7728 | var else_src: ?Ast.TokenIndex = null; |
| 7869 | var underscore_src: ?Ast.TokenIndex = null; | 7729 | var underscore_src: ?Ast.TokenIndex = null; |
| 7870 | for (case_nodes) |case_node| { | 7730 | for (case_nodes) |case_node| { |
| 7871 | const case = tree.fullSwitchCase(case_node).?; | 7731 | const case = tree.fullSwitchCase(case_node).?; |
| 7872 | if (case.payload_token) |payload_token| { | 7732 | if (case.payload_token) |payload_token| { |
| 7873 | const ident = if (token_tags[payload_token] == .asterisk) blk: { | 7733 | const ident = if (tree.tokenTag(payload_token) == .asterisk) blk: { |
| 7874 | any_payload_is_ref = true; | 7734 | any_payload_is_ref = true; |
| 7875 | break :blk payload_token + 1; | 7735 | break :blk payload_token + 1; |
| 7876 | } else payload_token; | 7736 | } else payload_token; |
| 7877 | if (token_tags[ident + 1] == .comma) { | 7737 | if (tree.tokenTag(ident + 1) == .comma) { |
| 7878 | any_has_tag_capture = true; | 7738 | any_has_tag_capture = true; |
| 7879 | } | 7739 | } |
| 7880 | 7740 | ||
| ... | @@ -7922,13 +7782,13 @@ fn switchExpr( | ... | @@ -7922,13 +7782,13 @@ fn switchExpr( |
| 7922 | }, | 7782 | }, |
| 7923 | ); | 7783 | ); |
| 7924 | } | 7784 | } |
| 7925 | special_node = case_node; | 7785 | special_node = case_node.toOptional(); |
| 7926 | special_prong = .@"else"; | 7786 | special_prong = .@"else"; |
| 7927 | else_src = case_src; | 7787 | else_src = case_src; |
| 7928 | continue; | 7788 | continue; |
| 7929 | } else if (case.ast.values.len == 1 and | 7789 | } else if (case.ast.values.len == 1 and |
| 7930 | node_tags[case.ast.values[0]] == .identifier and | 7790 | tree.nodeTag(case.ast.values[0]) == .identifier and |
| 7931 | mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_")) | 7791 | mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(case.ast.values[0])), "_")) |
| 7932 | { | 7792 | { |
| 7933 | const case_src = case.ast.arrow_token - 1; | 7793 | const case_src = case.ast.arrow_token - 1; |
| 7934 | if (underscore_src) |src| { | 7794 | if (underscore_src) |src| { |
| ... | @@ -7966,18 +7826,18 @@ fn switchExpr( | ... | @@ -7966,18 +7826,18 @@ fn switchExpr( |
| 7966 | if (case.inline_token != null) { | 7826 | if (case.inline_token != null) { |
| 7967 | return astgen.failTok(case_src, "cannot inline '_' prong", .{}); | 7827 | return astgen.failTok(case_src, "cannot inline '_' prong", .{}); |
| 7968 | } | 7828 | } |
| 7969 | special_node = case_node; | 7829 | special_node = case_node.toOptional(); |
| 7970 | special_prong = .under; | 7830 | special_prong = .under; |
| 7971 | underscore_src = case_src; | 7831 | underscore_src = case_src; |
| 7972 | continue; | 7832 | continue; |
| 7973 | } | 7833 | } |
| 7974 | 7834 | ||
| 7975 | for (case.ast.values) |val| { | 7835 | for (case.ast.values) |val| { |
| 7976 | if (node_tags[val] == .string_literal) | 7836 | if (tree.nodeTag(val) == .string_literal) |
| 7977 | return astgen.failNode(val, "cannot switch on strings", .{}); | 7837 | return astgen.failNode(val, "cannot switch on strings", .{}); |
| 7978 | } | 7838 | } |
| 7979 | 7839 | ||
| 7980 | if (case.ast.values.len == 1 and node_tags[case.ast.values[0]] != .switch_range) { | 7840 | if (case.ast.values.len == 1 and tree.nodeTag(case.ast.values[0]) != .switch_range) { |
| 7981 | scalar_cases_len += 1; | 7841 | scalar_cases_len += 1; |
| 7982 | } else { | 7842 | } else { |
| 7983 | multi_cases_len += 1; | 7843 | multi_cases_len += 1; |
| ... | @@ -8066,7 +7926,7 @@ fn switchExpr( | ... | @@ -8066,7 +7926,7 @@ fn switchExpr( |
| 8066 | const case = tree.fullSwitchCase(case_node).?; | 7926 | const case = tree.fullSwitchCase(case_node).?; |
| 8067 | 7927 | ||
| 8068 | const is_multi_case = case.ast.values.len > 1 or | 7928 | const is_multi_case = case.ast.values.len > 1 or |
| 8069 | (case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .switch_range); | 7929 | (case.ast.values.len == 1 and tree.nodeTag(case.ast.values[0]) == .switch_range); |
| 8070 | 7930 | ||
| 8071 | var dbg_var_name: Zir.NullTerminatedString = .empty; | 7931 | var dbg_var_name: Zir.NullTerminatedString = .empty; |
| 8072 | var dbg_var_inst: Zir.Inst.Ref = undefined; | 7932 | var dbg_var_inst: Zir.Inst.Ref = undefined; |
| ... | @@ -8080,18 +7940,15 @@ fn switchExpr( | ... | @@ -8080,18 +7940,15 @@ fn switchExpr( |
| 8080 | 7940 | ||
| 8081 | const sub_scope = blk: { | 7941 | const sub_scope = blk: { |
| 8082 | const payload_token = case.payload_token orelse break :blk &case_scope.base; | 7942 | const payload_token = case.payload_token orelse break :blk &case_scope.base; |
| 8083 | const ident = if (token_tags[payload_token] == .asterisk) | 7943 | const capture_is_ref = tree.tokenTag(payload_token) == .asterisk; |
| 8084 | payload_token + 1 | 7944 | const ident = payload_token + @intFromBool(capture_is_ref); |
| 8085 | else | ||
| 8086 | payload_token; | ||
| 8087 | 7945 | ||
| 8088 | const is_ptr = ident != payload_token; | 7946 | capture = if (capture_is_ref) .by_ref else .by_val; |
| 8089 | capture = if (is_ptr) .by_ref else .by_val; | ||
| 8090 | 7947 | ||
| 8091 | const ident_slice = tree.tokenSlice(ident); | 7948 | const ident_slice = tree.tokenSlice(ident); |
| 8092 | var payload_sub_scope: *Scope = undefined; | 7949 | var payload_sub_scope: *Scope = undefined; |
| 8093 | if (mem.eql(u8, ident_slice, "_")) { | 7950 | if (mem.eql(u8, ident_slice, "_")) { |
| 8094 | if (is_ptr) { | 7951 | if (capture_is_ref) { |
| 8095 | return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{}); | 7952 | return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{}); |
| 8096 | } | 7953 | } |
| 8097 | payload_sub_scope = &case_scope.base; | 7954 | payload_sub_scope = &case_scope.base; |
| ... | @@ -8111,7 +7968,7 @@ fn switchExpr( | ... | @@ -8111,7 +7968,7 @@ fn switchExpr( |
| 8111 | payload_sub_scope = &capture_val_scope.base; | 7968 | payload_sub_scope = &capture_val_scope.base; |
| 8112 | } | 7969 | } |
| 8113 | 7970 | ||
| 8114 | const tag_token = if (token_tags[ident + 1] == .comma) | 7971 | const tag_token = if (tree.tokenTag(ident + 1) == .comma) |
| 8115 | ident + 2 | 7972 | ident + 2 |
| 8116 | else | 7973 | else |
| 8117 | break :blk payload_sub_scope; | 7974 | break :blk payload_sub_scope; |
| ... | @@ -8149,7 +8006,7 @@ fn switchExpr( | ... | @@ -8149,7 +8006,7 @@ fn switchExpr( |
| 8149 | // items | 8006 | // items |
| 8150 | var items_len: u32 = 0; | 8007 | var items_len: u32 = 0; |
| 8151 | for (case.ast.values) |item_node| { | 8008 | for (case.ast.values) |item_node| { |
| 8152 | if (node_tags[item_node] == .switch_range) continue; | 8009 | if (tree.nodeTag(item_node) == .switch_range) continue; |
| 8153 | items_len += 1; | 8010 | items_len += 1; |
| 8154 | 8011 | ||
| 8155 | const item_inst = try comptimeExpr(parent_gz, scope, item_ri, item_node, .switch_item); | 8012 | const item_inst = try comptimeExpr(parent_gz, scope, item_ri, item_node, .switch_item); |
| ... | @@ -8159,11 +8016,12 @@ fn switchExpr( | ... | @@ -8159,11 +8016,12 @@ fn switchExpr( |
| 8159 | // ranges | 8016 | // ranges |
| 8160 | var ranges_len: u32 = 0; | 8017 | var ranges_len: u32 = 0; |
| 8161 | for (case.ast.values) |range| { | 8018 | for (case.ast.values) |range| { |
| 8162 | if (node_tags[range] != .switch_range) continue; | 8019 | if (tree.nodeTag(range) != .switch_range) continue; |
| 8163 | ranges_len += 1; | 8020 | ranges_len += 1; |
| 8164 | 8021 | ||
| 8165 | const first = try comptimeExpr(parent_gz, scope, item_ri, node_datas[range].lhs, .switch_item); | 8022 | const first_node, const last_node = tree.nodeData(range).node_and_node; |
| 8166 | const last = try comptimeExpr(parent_gz, scope, item_ri, node_datas[range].rhs, .switch_item); | 8023 | const first = try comptimeExpr(parent_gz, scope, item_ri, first_node, .switch_item); |
| 8024 | const last = try comptimeExpr(parent_gz, scope, item_ri, last_node, .switch_item); | ||
| 8167 | try payloads.appendSlice(gpa, &[_]u32{ | 8025 | try payloads.appendSlice(gpa, &[_]u32{ |
| 8168 | @intFromEnum(first), @intFromEnum(last), | 8026 | @intFromEnum(first), @intFromEnum(last), |
| 8169 | }); | 8027 | }); |
| ... | @@ -8172,7 +8030,7 @@ fn switchExpr( | ... | @@ -8172,7 +8030,7 @@ fn switchExpr( |
| 8172 | payloads.items[header_index] = items_len; | 8030 | payloads.items[header_index] = items_len; |
| 8173 | payloads.items[header_index + 1] = ranges_len; | 8031 | payloads.items[header_index + 1] = ranges_len; |
| 8174 | break :blk header_index + 2; | 8032 | break :blk header_index + 2; |
| 8175 | } else if (case_node == special_node) blk: { | 8033 | } else if (case_node.toOptional() == special_node) blk: { |
| 8176 | payloads.items[case_table_start] = header_index; | 8034 | payloads.items[case_table_start] = header_index; |
| 8177 | try payloads.resize(gpa, header_index + 1); // body_len | 8035 | try payloads.resize(gpa, header_index + 1); // body_len |
| 8178 | break :blk header_index; | 8036 | break :blk header_index; |
| ... | @@ -8285,17 +8143,15 @@ fn switchExpr( | ... | @@ -8285,17 +8143,15 @@ fn switchExpr( |
| 8285 | fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { | 8143 | fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 8286 | const astgen = gz.astgen; | 8144 | const astgen = gz.astgen; |
| 8287 | const tree = astgen.tree; | 8145 | const tree = astgen.tree; |
| 8288 | const node_datas = tree.nodes.items(.data); | ||
| 8289 | const node_tags = tree.nodes.items(.tag); | ||
| 8290 | 8146 | ||
| 8291 | if (astgen.fn_block == null) { | 8147 | if (astgen.fn_block == null) { |
| 8292 | return astgen.failNode(node, "'return' outside function scope", .{}); | 8148 | return astgen.failNode(node, "'return' outside function scope", .{}); |
| 8293 | } | 8149 | } |
| 8294 | 8150 | ||
| 8295 | if (gz.any_defer_node != 0) { | 8151 | if (gz.any_defer_node.unwrap()) |any_defer_node| { |
| 8296 | return astgen.failNodeNotes(node, "cannot return from defer expression", .{}, &.{ | 8152 | return astgen.failNodeNotes(node, "cannot return from defer expression", .{}, &.{ |
| 8297 | try astgen.errNoteNode( | 8153 | try astgen.errNoteNode( |
| 8298 | gz.any_defer_node, | 8154 | any_defer_node, |
| 8299 | "defer expression here", | 8155 | "defer expression here", |
| 8300 | .{}, | 8156 | .{}, |
| 8301 | ), | 8157 | ), |
| ... | @@ -8313,8 +8169,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref | ... | @@ -8313,8 +8169,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 8313 | 8169 | ||
| 8314 | const defer_outer = &astgen.fn_block.?.base; | 8170 | const defer_outer = &astgen.fn_block.?.base; |
| 8315 | 8171 | ||
| 8316 | const operand_node = node_datas[node].lhs; | 8172 | const operand_node = tree.nodeData(node).opt_node.unwrap() orelse { |
| 8317 | if (operand_node == 0) { | ||
| 8318 | // Returning a void value; skip error defers. | 8173 | // Returning a void value; skip error defers. |
| 8319 | try genDefers(gz, defer_outer, scope, .normal_only); | 8174 | try genDefers(gz, defer_outer, scope, .normal_only); |
| 8320 | 8175 | ||
| ... | @@ -8323,12 +8178,12 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref | ... | @@ -8323,12 +8178,12 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 8323 | 8178 | ||
| 8324 | _ = try gz.addUnNode(.ret_node, .void_value, node); | 8179 | _ = try gz.addUnNode(.ret_node, .void_value, node); |
| 8325 | return Zir.Inst.Ref.unreachable_value; | 8180 | return Zir.Inst.Ref.unreachable_value; |
| 8326 | } | 8181 | }; |
| 8327 | 8182 | ||
| 8328 | if (node_tags[operand_node] == .error_value) { | 8183 | if (tree.nodeTag(operand_node) == .error_value) { |
| 8329 | // Hot path for `return error.Foo`. This bypasses result location logic as well as logic | 8184 | // Hot path for `return error.Foo`. This bypasses result location logic as well as logic |
| 8330 | // for detecting whether to add something to the function's inferred error set. | 8185 | // for detecting whether to add something to the function's inferred error set. |
| 8331 | const ident_token = node_datas[operand_node].rhs; | 8186 | const ident_token = tree.nodeMainToken(operand_node) + 2; |
| 8332 | const err_name_str_index = try astgen.identAsString(ident_token); | 8187 | const err_name_str_index = try astgen.identAsString(ident_token); |
| 8333 | const defer_counts = countDefers(defer_outer, scope); | 8188 | const defer_counts = countDefers(defer_outer, scope); |
| 8334 | if (!defer_counts.need_err_code) { | 8189 | if (!defer_counts.need_err_code) { |
| ... | @@ -8459,9 +8314,8 @@ fn identifier( | ... | @@ -8459,9 +8314,8 @@ fn identifier( |
| 8459 | ) InnerError!Zir.Inst.Ref { | 8314 | ) InnerError!Zir.Inst.Ref { |
| 8460 | const astgen = gz.astgen; | 8315 | const astgen = gz.astgen; |
| 8461 | const tree = astgen.tree; | 8316 | const tree = astgen.tree; |
| 8462 | const main_tokens = tree.nodes.items(.main_token); | ||
| 8463 | 8317 | ||
| 8464 | const ident_token = main_tokens[ident]; | 8318 | const ident_token = tree.nodeMainToken(ident); |
| 8465 | const ident_name_raw = tree.tokenSlice(ident_token); | 8319 | const ident_name_raw = tree.tokenSlice(ident_token); |
| 8466 | if (mem.eql(u8, ident_name_raw, "_")) { | 8320 | if (mem.eql(u8, ident_name_raw, "_")) { |
| 8467 | return astgen.failNode(ident, "'_' used as an identifier without @\"_\" syntax", .{}); | 8321 | return astgen.failNode(ident, "'_' used as an identifier without @\"_\" syntax", .{}); |
| ... | @@ -8563,9 +8417,9 @@ fn localVarRef( | ... | @@ -8563,9 +8417,9 @@ fn localVarRef( |
| 8563 | // Locals cannot shadow anything, so we do not need to look for ambiguous | 8417 | // Locals cannot shadow anything, so we do not need to look for ambiguous |
| 8564 | // references in this case. | 8418 | // references in this case. |
| 8565 | if (ri.rl == .discard and ri.ctx == .assignment) { | 8419 | if (ri.rl == .discard and ri.ctx == .assignment) { |
| 8566 | local_val.discarded = ident_token; | 8420 | local_val.discarded = .fromToken(ident_token); |
| 8567 | } else { | 8421 | } else { |
| 8568 | local_val.used = ident_token; | 8422 | local_val.used = .fromToken(ident_token); |
| 8569 | } | 8423 | } |
| 8570 | 8424 | ||
| 8571 | if (local_val.is_used_or_discarded) |ptr| ptr.* = true; | 8425 | if (local_val.is_used_or_discarded) |ptr| ptr.* = true; |
| ... | @@ -8587,9 +8441,9 @@ fn localVarRef( | ... | @@ -8587,9 +8441,9 @@ fn localVarRef( |
| 8587 | const local_ptr = s.cast(Scope.LocalPtr).?; | 8441 | const local_ptr = s.cast(Scope.LocalPtr).?; |
| 8588 | if (local_ptr.name == name_str_index) { | 8442 | if (local_ptr.name == name_str_index) { |
| 8589 | if (ri.rl == .discard and ri.ctx == .assignment) { | 8443 | if (ri.rl == .discard and ri.ctx == .assignment) { |
| 8590 | local_ptr.discarded = ident_token; | 8444 | local_ptr.discarded = .fromToken(ident_token); |
| 8591 | } else { | 8445 | } else { |
| 8592 | local_ptr.used = ident_token; | 8446 | local_ptr.used = .fromToken(ident_token); |
| 8593 | } | 8447 | } |
| 8594 | 8448 | ||
| 8595 | // Can't close over a runtime variable | 8449 | // Can't close over a runtime variable |
| ... | @@ -8802,8 +8656,7 @@ fn stringLiteral( | ... | @@ -8802,8 +8656,7 @@ fn stringLiteral( |
| 8802 | ) InnerError!Zir.Inst.Ref { | 8656 | ) InnerError!Zir.Inst.Ref { |
| 8803 | const astgen = gz.astgen; | 8657 | const astgen = gz.astgen; |
| 8804 | const tree = astgen.tree; | 8658 | const tree = astgen.tree; |
| 8805 | const main_tokens = tree.nodes.items(.main_token); | 8659 | const str_lit_token = tree.nodeMainToken(node); |
| 8806 | const str_lit_token = main_tokens[node]; | ||
| 8807 | const str = try astgen.strLitAsString(str_lit_token); | 8660 | const str = try astgen.strLitAsString(str_lit_token); |
| 8808 | const result = try gz.add(.{ | 8661 | const result = try gz.add(.{ |
| 8809 | .tag = .str, | 8662 | .tag = .str, |
| ... | @@ -8835,8 +8688,7 @@ fn multilineStringLiteral( | ... | @@ -8835,8 +8688,7 @@ fn multilineStringLiteral( |
| 8835 | fn charLiteral(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { | 8688 | fn charLiteral(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 8836 | const astgen = gz.astgen; | 8689 | const astgen = gz.astgen; |
| 8837 | const tree = astgen.tree; | 8690 | const tree = astgen.tree; |
| 8838 | const main_tokens = tree.nodes.items(.main_token); | 8691 | const main_token = tree.nodeMainToken(node); |
| 8839 | const main_token = main_tokens[node]; | ||
| 8840 | const slice = tree.tokenSlice(main_token); | 8692 | const slice = tree.tokenSlice(main_token); |
| 8841 | 8693 | ||
| 8842 | switch (std.zig.parseCharLiteral(slice)) { | 8694 | switch (std.zig.parseCharLiteral(slice)) { |
| ... | @@ -8853,8 +8705,7 @@ const Sign = enum { negative, positive }; | ... | @@ -8853,8 +8705,7 @@ const Sign = enum { negative, positive }; |
| 8853 | fn numberLiteral(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index, source_node: Ast.Node.Index, sign: Sign) InnerError!Zir.Inst.Ref { | 8705 | fn numberLiteral(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index, source_node: Ast.Node.Index, sign: Sign) InnerError!Zir.Inst.Ref { |
| 8854 | const astgen = gz.astgen; | 8706 | const astgen = gz.astgen; |
| 8855 | const tree = astgen.tree; | 8707 | const tree = astgen.tree; |
| 8856 | const main_tokens = tree.nodes.items(.main_token); | 8708 | const num_token = tree.nodeMainToken(node); |
| 8857 | const num_token = main_tokens[node]; | ||
| 8858 | const bytes = tree.tokenSlice(num_token); | 8709 | const bytes = tree.tokenSlice(num_token); |
| 8859 | 8710 | ||
| 8860 | const result: Zir.Inst.Ref = switch (std.zig.parseNumberLiteral(bytes)) { | 8711 | const result: Zir.Inst.Ref = switch (std.zig.parseNumberLiteral(bytes)) { |
| ... | @@ -8972,16 +8823,12 @@ fn asmExpr( | ... | @@ -8972,16 +8823,12 @@ fn asmExpr( |
| 8972 | ) InnerError!Zir.Inst.Ref { | 8823 | ) InnerError!Zir.Inst.Ref { |
| 8973 | const astgen = gz.astgen; | 8824 | const astgen = gz.astgen; |
| 8974 | const tree = astgen.tree; | 8825 | const tree = astgen.tree; |
| 8975 | const main_tokens = tree.nodes.items(.main_token); | ||
| 8976 | const node_datas = tree.nodes.items(.data); | ||
| 8977 | const node_tags = tree.nodes.items(.tag); | ||
| 8978 | const token_tags = tree.tokens.items(.tag); | ||
| 8979 | 8826 | ||
| 8980 | const TagAndTmpl = struct { tag: Zir.Inst.Extended, tmpl: Zir.NullTerminatedString }; | 8827 | const TagAndTmpl = struct { tag: Zir.Inst.Extended, tmpl: Zir.NullTerminatedString }; |
| 8981 | const tag_and_tmpl: TagAndTmpl = switch (node_tags[full.ast.template]) { | 8828 | const tag_and_tmpl: TagAndTmpl = switch (tree.nodeTag(full.ast.template)) { |
| 8982 | .string_literal => .{ | 8829 | .string_literal => .{ |
| 8983 | .tag = .@"asm", | 8830 | .tag = .@"asm", |
| 8984 | .tmpl = (try astgen.strLitAsString(main_tokens[full.ast.template])).index, | 8831 | .tmpl = (try astgen.strLitAsString(tree.nodeMainToken(full.ast.template))).index, |
| 8985 | }, | 8832 | }, |
| 8986 | .multiline_string_literal => .{ | 8833 | .multiline_string_literal => .{ |
| 8987 | .tag = .@"asm", | 8834 | .tag = .@"asm", |
| ... | @@ -9016,17 +8863,17 @@ fn asmExpr( | ... | @@ -9016,17 +8863,17 @@ fn asmExpr( |
| 9016 | var output_type_bits: u32 = 0; | 8863 | var output_type_bits: u32 = 0; |
| 9017 | 8864 | ||
| 9018 | for (full.outputs, 0..) |output_node, i| { | 8865 | for (full.outputs, 0..) |output_node, i| { |
| 9019 | const symbolic_name = main_tokens[output_node]; | 8866 | const symbolic_name = tree.nodeMainToken(output_node); |
| 9020 | const name = try astgen.identAsString(symbolic_name); | 8867 | const name = try astgen.identAsString(symbolic_name); |
| 9021 | const constraint_token = symbolic_name + 2; | 8868 | const constraint_token = symbolic_name + 2; |
| 9022 | const constraint = (try astgen.strLitAsString(constraint_token)).index; | 8869 | const constraint = (try astgen.strLitAsString(constraint_token)).index; |
| 9023 | const has_arrow = token_tags[symbolic_name + 4] == .arrow; | 8870 | const has_arrow = tree.tokenTag(symbolic_name + 4) == .arrow; |
| 9024 | if (has_arrow) { | 8871 | if (has_arrow) { |
| 9025 | if (output_type_bits != 0) { | 8872 | if (output_type_bits != 0) { |
| 9026 | return astgen.failNode(output_node, "inline assembly allows up to one output value", .{}); | 8873 | return astgen.failNode(output_node, "inline assembly allows up to one output value", .{}); |
| 9027 | } | 8874 | } |
| 9028 | output_type_bits |= @as(u32, 1) << @intCast(i); | 8875 | output_type_bits |= @as(u32, 1) << @intCast(i); |
| 9029 | const out_type_node = node_datas[output_node].lhs; | 8876 | const out_type_node = tree.nodeData(output_node).opt_node_and_token[0].unwrap().?; |
| 9030 | const out_type_inst = try typeExpr(gz, scope, out_type_node); | 8877 | const out_type_inst = try typeExpr(gz, scope, out_type_node); |
| 9031 | outputs[i] = .{ | 8878 | outputs[i] = .{ |
| 9032 | .name = name, | 8879 | .name = name, |
| ... | @@ -9053,11 +8900,11 @@ fn asmExpr( | ... | @@ -9053,11 +8900,11 @@ fn asmExpr( |
| 9053 | const inputs = inputs_buffer[0..full.inputs.len]; | 8900 | const inputs = inputs_buffer[0..full.inputs.len]; |
| 9054 | 8901 | ||
| 9055 | for (full.inputs, 0..) |input_node, i| { | 8902 | for (full.inputs, 0..) |input_node, i| { |
| 9056 | const symbolic_name = main_tokens[input_node]; | 8903 | const symbolic_name = tree.nodeMainToken(input_node); |
| 9057 | const name = try astgen.identAsString(symbolic_name); | 8904 | const name = try astgen.identAsString(symbolic_name); |
| 9058 | const constraint_token = symbolic_name + 2; | 8905 | const constraint_token = symbolic_name + 2; |
| 9059 | const constraint = (try astgen.strLitAsString(constraint_token)).index; | 8906 | const constraint = (try astgen.strLitAsString(constraint_token)).index; |
| 9060 | const operand = try expr(gz, scope, .{ .rl = .none }, node_datas[input_node].lhs); | 8907 | const operand = try expr(gz, scope, .{ .rl = .none }, tree.nodeData(input_node).node_and_token[0]); |
| 9061 | inputs[i] = .{ | 8908 | inputs[i] = .{ |
| 9062 | .name = name, | 8909 | .name = name, |
| 9063 | .constraint = constraint, | 8910 | .constraint = constraint, |
| ... | @@ -9078,10 +8925,10 @@ fn asmExpr( | ... | @@ -9078,10 +8925,10 @@ fn asmExpr( |
| 9078 | clobbers_buffer[clobber_i] = @intFromEnum((try astgen.strLitAsString(tok_i)).index); | 8925 | clobbers_buffer[clobber_i] = @intFromEnum((try astgen.strLitAsString(tok_i)).index); |
| 9079 | clobber_i += 1; | 8926 | clobber_i += 1; |
| 9080 | tok_i += 1; | 8927 | tok_i += 1; |
| 9081 | switch (token_tags[tok_i]) { | 8928 | switch (tree.tokenTag(tok_i)) { |
| 9082 | .r_paren => break :clobbers, | 8929 | .r_paren => break :clobbers, |
| 9083 | .comma => { | 8930 | .comma => { |
| 9084 | if (token_tags[tok_i + 1] == .r_paren) { | 8931 | if (tree.tokenTag(tok_i + 1) == .r_paren) { |
| 9085 | break :clobbers; | 8932 | break :clobbers; |
| 9086 | } else { | 8933 | } else { |
| 9087 | continue; | 8934 | continue; |
| ... | @@ -9173,9 +9020,6 @@ fn ptrCast( | ... | @@ -9173,9 +9020,6 @@ fn ptrCast( |
| 9173 | ) InnerError!Zir.Inst.Ref { | 9020 | ) InnerError!Zir.Inst.Ref { |
| 9174 | const astgen = gz.astgen; | 9021 | const astgen = gz.astgen; |
| 9175 | const tree = astgen.tree; | 9022 | const tree = astgen.tree; |
| 9176 | const main_tokens = tree.nodes.items(.main_token); | ||
| 9177 | const node_datas = tree.nodes.items(.data); | ||
| 9178 | const node_tags = tree.nodes.items(.tag); | ||
| 9179 | 9023 | ||
| 9180 | const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).@"struct".backing_integer.?; | 9024 | const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).@"struct".backing_integer.?; |
| 9181 | var flags: Zir.Inst.FullPtrCastFlags = .{}; | 9025 | var flags: Zir.Inst.FullPtrCastFlags = .{}; |
| ... | @@ -9184,23 +9028,26 @@ fn ptrCast( | ... | @@ -9184,23 +9028,26 @@ fn ptrCast( |
| 9184 | // to handle `builtin_call_two`. | 9028 | // to handle `builtin_call_two`. |
| 9185 | var node = root_node; | 9029 | var node = root_node; |
| 9186 | while (true) { | 9030 | while (true) { |
| 9187 | switch (node_tags[node]) { | 9031 | switch (tree.nodeTag(node)) { |
| 9188 | .builtin_call_two, .builtin_call_two_comma => {}, | 9032 | .builtin_call_two, .builtin_call_two_comma => {}, |
| 9189 | .grouped_expression => { | 9033 | .grouped_expression => { |
| 9190 | // Handle the chaining even with redundant parentheses | 9034 | // Handle the chaining even with redundant parentheses |
| 9191 | node = node_datas[node].lhs; | 9035 | node = tree.nodeData(node).node_and_token[0]; |
| 9192 | continue; | 9036 | continue; |
| 9193 | }, | 9037 | }, |
| 9194 | else => break, | 9038 | else => break, |
| 9195 | } | 9039 | } |
| 9196 | 9040 | ||
| 9197 | if (node_datas[node].lhs == 0) break; // 0 args | 9041 | var buf: [2]Ast.Node.Index = undefined; |
| 9042 | const args = tree.builtinCallParams(&buf, node).?; | ||
| 9043 | std.debug.assert(args.len <= 2); | ||
| 9044 | |||
| 9045 | if (args.len == 0) break; // 0 args | ||
| 9198 | 9046 | ||
| 9199 | const builtin_token = main_tokens[node]; | 9047 | const builtin_token = tree.nodeMainToken(node); |
| 9200 | const builtin_name = tree.tokenSlice(builtin_token); | 9048 | const builtin_name = tree.tokenSlice(builtin_token); |
| 9201 | const info = BuiltinFn.list.get(builtin_name) orelse break; | 9049 | const info = BuiltinFn.list.get(builtin_name) orelse break; |
| 9202 | if (node_datas[node].rhs == 0) { | 9050 | if (args.len == 1) { |
| 9203 | // 1 arg | ||
| 9204 | if (info.param_count != 1) break; | 9051 | if (info.param_count != 1) break; |
| 9205 | 9052 | ||
| 9206 | switch (info.tag) { | 9053 | switch (info.tag) { |
| ... | @@ -9218,9 +9065,9 @@ fn ptrCast( | ... | @@ -9218,9 +9065,9 @@ fn ptrCast( |
| 9218 | }, | 9065 | }, |
| 9219 | } | 9066 | } |
| 9220 | 9067 | ||
| 9221 | node = node_datas[node].lhs; | 9068 | node = args[0]; |
| 9222 | } else { | 9069 | } else { |
| 9223 | // 2 args | 9070 | std.debug.assert(args.len == 2); |
| 9224 | if (info.param_count != 2) break; | 9071 | if (info.param_count != 2) break; |
| 9225 | 9072 | ||
| 9226 | switch (info.tag) { | 9073 | switch (info.tag) { |
| ... | @@ -9231,8 +9078,8 @@ fn ptrCast( | ... | @@ -9231,8 +9078,8 @@ fn ptrCast( |
| 9231 | const flags_int: FlagsInt = @bitCast(flags); | 9078 | const flags_int: FlagsInt = @bitCast(flags); |
| 9232 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, root_node); | 9079 | const cursor = maybeAdvanceSourceCursorToMainToken(gz, root_node); |
| 9233 | const parent_ptr_type = try ri.rl.resultTypeForCast(gz, root_node, "@alignCast"); | 9080 | const parent_ptr_type = try ri.rl.resultTypeForCast(gz, root_node, "@alignCast"); |
| 9234 | const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, node_datas[node].lhs, .field_name); | 9081 | const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, args[0], .field_name); |
| 9235 | const field_ptr = try expr(gz, scope, .{ .rl = .none }, node_datas[node].rhs); | 9082 | const field_ptr = try expr(gz, scope, .{ .rl = .none }, args[1]); |
| 9236 | try emitDbgStmt(gz, cursor); | 9083 | try emitDbgStmt(gz, cursor); |
| 9237 | const result = try gz.addExtendedPayloadSmall(.field_parent_ptr, flags_int, Zir.Inst.FieldParentPtr{ | 9084 | const result = try gz.addExtendedPayloadSmall(.field_parent_ptr, flags_int, Zir.Inst.FieldParentPtr{ |
| 9238 | .src_node = gz.nodeIndexToRelative(node), | 9085 | .src_node = gz.nodeIndexToRelative(node), |
| ... | @@ -9397,9 +9244,8 @@ fn builtinCall( | ... | @@ -9397,9 +9244,8 @@ fn builtinCall( |
| 9397 | ) InnerError!Zir.Inst.Ref { | 9244 | ) InnerError!Zir.Inst.Ref { |
| 9398 | const astgen = gz.astgen; | 9245 | const astgen = gz.astgen; |
| 9399 | const tree = astgen.tree; | 9246 | const tree = astgen.tree; |
| 9400 | const main_tokens = tree.nodes.items(.main_token); | ||
| 9401 | 9247 | ||
| 9402 | const builtin_token = main_tokens[node]; | 9248 | const builtin_token = tree.nodeMainToken(node); |
| 9403 | const builtin_name = tree.tokenSlice(builtin_token); | 9249 | const builtin_name = tree.tokenSlice(builtin_token); |
| 9404 | 9250 | ||
| 9405 | // We handle the different builtins manually because they have different semantics depending | 9251 | // We handle the different builtins manually because they have different semantics depending |
| ... | @@ -9440,14 +9286,13 @@ fn builtinCall( | ... | @@ -9440,14 +9286,13 @@ fn builtinCall( |
| 9440 | return rvalue(gz, ri, .void_value, node); | 9286 | return rvalue(gz, ri, .void_value, node); |
| 9441 | }, | 9287 | }, |
| 9442 | .import => { | 9288 | .import => { |
| 9443 | const node_tags = tree.nodes.items(.tag); | ||
| 9444 | const operand_node = params[0]; | 9289 | const operand_node = params[0]; |
| 9445 | 9290 | ||
| 9446 | if (node_tags[operand_node] != .string_literal) { | 9291 | if (tree.nodeTag(operand_node) != .string_literal) { |
| 9447 | // Spec reference: https://github.com/ziglang/zig/issues/2206 | 9292 | // Spec reference: https://github.com/ziglang/zig/issues/2206 |
| 9448 | return astgen.failNode(operand_node, "@import operand must be a string literal", .{}); | 9293 | return astgen.failNode(operand_node, "@import operand must be a string literal", .{}); |
| 9449 | } | 9294 | } |
| 9450 | const str_lit_token = main_tokens[operand_node]; | 9295 | const str_lit_token = tree.nodeMainToken(operand_node); |
| 9451 | const str = try astgen.strLitAsString(str_lit_token); | 9296 | const str = try astgen.strLitAsString(str_lit_token); |
| 9452 | const str_slice = astgen.string_bytes.items[@intFromEnum(str.index)..][0..str.len]; | 9297 | const str_slice = astgen.string_bytes.items[@intFromEnum(str.index)..][0..str.len]; |
| 9453 | if (mem.indexOfScalar(u8, str_slice, 0) != null) { | 9298 | if (mem.indexOfScalar(u8, str_slice, 0) != null) { |
| ... | @@ -9558,8 +9403,7 @@ fn builtinCall( | ... | @@ -9558,8 +9403,7 @@ fn builtinCall( |
| 9558 | std.mem.asBytes(&astgen.source_column), | 9403 | std.mem.asBytes(&astgen.source_column), |
| 9559 | ); | 9404 | ); |
| 9560 | 9405 | ||
| 9561 | const token_starts = tree.tokens.items(.start); | 9406 | const node_start = tree.tokenStart(tree.firstToken(node)); |
| 9562 | const node_start = token_starts[tree.firstToken(node)]; | ||
| 9563 | astgen.advanceSourceCursor(node_start); | 9407 | astgen.advanceSourceCursor(node_start); |
| 9564 | const result = try gz.addExtendedPayload(.builtin_src, Zir.Inst.Src{ | 9408 | const result = try gz.addExtendedPayload(.builtin_src, Zir.Inst.Src{ |
| 9565 | .node = gz.nodeIndexToRelative(node), | 9409 | .node = gz.nodeIndexToRelative(node), |
| ... | @@ -9839,7 +9683,7 @@ fn builtinCall( | ... | @@ -9839,7 +9683,7 @@ fn builtinCall( |
| 9839 | .callee = callee, | 9683 | .callee = callee, |
| 9840 | .args = args, | 9684 | .args = args, |
| 9841 | .flags = .{ | 9685 | .flags = .{ |
| 9842 | .is_nosuspend = gz.nosuspend_node != 0, | 9686 | .is_nosuspend = gz.nosuspend_node != .none, |
| 9843 | .ensure_result_used = false, | 9687 | .ensure_result_used = false, |
| 9844 | }, | 9688 | }, |
| 9845 | }); | 9689 | }); |
| ... | @@ -10064,13 +9908,11 @@ fn negation( | ... | @@ -10064,13 +9908,11 @@ fn negation( |
| 10064 | ) InnerError!Zir.Inst.Ref { | 9908 | ) InnerError!Zir.Inst.Ref { |
| 10065 | const astgen = gz.astgen; | 9909 | const astgen = gz.astgen; |
| 10066 | const tree = astgen.tree; | 9910 | const tree = astgen.tree; |
| 10067 | const node_tags = tree.nodes.items(.tag); | ||
| 10068 | const node_datas = tree.nodes.items(.data); | ||
| 10069 | 9911 | ||
| 10070 | // Check for float literal as the sub-expression because we want to preserve | 9912 | // Check for float literal as the sub-expression because we want to preserve |
| 10071 | // its negativity rather than having it go through comptime subtraction. | 9913 | // its negativity rather than having it go through comptime subtraction. |
| 10072 | const operand_node = node_datas[node].lhs; | 9914 | const operand_node = tree.nodeData(node).node; |
| 10073 | if (node_tags[operand_node] == .number_literal) { | 9915 | if (tree.nodeTag(operand_node) == .number_literal) { |
| 10074 | return numberLiteral(gz, ri, operand_node, node, .negative); | 9916 | return numberLiteral(gz, ri, operand_node, node, .negative); |
| 10075 | } | 9917 | } |
| 10076 | 9918 | ||
| ... | @@ -10186,7 +10028,7 @@ fn shiftOp( | ... | @@ -10186,7 +10028,7 @@ fn shiftOp( |
| 10186 | ) InnerError!Zir.Inst.Ref { | 10028 | ) InnerError!Zir.Inst.Ref { |
| 10187 | const lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node); | 10029 | const lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node); |
| 10188 | 10030 | ||
| 10189 | const cursor = switch (gz.astgen.tree.nodes.items(.tag)[node]) { | 10031 | const cursor = switch (gz.astgen.tree.nodeTag(node)) { |
| 10190 | .shl, .shr => maybeAdvanceSourceCursorToMainToken(gz, node), | 10032 | .shl, .shr => maybeAdvanceSourceCursorToMainToken(gz, node), |
| 10191 | else => undefined, | 10033 | else => undefined, |
| 10192 | }; | 10034 | }; |
| ... | @@ -10194,7 +10036,7 @@ fn shiftOp( | ... | @@ -10194,7 +10036,7 @@ fn shiftOp( |
| 10194 | const log2_int_type = try gz.addUnNode(.typeof_log2_int_type, lhs, lhs_node); | 10036 | const log2_int_type = try gz.addUnNode(.typeof_log2_int_type, lhs, lhs_node); |
| 10195 | const rhs = try expr(gz, scope, .{ .rl = .{ .ty = log2_int_type }, .ctx = .shift_op }, rhs_node); | 10037 | const rhs = try expr(gz, scope, .{ .rl = .{ .ty = log2_int_type }, .ctx = .shift_op }, rhs_node); |
| 10196 | 10038 | ||
| 10197 | switch (gz.astgen.tree.nodes.items(.tag)[node]) { | 10039 | switch (gz.astgen.tree.nodeTag(node)) { |
| 10198 | .shl, .shr => try emitDbgStmt(gz, cursor), | 10040 | .shl, .shr => try emitDbgStmt(gz, cursor), |
| 10199 | else => undefined, | 10041 | else => undefined, |
| 10200 | } | 10042 | } |
| ... | @@ -10270,14 +10112,14 @@ fn callExpr( | ... | @@ -10270,14 +10112,14 @@ fn callExpr( |
| 10270 | if (call.async_token != null) { | 10112 | if (call.async_token != null) { |
| 10271 | break :blk .async_kw; | 10113 | break :blk .async_kw; |
| 10272 | } | 10114 | } |
| 10273 | if (gz.nosuspend_node != 0) { | 10115 | if (gz.nosuspend_node != .none) { |
| 10274 | break :blk .no_async; | 10116 | break :blk .no_async; |
| 10275 | } | 10117 | } |
| 10276 | break :blk .auto; | 10118 | break :blk .auto; |
| 10277 | }; | 10119 | }; |
| 10278 | 10120 | ||
| 10279 | { | 10121 | { |
| 10280 | astgen.advanceSourceCursor(astgen.tree.tokens.items(.start)[call.ast.lparen]); | 10122 | astgen.advanceSourceCursor(astgen.tree.tokenStart(call.ast.lparen)); |
| 10281 | const line = astgen.source_line - gz.decl_line; | 10123 | const line = astgen.source_line - gz.decl_line; |
| 10282 | const column = astgen.source_column; | 10124 | const column = astgen.source_column; |
| 10283 | // Sema expects a dbg_stmt immediately before call, | 10125 | // Sema expects a dbg_stmt immediately before call, |
| ... | @@ -10288,7 +10130,6 @@ fn callExpr( | ... | @@ -10288,7 +10130,6 @@ fn callExpr( |
| 10288 | .direct => |obj| assert(obj != .none), | 10130 | .direct => |obj| assert(obj != .none), |
| 10289 | .field => |field| assert(field.obj_ptr != .none), | 10131 | .field => |field| assert(field.obj_ptr != .none), |
| 10290 | } | 10132 | } |
| 10291 | assert(node != 0); | ||
| 10292 | 10133 | ||
| 10293 | const call_index: Zir.Inst.Index = @enumFromInt(astgen.instructions.len); | 10134 | const call_index: Zir.Inst.Index = @enumFromInt(astgen.instructions.len); |
| 10294 | const call_inst = call_index.toRef(); | 10135 | const call_inst = call_index.toRef(); |
| ... | @@ -10399,14 +10240,10 @@ fn calleeExpr( | ... | @@ -10399,14 +10240,10 @@ fn calleeExpr( |
| 10399 | const astgen = gz.astgen; | 10240 | const astgen = gz.astgen; |
| 10400 | const tree = astgen.tree; | 10241 | const tree = astgen.tree; |
| 10401 | 10242 | ||
| 10402 | const tag = tree.nodes.items(.tag)[node]; | 10243 | const tag = tree.nodeTag(node); |
| 10403 | switch (tag) { | 10244 | switch (tag) { |
| 10404 | .field_access => { | 10245 | .field_access => { |
| 10405 | const main_tokens = tree.nodes.items(.main_token); | 10246 | const object_node, const field_ident = tree.nodeData(node).node_and_token; |
| 10406 | const node_datas = tree.nodes.items(.data); | ||
| 10407 | const object_node = node_datas[node].lhs; | ||
| 10408 | const dot_token = main_tokens[node]; | ||
| 10409 | const field_ident = dot_token + 1; | ||
| 10410 | const str_index = try astgen.identAsString(field_ident); | 10247 | const str_index = try astgen.identAsString(field_ident); |
| 10411 | // Capture the object by reference so we can promote it to an | 10248 | // Capture the object by reference so we can promote it to an |
| 10412 | // address in Sema if needed. | 10249 | // address in Sema if needed. |
| ... | @@ -10431,7 +10268,7 @@ fn calleeExpr( | ... | @@ -10431,7 +10268,7 @@ fn calleeExpr( |
| 10431 | // Decl literal call syntax, e.g. | 10268 | // Decl literal call syntax, e.g. |
| 10432 | // `const foo: T = .init();` | 10269 | // `const foo: T = .init();` |
| 10433 | // Look up `init` in `T`, but don't try and coerce it. | 10270 | // Look up `init` in `T`, but don't try and coerce it. |
| 10434 | const str_index = try astgen.identAsString(tree.nodes.items(.main_token)[node]); | 10271 | const str_index = try astgen.identAsString(tree.nodeMainToken(node)); |
| 10435 | const callee = try gz.addPlNode(.decl_literal_no_coerce, node, Zir.Inst.Field{ | 10272 | const callee = try gz.addPlNode(.decl_literal_no_coerce, node, Zir.Inst.Field{ |
| 10436 | .lhs = res_ty, | 10273 | .lhs = res_ty, |
| 10437 | .field_name_start = str_index, | 10274 | .field_name_start = str_index, |
| ... | @@ -10503,12 +10340,9 @@ comptime { | ... | @@ -10503,12 +10340,9 @@ comptime { |
| 10503 | } | 10340 | } |
| 10504 | 10341 | ||
| 10505 | fn nodeIsTriviallyZero(tree: *const Ast, node: Ast.Node.Index) bool { | 10342 | fn nodeIsTriviallyZero(tree: *const Ast, node: Ast.Node.Index) bool { |
| 10506 | const node_tags = tree.nodes.items(.tag); | 10343 | switch (tree.nodeTag(node)) { |
| 10507 | const main_tokens = tree.nodes.items(.main_token); | ||
| 10508 | |||
| 10509 | switch (node_tags[node]) { | ||
| 10510 | .number_literal => { | 10344 | .number_literal => { |
| 10511 | const ident = main_tokens[node]; | 10345 | const ident = tree.nodeMainToken(node); |
| 10512 | return switch (std.zig.parseNumberLiteral(tree.tokenSlice(ident))) { | 10346 | return switch (std.zig.parseNumberLiteral(tree.tokenSlice(ident))) { |
| 10513 | .int => |number| switch (number) { | 10347 | .int => |number| switch (number) { |
| 10514 | 0 => true, | 10348 | 0 => true, |
| ... | @@ -10522,12 +10356,9 @@ fn nodeIsTriviallyZero(tree: *const Ast, node: Ast.Node.Index) bool { | ... | @@ -10522,12 +10356,9 @@ fn nodeIsTriviallyZero(tree: *const Ast, node: Ast.Node.Index) bool { |
| 10522 | } | 10356 | } |
| 10523 | 10357 | ||
| 10524 | fn nodeMayAppendToErrorTrace(tree: *const Ast, start_node: Ast.Node.Index) bool { | 10358 | fn nodeMayAppendToErrorTrace(tree: *const Ast, start_node: Ast.Node.Index) bool { |
| 10525 | const node_tags = tree.nodes.items(.tag); | ||
| 10526 | const node_datas = tree.nodes.items(.data); | ||
| 10527 | |||
| 10528 | var node = start_node; | 10359 | var node = start_node; |
| 10529 | while (true) { | 10360 | while (true) { |
| 10530 | switch (node_tags[node]) { | 10361 | switch (tree.nodeTag(node)) { |
| 10531 | // These don't have the opportunity to call any runtime functions. | 10362 | // These don't have the opportunity to call any runtime functions. |
| 10532 | .error_value, | 10363 | .error_value, |
| 10533 | .identifier, | 10364 | .identifier, |
| ... | @@ -10535,11 +10366,12 @@ fn nodeMayAppendToErrorTrace(tree: *const Ast, start_node: Ast.Node.Index) bool | ... | @@ -10535,11 +10366,12 @@ fn nodeMayAppendToErrorTrace(tree: *const Ast, start_node: Ast.Node.Index) bool |
| 10535 | => return false, | 10366 | => return false, |
| 10536 | 10367 | ||
| 10537 | // Forward the question to the LHS sub-expression. | 10368 | // Forward the question to the LHS sub-expression. |
| 10538 | .grouped_expression, | ||
| 10539 | .@"try", | 10369 | .@"try", |
| 10540 | .@"nosuspend", | 10370 | .@"nosuspend", |
| 10371 | => node = tree.nodeData(node).node, | ||
| 10372 | .grouped_expression, | ||
| 10541 | .unwrap_optional, | 10373 | .unwrap_optional, |
| 10542 | => node = node_datas[node].lhs, | 10374 | => node = tree.nodeData(node).node_and_token[0], |
| 10543 | 10375 | ||
| 10544 | // Anything that does not eval to an error is guaranteed to pop any | 10376 | // Anything that does not eval to an error is guaranteed to pop any |
| 10545 | // additions to the error trace, so it effectively does not append. | 10377 | // additions to the error trace, so it effectively does not append. |
| ... | @@ -10549,14 +10381,9 @@ fn nodeMayAppendToErrorTrace(tree: *const Ast, start_node: Ast.Node.Index) bool | ... | @@ -10549,14 +10381,9 @@ fn nodeMayAppendToErrorTrace(tree: *const Ast, start_node: Ast.Node.Index) bool |
| 10549 | } | 10381 | } |
| 10550 | 10382 | ||
| 10551 | fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.EvalToError { | 10383 | fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.EvalToError { |
| 10552 | const node_tags = tree.nodes.items(.tag); | ||
| 10553 | const node_datas = tree.nodes.items(.data); | ||
| 10554 | const main_tokens = tree.nodes.items(.main_token); | ||
| 10555 | const token_tags = tree.tokens.items(.tag); | ||
| 10556 | |||
| 10557 | var node = start_node; | 10384 | var node = start_node; |
| 10558 | while (true) { | 10385 | while (true) { |
| 10559 | switch (node_tags[node]) { | 10386 | switch (tree.nodeTag(node)) { |
| 10560 | .root, | 10387 | .root, |
| 10561 | .@"usingnamespace", | 10388 | .@"usingnamespace", |
| 10562 | .test_decl, | 10389 | .test_decl, |
| ... | @@ -10719,13 +10546,14 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev | ... | @@ -10719,13 +10546,14 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev |
| 10719 | => return .never, | 10546 | => return .never, |
| 10720 | 10547 | ||
| 10721 | // Forward the question to the LHS sub-expression. | 10548 | // Forward the question to the LHS sub-expression. |
| 10722 | .grouped_expression, | ||
| 10723 | .@"try", | 10549 | .@"try", |
| 10724 | .@"await", | 10550 | .@"await", |
| 10725 | .@"comptime", | 10551 | .@"comptime", |
| 10726 | .@"nosuspend", | 10552 | .@"nosuspend", |
| 10553 | => node = tree.nodeData(node).node, | ||
| 10554 | .grouped_expression, | ||
| 10727 | .unwrap_optional, | 10555 | .unwrap_optional, |
| 10728 | => node = node_datas[node].lhs, | 10556 | => node = tree.nodeData(node).node_and_token[0], |
| 10729 | 10557 | ||
| 10730 | // LHS sub-expression may still be an error under the outer optional or error union | 10558 | // LHS sub-expression may still be an error under the outer optional or error union |
| 10731 | .@"catch", | 10559 | .@"catch", |
| ... | @@ -10737,8 +10565,8 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev | ... | @@ -10737,8 +10565,8 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev |
| 10737 | .block, | 10565 | .block, |
| 10738 | .block_semicolon, | 10566 | .block_semicolon, |
| 10739 | => { | 10567 | => { |
| 10740 | const lbrace = main_tokens[node]; | 10568 | const lbrace = tree.nodeMainToken(node); |
| 10741 | if (token_tags[lbrace - 1] == .colon) { | 10569 | if (tree.tokenTag(lbrace - 1) == .colon) { |
| 10742 | // Labeled blocks may need a memory location to forward | 10570 | // Labeled blocks may need a memory location to forward |
| 10743 | // to their break statements. | 10571 | // to their break statements. |
| 10744 | return .maybe; | 10572 | return .maybe; |
| ... | @@ -10752,7 +10580,7 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev | ... | @@ -10752,7 +10580,7 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev |
| 10752 | .builtin_call_two, | 10580 | .builtin_call_two, |
| 10753 | .builtin_call_two_comma, | 10581 | .builtin_call_two_comma, |
| 10754 | => { | 10582 | => { |
| 10755 | const builtin_token = main_tokens[node]; | 10583 | const builtin_token = tree.nodeMainToken(node); |
| 10756 | const builtin_name = tree.tokenSlice(builtin_token); | 10584 | const builtin_name = tree.tokenSlice(builtin_token); |
| 10757 | // If the builtin is an invalid name, we don't cause an error here; instead | 10585 | // If the builtin is an invalid name, we don't cause an error here; instead |
| 10758 | // let it pass, and the error will be "invalid builtin function" later. | 10586 | // let it pass, and the error will be "invalid builtin function" later. |
| ... | @@ -10766,12 +10594,9 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev | ... | @@ -10766,12 +10594,9 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev |
| 10766 | /// Returns `true` if it is known the type expression has more than one possible value; | 10594 | /// Returns `true` if it is known the type expression has more than one possible value; |
| 10767 | /// `false` otherwise. | 10595 | /// `false` otherwise. |
| 10768 | fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.Index) bool { | 10596 | fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.Index) bool { |
| 10769 | const node_tags = tree.nodes.items(.tag); | ||
| 10770 | const node_datas = tree.nodes.items(.data); | ||
| 10771 | |||
| 10772 | var node = start_node; | 10597 | var node = start_node; |
| 10773 | while (true) { | 10598 | while (true) { |
| 10774 | switch (node_tags[node]) { | 10599 | switch (tree.nodeTag(node)) { |
| 10775 | .root, | 10600 | .root, |
| 10776 | .@"usingnamespace", | 10601 | .@"usingnamespace", |
| 10777 | .test_decl, | 10602 | .test_decl, |
| ... | @@ -10934,13 +10759,14 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In | ... | @@ -10934,13 +10759,14 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In |
| 10934 | => return false, | 10759 | => return false, |
| 10935 | 10760 | ||
| 10936 | // Forward the question to the LHS sub-expression. | 10761 | // Forward the question to the LHS sub-expression. |
| 10937 | .grouped_expression, | ||
| 10938 | .@"try", | 10762 | .@"try", |
| 10939 | .@"await", | 10763 | .@"await", |
| 10940 | .@"comptime", | 10764 | .@"comptime", |
| 10941 | .@"nosuspend", | 10765 | .@"nosuspend", |
| 10766 | => node = tree.nodeData(node).node, | ||
| 10767 | .grouped_expression, | ||
| 10942 | .unwrap_optional, | 10768 | .unwrap_optional, |
| 10943 | => node = node_datas[node].lhs, | 10769 | => node = tree.nodeData(node).node_and_token[0], |
| 10944 | 10770 | ||
| 10945 | .ptr_type_aligned, | 10771 | .ptr_type_aligned, |
| 10946 | .ptr_type_sentinel, | 10772 | .ptr_type_sentinel, |
| ... | @@ -10952,8 +10778,7 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In | ... | @@ -10952,8 +10778,7 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In |
| 10952 | => return true, | 10778 | => return true, |
| 10953 | 10779 | ||
| 10954 | .identifier => { | 10780 | .identifier => { |
| 10955 | const main_tokens = tree.nodes.items(.main_token); | 10781 | const ident_bytes = tree.tokenSlice(tree.nodeMainToken(node)); |
| 10956 | const ident_bytes = tree.tokenSlice(main_tokens[node]); | ||
| 10957 | if (primitive_instrs.get(ident_bytes)) |primitive| switch (primitive) { | 10782 | if (primitive_instrs.get(ident_bytes)) |primitive| switch (primitive) { |
| 10958 | .anyerror_type, | 10783 | .anyerror_type, |
| 10959 | .anyframe_type, | 10784 | .anyframe_type, |
| ... | @@ -11013,12 +10838,9 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In | ... | @@ -11013,12 +10838,9 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In |
| 11013 | /// Returns `true` if it is known the expression is a type that cannot be used at runtime; | 10838 | /// Returns `true` if it is known the expression is a type that cannot be used at runtime; |
| 11014 | /// `false` otherwise. | 10839 | /// `false` otherwise. |
| 11015 | fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool { | 10840 | fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool { |
| 11016 | const node_tags = tree.nodes.items(.tag); | ||
| 11017 | const node_datas = tree.nodes.items(.data); | ||
| 11018 | |||
| 11019 | var node = start_node; | 10841 | var node = start_node; |
| 11020 | while (true) { | 10842 | while (true) { |
| 11021 | switch (node_tags[node]) { | 10843 | switch (tree.nodeTag(node)) { |
| 11022 | .root, | 10844 | .root, |
| 11023 | .@"usingnamespace", | 10845 | .@"usingnamespace", |
| 11024 | .test_decl, | 10846 | .test_decl, |
| ... | @@ -11190,17 +11012,17 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool { | ... | @@ -11190,17 +11012,17 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool { |
| 11190 | => return true, | 11012 | => return true, |
| 11191 | 11013 | ||
| 11192 | // Forward the question to the LHS sub-expression. | 11014 | // Forward the question to the LHS sub-expression. |
| 11193 | .grouped_expression, | ||
| 11194 | .@"try", | 11015 | .@"try", |
| 11195 | .@"await", | 11016 | .@"await", |
| 11196 | .@"comptime", | 11017 | .@"comptime", |
| 11197 | .@"nosuspend", | 11018 | .@"nosuspend", |
| 11019 | => node = tree.nodeData(node).node, | ||
| 11020 | .grouped_expression, | ||
| 11198 | .unwrap_optional, | 11021 | .unwrap_optional, |
| 11199 | => node = node_datas[node].lhs, | 11022 | => node = tree.nodeData(node).node_and_token[0], |
| 11200 | 11023 | ||
| 11201 | .identifier => { | 11024 | .identifier => { |
| 11202 | const main_tokens = tree.nodes.items(.main_token); | 11025 | const ident_bytes = tree.tokenSlice(tree.nodeMainToken(node)); |
| 11203 | const ident_bytes = tree.tokenSlice(main_tokens[node]); | ||
| 11204 | if (primitive_instrs.get(ident_bytes)) |primitive| switch (primitive) { | 11026 | if (primitive_instrs.get(ident_bytes)) |primitive| switch (primitive) { |
| 11205 | .anyerror_type, | 11027 | .anyerror_type, |
| 11206 | .anyframe_type, | 11028 | .anyframe_type, |
| ... | @@ -11259,8 +11081,7 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool { | ... | @@ -11259,8 +11081,7 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool { |
| 11259 | 11081 | ||
| 11260 | /// Returns `true` if the node uses `gz.anon_name_strategy`. | 11082 | /// Returns `true` if the node uses `gz.anon_name_strategy`. |
| 11261 | fn nodeUsesAnonNameStrategy(tree: *const Ast, node: Ast.Node.Index) bool { | 11083 | fn nodeUsesAnonNameStrategy(tree: *const Ast, node: Ast.Node.Index) bool { |
| 11262 | const node_tags = tree.nodes.items(.tag); | 11084 | switch (tree.nodeTag(node)) { |
| 11263 | switch (node_tags[node]) { | ||
| 11264 | .container_decl, | 11085 | .container_decl, |
| 11265 | .container_decl_trailing, | 11086 | .container_decl_trailing, |
| 11266 | .container_decl_two, | 11087 | .container_decl_two, |
| ... | @@ -11275,7 +11096,7 @@ fn nodeUsesAnonNameStrategy(tree: *const Ast, node: Ast.Node.Index) bool { | ... | @@ -11275,7 +11096,7 @@ fn nodeUsesAnonNameStrategy(tree: *const Ast, node: Ast.Node.Index) bool { |
| 11275 | .tagged_union_enum_tag_trailing, | 11096 | .tagged_union_enum_tag_trailing, |
| 11276 | => return true, | 11097 | => return true, |
| 11277 | .builtin_call_two, .builtin_call_two_comma, .builtin_call, .builtin_call_comma => { | 11098 | .builtin_call_two, .builtin_call_two_comma, .builtin_call, .builtin_call_comma => { |
| 11278 | const builtin_token = tree.nodes.items(.main_token)[node]; | 11099 | const builtin_token = tree.nodeMainToken(node); |
| 11279 | const builtin_name = tree.tokenSlice(builtin_token); | 11100 | const builtin_name = tree.tokenSlice(builtin_token); |
| 11280 | return std.mem.eql(u8, builtin_name, "@Type"); | 11101 | return std.mem.eql(u8, builtin_name, "@Type"); |
| 11281 | }, | 11102 | }, |
| ... | @@ -11508,8 +11329,7 @@ fn rvalueInner( | ... | @@ -11508,8 +11329,7 @@ fn rvalueInner( |
| 11508 | /// See also `appendIdentStr` and `parseStrLit`. | 11329 | /// See also `appendIdentStr` and `parseStrLit`. |
| 11509 | fn identifierTokenString(astgen: *AstGen, token: Ast.TokenIndex) InnerError![]const u8 { | 11330 | fn identifierTokenString(astgen: *AstGen, token: Ast.TokenIndex) InnerError![]const u8 { |
| 11510 | const tree = astgen.tree; | 11331 | const tree = astgen.tree; |
| 11511 | const token_tags = tree.tokens.items(.tag); | 11332 | assert(tree.tokenTag(token) == .identifier); |
| 11512 | assert(token_tags[token] == .identifier); | ||
| 11513 | const ident_name = tree.tokenSlice(token); | 11333 | const ident_name = tree.tokenSlice(token); |
| 11514 | if (!mem.startsWith(u8, ident_name, "@")) { | 11334 | if (!mem.startsWith(u8, ident_name, "@")) { |
| 11515 | return ident_name; | 11335 | return ident_name; |
| ... | @@ -11535,8 +11355,7 @@ fn appendIdentStr( | ... | @@ -11535,8 +11355,7 @@ fn appendIdentStr( |
| 11535 | buf: *ArrayListUnmanaged(u8), | 11355 | buf: *ArrayListUnmanaged(u8), |
| 11536 | ) InnerError!void { | 11356 | ) InnerError!void { |
| 11537 | const tree = astgen.tree; | 11357 | const tree = astgen.tree; |
| 11538 | const token_tags = tree.tokens.items(.tag); | 11358 | assert(tree.tokenTag(token) == .identifier); |
| 11539 | assert(token_tags[token] == .identifier); | ||
| 11540 | const ident_name = tree.tokenSlice(token); | 11359 | const ident_name = tree.tokenSlice(token); |
| 11541 | if (!mem.startsWith(u8, ident_name, "@")) { | 11360 | if (!mem.startsWith(u8, ident_name, "@")) { |
| 11542 | return buf.appendSlice(astgen.gpa, ident_name); | 11361 | return buf.appendSlice(astgen.gpa, ident_name); |
| ... | @@ -11625,8 +11444,8 @@ fn appendErrorNodeNotes( | ... | @@ -11625,8 +11444,8 @@ fn appendErrorNodeNotes( |
| 11625 | } else 0; | 11444 | } else 0; |
| 11626 | try astgen.compile_errors.append(astgen.gpa, .{ | 11445 | try astgen.compile_errors.append(astgen.gpa, .{ |
| 11627 | .msg = msg, | 11446 | .msg = msg, |
| 11628 | .node = node, | 11447 | .node = node.toOptional(), |
| 11629 | .token = 0, | 11448 | .token = .none, |
| 11630 | .byte_offset = 0, | 11449 | .byte_offset = 0, |
| 11631 | .notes = notes_index, | 11450 | .notes = notes_index, |
| 11632 | }); | 11451 | }); |
| ... | @@ -11717,8 +11536,8 @@ fn appendErrorTokNotesOff( | ... | @@ -11717,8 +11536,8 @@ fn appendErrorTokNotesOff( |
| 11717 | } else 0; | 11536 | } else 0; |
| 11718 | try astgen.compile_errors.append(gpa, .{ | 11537 | try astgen.compile_errors.append(gpa, .{ |
| 11719 | .msg = msg, | 11538 | .msg = msg, |
| 11720 | .node = 0, | 11539 | .node = .none, |
| 11721 | .token = token, | 11540 | .token = .fromToken(token), |
| 11722 | .byte_offset = byte_offset, | 11541 | .byte_offset = byte_offset, |
| 11723 | .notes = notes_index, | 11542 | .notes = notes_index, |
| 11724 | }); | 11543 | }); |
| ... | @@ -11746,8 +11565,8 @@ fn errNoteTokOff( | ... | @@ -11746,8 +11565,8 @@ fn errNoteTokOff( |
| 11746 | try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args); | 11565 | try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args); |
| 11747 | return astgen.addExtra(Zir.Inst.CompileErrors.Item{ | 11566 | return astgen.addExtra(Zir.Inst.CompileErrors.Item{ |
| 11748 | .msg = msg, | 11567 | .msg = msg, |
| 11749 | .node = 0, | 11568 | .node = .none, |
| 11750 | .token = token, | 11569 | .token = .fromToken(token), |
| 11751 | .byte_offset = byte_offset, | 11570 | .byte_offset = byte_offset, |
| 11752 | .notes = 0, | 11571 | .notes = 0, |
| 11753 | }); | 11572 | }); |
| ... | @@ -11765,8 +11584,8 @@ fn errNoteNode( | ... | @@ -11765,8 +11584,8 @@ fn errNoteNode( |
| 11765 | try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args); | 11584 | try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args); |
| 11766 | return astgen.addExtra(Zir.Inst.CompileErrors.Item{ | 11585 | return astgen.addExtra(Zir.Inst.CompileErrors.Item{ |
| 11767 | .msg = msg, | 11586 | .msg = msg, |
| 11768 | .node = node, | 11587 | .node = node.toOptional(), |
| 11769 | .token = 0, | 11588 | .token = .none, |
| 11770 | .byte_offset = 0, | 11589 | .byte_offset = 0, |
| 11771 | .notes = 0, | 11590 | .notes = 0, |
| 11772 | }); | 11591 | }); |
| ... | @@ -11832,10 +11651,8 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice { | ... | @@ -11832,10 +11651,8 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice { |
| 11832 | 11651 | ||
| 11833 | fn strLitNodeAsString(astgen: *AstGen, node: Ast.Node.Index) !IndexSlice { | 11652 | fn strLitNodeAsString(astgen: *AstGen, node: Ast.Node.Index) !IndexSlice { |
| 11834 | const tree = astgen.tree; | 11653 | const tree = astgen.tree; |
| 11835 | const node_datas = tree.nodes.items(.data); | ||
| 11836 | 11654 | ||
| 11837 | const start = node_datas[node].lhs; | 11655 | const start, const end = tree.nodeData(node).token_and_token; |
| 11838 | const end = node_datas[node].rhs; | ||
| 11839 | 11656 | ||
| 11840 | const gpa = astgen.gpa; | 11657 | const gpa = astgen.gpa; |
| 11841 | const string_bytes = &astgen.string_bytes; | 11658 | const string_bytes = &astgen.string_bytes; |
| ... | @@ -11930,11 +11747,11 @@ const Scope = struct { | ... | @@ -11930,11 +11747,11 @@ const Scope = struct { |
| 11930 | /// Source location of the corresponding variable declaration. | 11747 | /// Source location of the corresponding variable declaration. |
| 11931 | token_src: Ast.TokenIndex, | 11748 | token_src: Ast.TokenIndex, |
| 11932 | /// Track the first identifier where it is referenced. | 11749 | /// Track the first identifier where it is referenced. |
| 11933 | /// 0 means never referenced. | 11750 | /// .none means never referenced. |
| 11934 | used: Ast.TokenIndex = 0, | 11751 | used: Ast.OptionalTokenIndex = .none, |
| 11935 | /// Track the identifier where it is discarded, like this `_ = foo;`. | 11752 | /// Track the identifier where it is discarded, like this `_ = foo;`. |
| 11936 | /// 0 means never discarded. | 11753 | /// .none means never discarded. |
| 11937 | discarded: Ast.TokenIndex = 0, | 11754 | discarded: Ast.OptionalTokenIndex = .none, |
| 11938 | is_used_or_discarded: ?*bool = null, | 11755 | is_used_or_discarded: ?*bool = null, |
| 11939 | /// String table index. | 11756 | /// String table index. |
| 11940 | name: Zir.NullTerminatedString, | 11757 | name: Zir.NullTerminatedString, |
| ... | @@ -11954,11 +11771,11 @@ const Scope = struct { | ... | @@ -11954,11 +11771,11 @@ const Scope = struct { |
| 11954 | /// Source location of the corresponding variable declaration. | 11771 | /// Source location of the corresponding variable declaration. |
| 11955 | token_src: Ast.TokenIndex, | 11772 | token_src: Ast.TokenIndex, |
| 11956 | /// Track the first identifier where it is referenced. | 11773 | /// Track the first identifier where it is referenced. |
| 11957 | /// 0 means never referenced. | 11774 | /// .none means never referenced. |
| 11958 | used: Ast.TokenIndex = 0, | 11775 | used: Ast.OptionalTokenIndex = .none, |
| 11959 | /// Track the identifier where it is discarded, like this `_ = foo;`. | 11776 | /// Track the identifier where it is discarded, like this `_ = foo;`. |
| 11960 | /// 0 means never discarded. | 11777 | /// .none means never discarded. |
| 11961 | discarded: Ast.TokenIndex = 0, | 11778 | discarded: Ast.OptionalTokenIndex = .none, |
| 11962 | /// Whether this value is used as an lvalue after initialization. | 11779 | /// Whether this value is used as an lvalue after initialization. |
| 11963 | /// If not, we know it can be `const`, so will emit a compile error if it is `var`. | 11780 | /// If not, we know it can be `const`, so will emit a compile error if it is `var`. |
| 11964 | used_as_lvalue: bool = false, | 11781 | used_as_lvalue: bool = false, |
| ... | @@ -12053,12 +11870,12 @@ const GenZir = struct { | ... | @@ -12053,12 +11870,12 @@ const GenZir = struct { |
| 12053 | break_result_info: AstGen.ResultInfo = undefined, | 11870 | break_result_info: AstGen.ResultInfo = undefined, |
| 12054 | continue_result_info: AstGen.ResultInfo = undefined, | 11871 | continue_result_info: AstGen.ResultInfo = undefined, |
| 12055 | 11872 | ||
| 12056 | suspend_node: Ast.Node.Index = 0, | 11873 | suspend_node: Ast.Node.OptionalIndex = .none, |
| 12057 | nosuspend_node: Ast.Node.Index = 0, | 11874 | nosuspend_node: Ast.Node.OptionalIndex = .none, |
| 12058 | /// Set if this GenZir is a defer. | 11875 | /// Set if this GenZir is a defer. |
| 12059 | cur_defer_node: Ast.Node.Index = 0, | 11876 | cur_defer_node: Ast.Node.OptionalIndex = .none, |
| 12060 | // Set if this GenZir is a defer or it is inside a defer. | 11877 | // Set if this GenZir is a defer or it is inside a defer. |
| 12061 | any_defer_node: Ast.Node.Index = 0, | 11878 | any_defer_node: Ast.Node.OptionalIndex = .none, |
| 12062 | 11879 | ||
| 12063 | const unstacked_top = std.math.maxInt(usize); | 11880 | const unstacked_top = std.math.maxInt(usize); |
| 12064 | /// Call unstack before adding any new instructions to containing GenZir. | 11881 | /// Call unstack before adding any new instructions to containing GenZir. |
| ... | @@ -12139,12 +11956,12 @@ const GenZir = struct { | ... | @@ -12139,12 +11956,12 @@ const GenZir = struct { |
| 12139 | return false; | 11956 | return false; |
| 12140 | } | 11957 | } |
| 12141 | 11958 | ||
| 12142 | fn nodeIndexToRelative(gz: GenZir, node_index: Ast.Node.Index) i32 { | 11959 | fn nodeIndexToRelative(gz: GenZir, node_index: Ast.Node.Index) Ast.Node.Offset { |
| 12143 | return @as(i32, @bitCast(node_index)) - @as(i32, @bitCast(gz.decl_node_index)); | 11960 | return gz.decl_node_index.toOffset(node_index); |
| 12144 | } | 11961 | } |
| 12145 | 11962 | ||
| 12146 | fn tokenIndexToRelative(gz: GenZir, token: Ast.TokenIndex) u32 { | 11963 | fn tokenIndexToRelative(gz: GenZir, token: Ast.TokenIndex) Ast.TokenOffset { |
| 12147 | return token - gz.srcToken(); | 11964 | return .init(gz.srcToken(), token); |
| 12148 | } | 11965 | } |
| 12149 | 11966 | ||
| 12150 | fn srcToken(gz: GenZir) Ast.TokenIndex { | 11967 | fn srcToken(gz: GenZir) Ast.TokenIndex { |
| ... | @@ -12297,7 +12114,7 @@ const GenZir = struct { | ... | @@ -12297,7 +12114,7 @@ const GenZir = struct { |
| 12297 | proto_hash: std.zig.SrcHash, | 12114 | proto_hash: std.zig.SrcHash, |
| 12298 | }, | 12115 | }, |
| 12299 | ) !Zir.Inst.Ref { | 12116 | ) !Zir.Inst.Ref { |
| 12300 | assert(args.src_node != 0); | 12117 | assert(args.src_node != .root); |
| 12301 | const astgen = gz.astgen; | 12118 | const astgen = gz.astgen; |
| 12302 | const gpa = astgen.gpa; | 12119 | const gpa = astgen.gpa; |
| 12303 | const ret_ref = if (args.ret_ref == .void_type) .none else args.ret_ref; | 12120 | const ret_ref = if (args.ret_ref == .void_type) .none else args.ret_ref; |
| ... | @@ -12329,13 +12146,13 @@ const GenZir = struct { | ... | @@ -12329,13 +12146,13 @@ const GenZir = struct { |
| 12329 | var src_locs_and_hash_buffer: [7]u32 = undefined; | 12146 | var src_locs_and_hash_buffer: [7]u32 = undefined; |
| 12330 | const src_locs_and_hash: []const u32 = if (args.body_gz != null) src_locs_and_hash: { | 12147 | const src_locs_and_hash: []const u32 = if (args.body_gz != null) src_locs_and_hash: { |
| 12331 | const tree = astgen.tree; | 12148 | const tree = astgen.tree; |
| 12332 | const node_tags = tree.nodes.items(.tag); | ||
| 12333 | const node_datas = tree.nodes.items(.data); | ||
| 12334 | const token_starts = tree.tokens.items(.start); | ||
| 12335 | const fn_decl = args.src_node; | 12149 | const fn_decl = args.src_node; |
| 12336 | assert(node_tags[fn_decl] == .fn_decl or node_tags[fn_decl] == .test_decl); | 12150 | const block = switch (tree.nodeTag(fn_decl)) { |
| 12337 | const block = node_datas[fn_decl].rhs; | 12151 | .fn_decl => tree.nodeData(fn_decl).node_and_node[1], |
| 12338 | const rbrace_start = token_starts[tree.lastToken(block)]; | 12152 | .test_decl => tree.nodeData(fn_decl).opt_token_and_node[1], |
| 12153 | else => unreachable, | ||
| 12154 | }; | ||
| 12155 | const rbrace_start = tree.tokenStart(tree.lastToken(block)); | ||
| 12339 | astgen.advanceSourceCursor(rbrace_start); | 12156 | astgen.advanceSourceCursor(rbrace_start); |
| 12340 | const rbrace_line: u32 = @intCast(astgen.source_line - gz.decl_line); | 12157 | const rbrace_line: u32 = @intCast(astgen.source_line - gz.decl_line); |
| 12341 | const rbrace_column: u32 = @intCast(astgen.source_column); | 12158 | const rbrace_column: u32 = @intCast(astgen.source_column); |
| ... | @@ -12742,7 +12559,7 @@ const GenZir = struct { | ... | @@ -12742,7 +12559,7 @@ const GenZir = struct { |
| 12742 | .data = .{ .extended = .{ | 12559 | .data = .{ .extended = .{ |
| 12743 | .opcode = opcode, | 12560 | .opcode = opcode, |
| 12744 | .small = small, | 12561 | .small = small, |
| 12745 | .operand = @bitCast(gz.nodeIndexToRelative(src_node)), | 12562 | .operand = @bitCast(@intFromEnum(gz.nodeIndexToRelative(src_node))), |
| 12746 | } }, | 12563 | } }, |
| 12747 | }); | 12564 | }); |
| 12748 | gz.instructions.appendAssumeCapacity(new_index); | 12565 | gz.instructions.appendAssumeCapacity(new_index); |
| ... | @@ -12931,9 +12748,9 @@ const GenZir = struct { | ... | @@ -12931,9 +12748,9 @@ const GenZir = struct { |
| 12931 | .operand = operand, | 12748 | .operand = operand, |
| 12932 | .payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Break{ | 12749 | .payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Break{ |
| 12933 | .operand_src_node = if (operand_src_node) |src_node| | 12750 | .operand_src_node = if (operand_src_node) |src_node| |
| 12934 | gz.nodeIndexToRelative(src_node) | 12751 | gz.nodeIndexToRelative(src_node).toOptional() |
| 12935 | else | 12752 | else |
| 12936 | Zir.Inst.Break.no_src_node, | 12753 | .none, |
| 12937 | .block_inst = block_inst, | 12754 | .block_inst = block_inst, |
| 12938 | }), | 12755 | }), |
| 12939 | } }, | 12756 | } }, |
| ... | @@ -13022,7 +12839,7 @@ const GenZir = struct { | ... | @@ -13022,7 +12839,7 @@ const GenZir = struct { |
| 13022 | .data = .{ .extended = .{ | 12839 | .data = .{ .extended = .{ |
| 13023 | .opcode = opcode, | 12840 | .opcode = opcode, |
| 13024 | .small = undefined, | 12841 | .small = undefined, |
| 13025 | .operand = @bitCast(gz.nodeIndexToRelative(src_node)), | 12842 | .operand = @bitCast(@intFromEnum(gz.nodeIndexToRelative(src_node))), |
| 13026 | } }, | 12843 | } }, |
| 13027 | }); | 12844 | }); |
| 13028 | } | 12845 | } |
| ... | @@ -13202,8 +13019,8 @@ const GenZir = struct { | ... | @@ -13202,8 +13019,8 @@ const GenZir = struct { |
| 13202 | const astgen = gz.astgen; | 13019 | const astgen = gz.astgen; |
| 13203 | const gpa = astgen.gpa; | 13020 | const gpa = astgen.gpa; |
| 13204 | 13021 | ||
| 13205 | // Node 0 is valid for the root `struct_decl` of a file! | 13022 | // Node .root is valid for the root `struct_decl` of a file! |
| 13206 | assert(args.src_node != 0 or gz.parent.tag == .top); | 13023 | assert(args.src_node != .root or gz.parent.tag == .top); |
| 13207 | 13024 | ||
| 13208 | const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash); | 13025 | const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash); |
| 13209 | 13026 | ||
| ... | @@ -13263,7 +13080,7 @@ const GenZir = struct { | ... | @@ -13263,7 +13080,7 @@ const GenZir = struct { |
| 13263 | const astgen = gz.astgen; | 13080 | const astgen = gz.astgen; |
| 13264 | const gpa = astgen.gpa; | 13081 | const gpa = astgen.gpa; |
| 13265 | 13082 | ||
| 13266 | assert(args.src_node != 0); | 13083 | assert(args.src_node != .root); |
| 13267 | 13084 | ||
| 13268 | const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash); | 13085 | const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash); |
| 13269 | 13086 | ||
| ... | @@ -13325,7 +13142,7 @@ const GenZir = struct { | ... | @@ -13325,7 +13142,7 @@ const GenZir = struct { |
| 13325 | const astgen = gz.astgen; | 13142 | const astgen = gz.astgen; |
| 13326 | const gpa = astgen.gpa; | 13143 | const gpa = astgen.gpa; |
| 13327 | 13144 | ||
| 13328 | assert(args.src_node != 0); | 13145 | assert(args.src_node != .root); |
| 13329 | 13146 | ||
| 13330 | const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash); | 13147 | const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash); |
| 13331 | 13148 | ||
| ... | @@ -13380,7 +13197,7 @@ const GenZir = struct { | ... | @@ -13380,7 +13197,7 @@ const GenZir = struct { |
| 13380 | const astgen = gz.astgen; | 13197 | const astgen = gz.astgen; |
| 13381 | const gpa = astgen.gpa; | 13198 | const gpa = astgen.gpa; |
| 13382 | 13199 | ||
| 13383 | assert(args.src_node != 0); | 13200 | assert(args.src_node != .root); |
| 13384 | 13201 | ||
| 13385 | try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.OpaqueDecl).@"struct".fields.len + 2); | 13202 | try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.OpaqueDecl).@"struct".fields.len + 2); |
| 13386 | const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.OpaqueDecl{ | 13203 | const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.OpaqueDecl{ |
| ... | @@ -13574,9 +13391,7 @@ fn maybeAdvanceSourceCursorToMainToken(gz: *GenZir, node: Ast.Node.Index) LineCo | ... | @@ -13574,9 +13391,7 @@ fn maybeAdvanceSourceCursorToMainToken(gz: *GenZir, node: Ast.Node.Index) LineCo |
| 13574 | if (gz.is_comptime) return .{ gz.astgen.source_line - gz.decl_line, gz.astgen.source_column }; | 13391 | if (gz.is_comptime) return .{ gz.astgen.source_line - gz.decl_line, gz.astgen.source_column }; |
| 13575 | 13392 | ||
| 13576 | const tree = gz.astgen.tree; | 13393 | const tree = gz.astgen.tree; |
| 13577 | const token_starts = tree.tokens.items(.start); | 13394 | const node_start = tree.tokenStart(tree.nodeMainToken(node)); |
| 13578 | const main_tokens = tree.nodes.items(.main_token); | ||
| 13579 | const node_start = token_starts[main_tokens[node]]; | ||
| 13580 | gz.astgen.advanceSourceCursor(node_start); | 13395 | gz.astgen.advanceSourceCursor(node_start); |
| 13581 | 13396 | ||
| 13582 | return .{ gz.astgen.source_line - gz.decl_line, gz.astgen.source_column }; | 13397 | return .{ gz.astgen.source_line - gz.decl_line, gz.astgen.source_column }; |
| ... | @@ -13585,8 +13400,7 @@ fn maybeAdvanceSourceCursorToMainToken(gz: *GenZir, node: Ast.Node.Index) LineCo | ... | @@ -13585,8 +13400,7 @@ fn maybeAdvanceSourceCursorToMainToken(gz: *GenZir, node: Ast.Node.Index) LineCo |
| 13585 | /// Advances the source cursor to the beginning of `node`. | 13400 | /// Advances the source cursor to the beginning of `node`. |
| 13586 | fn advanceSourceCursorToNode(astgen: *AstGen, node: Ast.Node.Index) void { | 13401 | fn advanceSourceCursorToNode(astgen: *AstGen, node: Ast.Node.Index) void { |
| 13587 | const tree = astgen.tree; | 13402 | const tree = astgen.tree; |
| 13588 | const token_starts = tree.tokens.items(.start); | 13403 | const node_start = tree.tokenStart(tree.firstToken(node)); |
| 13589 | const node_start = token_starts[tree.firstToken(node)]; | ||
| 13590 | astgen.advanceSourceCursor(node_start); | 13404 | astgen.advanceSourceCursor(node_start); |
| 13591 | } | 13405 | } |
| 13592 | 13406 | ||
| ... | @@ -13641,9 +13455,6 @@ fn scanContainer( | ... | @@ -13641,9 +13455,6 @@ fn scanContainer( |
| 13641 | ) !u32 { | 13455 | ) !u32 { |
| 13642 | const gpa = astgen.gpa; | 13456 | const gpa = astgen.gpa; |
| 13643 | const tree = astgen.tree; | 13457 | const tree = astgen.tree; |
| 13644 | const node_tags = tree.nodes.items(.tag); | ||
| 13645 | const main_tokens = tree.nodes.items(.main_token); | ||
| 13646 | const token_tags = tree.tokens.items(.tag); | ||
| 13647 | 13458 | ||
| 13648 | var any_invalid_declarations = false; | 13459 | var any_invalid_declarations = false; |
| 13649 | 13460 | ||
| ... | @@ -13673,7 +13484,7 @@ fn scanContainer( | ... | @@ -13673,7 +13484,7 @@ fn scanContainer( |
| 13673 | var decl_count: u32 = 0; | 13484 | var decl_count: u32 = 0; |
| 13674 | for (members) |member_node| { | 13485 | for (members) |member_node| { |
| 13675 | const Kind = enum { decl, field }; | 13486 | const Kind = enum { decl, field }; |
| 13676 | const kind: Kind, const name_token = switch (node_tags[member_node]) { | 13487 | const kind: Kind, const name_token = switch (tree.nodeTag(member_node)) { |
| 13677 | .container_field_init, | 13488 | .container_field_init, |
| 13678 | .container_field_align, | 13489 | .container_field_align, |
| 13679 | .container_field, | 13490 | .container_field, |
| ... | @@ -13681,7 +13492,7 @@ fn scanContainer( | ... | @@ -13681,7 +13492,7 @@ fn scanContainer( |
| 13681 | var full = tree.fullContainerField(member_node).?; | 13492 | var full = tree.fullContainerField(member_node).?; |
| 13682 | switch (container_kind) { | 13493 | switch (container_kind) { |
| 13683 | .@"struct", .@"opaque" => {}, | 13494 | .@"struct", .@"opaque" => {}, |
| 13684 | .@"union", .@"enum" => full.convertToNonTupleLike(astgen.tree.nodes), | 13495 | .@"union", .@"enum" => full.convertToNonTupleLike(astgen.tree), |
| 13685 | } | 13496 | } |
| 13686 | if (full.ast.tuple_like) continue; | 13497 | if (full.ast.tuple_like) continue; |
| 13687 | break :blk .{ .field, full.ast.main_token }; | 13498 | break :blk .{ .field, full.ast.main_token }; |
| ... | @@ -13693,7 +13504,7 @@ fn scanContainer( | ... | @@ -13693,7 +13504,7 @@ fn scanContainer( |
| 13693 | .aligned_var_decl, | 13504 | .aligned_var_decl, |
| 13694 | => blk: { | 13505 | => blk: { |
| 13695 | decl_count += 1; | 13506 | decl_count += 1; |
| 13696 | break :blk .{ .decl, main_tokens[member_node] + 1 }; | 13507 | break :blk .{ .decl, tree.nodeMainToken(member_node) + 1 }; |
| 13697 | }, | 13508 | }, |
| 13698 | 13509 | ||
| 13699 | .fn_proto_simple, | 13510 | .fn_proto_simple, |
| ... | @@ -13703,8 +13514,8 @@ fn scanContainer( | ... | @@ -13703,8 +13514,8 @@ fn scanContainer( |
| 13703 | .fn_decl, | 13514 | .fn_decl, |
| 13704 | => blk: { | 13515 | => blk: { |
| 13705 | decl_count += 1; | 13516 | decl_count += 1; |
| 13706 | const ident = main_tokens[member_node] + 1; | 13517 | const ident = tree.nodeMainToken(member_node) + 1; |
| 13707 | if (token_tags[ident] != .identifier) { | 13518 | if (tree.tokenTag(ident) != .identifier) { |
| 13708 | try astgen.appendErrorNode(member_node, "missing function name", .{}); | 13519 | try astgen.appendErrorNode(member_node, "missing function name", .{}); |
| 13709 | any_invalid_declarations = true; | 13520 | any_invalid_declarations = true; |
| 13710 | continue; | 13521 | continue; |
| ... | @@ -13721,12 +13532,12 @@ fn scanContainer( | ... | @@ -13721,12 +13532,12 @@ fn scanContainer( |
| 13721 | decl_count += 1; | 13532 | decl_count += 1; |
| 13722 | // We don't want shadowing detection here, and test names work a bit differently, so | 13533 | // We don't want shadowing detection here, and test names work a bit differently, so |
| 13723 | // we must do the redeclaration detection ourselves. | 13534 | // we must do the redeclaration detection ourselves. |
| 13724 | const test_name_token = main_tokens[member_node] + 1; | 13535 | const test_name_token = tree.nodeMainToken(member_node) + 1; |
| 13725 | const new_ent: NameEntry = .{ | 13536 | const new_ent: NameEntry = .{ |
| 13726 | .tok = test_name_token, | 13537 | .tok = test_name_token, |
| 13727 | .next = null, | 13538 | .next = null, |
| 13728 | }; | 13539 | }; |
| 13729 | switch (token_tags[test_name_token]) { | 13540 | switch (tree.tokenTag(test_name_token)) { |
| 13730 | else => {}, // unnamed test | 13541 | else => {}, // unnamed test |
| 13731 | .string_literal => { | 13542 | .string_literal => { |
| 13732 | const name = try astgen.strLitAsString(test_name_token); | 13543 | const name = try astgen.strLitAsString(test_name_token); |
| ... | @@ -14328,3 +14139,7 @@ fn fetchRemoveRefEntries(astgen: *AstGen, param_insts: []const Zir.Inst.Index) ! | ... | @@ -14328,3 +14139,7 @@ fn fetchRemoveRefEntries(astgen: *AstGen, param_insts: []const Zir.Inst.Index) ! |
| 14328 | } | 14139 | } |
| 14329 | return refs.items; | 14140 | return refs.items; |
| 14330 | } | 14141 | } |
| 14142 | |||
| 14143 | test { | ||
| 14144 | _ = &generate; | ||
| 14145 | } |
lib/std/zig/AstRlAnnotate.zig+173-164| ... | @@ -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 | ||
| ... | @@ -313,17 +322,13 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -313,17 +322,13 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 313 | .error_set_decl, | 322 | .error_set_decl, |
| 314 | => return false, | 323 | => return false, |
| 315 | 324 | ||
| 316 | .builtin_call_two, .builtin_call_two_comma => { | 325 | .builtin_call_two, |
| 317 | if (node_datas[node].lhs == 0) { | 326 | .builtin_call_two_comma, |
| 318 | return astrl.builtinCall(block, ri, node, &.{}); | 327 | .builtin_call, |
| 319 | } else if (node_datas[node].rhs == 0) { | 328 | .builtin_call_comma, |
| 320 | return astrl.builtinCall(block, ri, node, &.{node_datas[node].lhs}); | 329 | => { |
| 321 | } else { | 330 | var buf: [2]Ast.Node.Index = undefined; |
| 322 | return astrl.builtinCall(block, ri, node, &.{ node_datas[node].lhs, node_datas[node].rhs }); | 331 | const params = tree.builtinCallParams(&buf, node).?; |
| 323 | } | ||
| 324 | }, | ||
| 325 | .builtin_call, .builtin_call_comma => { | ||
| 326 | const params = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; | ||
| 327 | return astrl.builtinCall(block, ri, node, params); | 332 | return astrl.builtinCall(block, ri, node, params); |
| 328 | }, | 333 | }, |
| 329 | 334 | ||
| ... | @@ -342,7 +347,7 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -342,7 +347,7 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 342 | for (full.ast.params) |param_node| { | 347 | for (full.ast.params) |param_node| { |
| 343 | _ = try astrl.expr(param_node, block, ResultInfo.type_only); | 348 | _ = try astrl.expr(param_node, block, ResultInfo.type_only); |
| 344 | } | 349 | } |
| 345 | return switch (node_tags[node]) { | 350 | return switch (tree.nodeTag(node)) { |
| 346 | .call_one, | 351 | .call_one, |
| 347 | .call_one_comma, | 352 | .call_one_comma, |
| 348 | .call, | 353 | .call, |
| ... | @@ -358,8 +363,8 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -358,8 +363,8 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 358 | }, | 363 | }, |
| 359 | 364 | ||
| 360 | .@"return" => { | 365 | .@"return" => { |
| 361 | if (node_datas[node].lhs != 0) { | 366 | if (tree.nodeData(node).opt_node.unwrap()) |lhs| { |
| 362 | 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); |
| 363 | if (ret_val_consumes_rl) { | 368 | if (ret_val_consumes_rl) { |
| 364 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | 369 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); |
| 365 | } | 370 | } |
| ... | @@ -368,7 +373,8 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -368,7 +373,8 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 368 | }, | 373 | }, |
| 369 | 374 | ||
| 370 | .field_access => { | 375 | .field_access => { |
| 371 | _ = 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); | ||
| 372 | return false; | 378 | return false; |
| 373 | }, | 379 | }, |
| 374 | 380 | ||
| ... | @@ -380,15 +386,15 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -380,15 +386,15 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 380 | _ = 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 |
| 381 | } | 387 | } |
| 382 | 388 | ||
| 383 | if (full.ast.else_expr == 0) { | 389 | if (full.ast.else_expr.unwrap()) |else_expr| { |
| 384 | _ = try astrl.expr(full.ast.then_expr, block, ResultInfo.none); | ||
| 385 | return false; | ||
| 386 | } else { | ||
| 387 | 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); |
| 388 | 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); |
| 389 | const uses_rl = then_uses_rl or else_uses_rl; | 392 | const uses_rl = then_uses_rl or else_uses_rl; |
| 390 | 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, {}); |
| 391 | return uses_rl; | 394 | return uses_rl; |
| 395 | } else { | ||
| 396 | _ = try astrl.expr(full.ast.then_expr, block, ResultInfo.none); | ||
| 397 | return false; | ||
| 392 | } | 398 | } |
| 393 | }, | 399 | }, |
| 394 | 400 | ||
| ... | @@ -409,12 +415,12 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -409,12 +415,12 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 409 | .ri = ri, | 415 | .ri = ri, |
| 410 | .consumes_res_ptr = false, | 416 | .consumes_res_ptr = false, |
| 411 | }; | 417 | }; |
| 412 | if (full.ast.cont_expr != 0) { | 418 | if (full.ast.cont_expr.unwrap()) |cont_expr| { |
| 413 | _ = try astrl.expr(full.ast.cont_expr, &new_block, ResultInfo.none); | 419 | _ = try astrl.expr(cont_expr, &new_block, ResultInfo.none); |
| 414 | } | 420 | } |
| 415 | _ = try astrl.expr(full.ast.then_expr, &new_block, ResultInfo.none); | 421 | _ = try astrl.expr(full.ast.then_expr, &new_block, ResultInfo.none); |
| 416 | 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: { |
| 417 | break :else_rl try astrl.expr(full.ast.else_expr, block, ri); | 423 | break :else_rl try astrl.expr(else_expr, block, ri); |
| 418 | } else false; | 424 | } else false; |
| 419 | if (new_block.consumes_res_ptr or else_consumes_rl) { | 425 | if (new_block.consumes_res_ptr or else_consumes_rl) { |
| 420 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | 426 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); |
| ... | @@ -430,10 +436,11 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -430,10 +436,11 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 430 | break :label try astrl.identString(label_token); | 436 | break :label try astrl.identString(label_token); |
| 431 | } else null; | 437 | } else null; |
| 432 | for (full.ast.inputs) |input| { | 438 | for (full.ast.inputs) |input| { |
| 433 | if (node_tags[input] == .for_range) { | 439 | if (tree.nodeTag(input) == .for_range) { |
| 434 | _ = try astrl.expr(node_datas[input].lhs, block, ResultInfo.type_only); | 440 | const lhs, const opt_rhs = tree.nodeData(input).node_and_opt_node; |
| 435 | if (node_datas[input].rhs != 0) { | 441 | _ = try astrl.expr(lhs, block, ResultInfo.type_only); |
| 436 | _ = 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); | ||
| 437 | } | 444 | } |
| 438 | } else { | 445 | } else { |
| 439 | _ = try astrl.expr(input, block, ResultInfo.none); | 446 | _ = try astrl.expr(input, block, ResultInfo.none); |
| ... | @@ -447,8 +454,8 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -447,8 +454,8 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 447 | .consumes_res_ptr = false, | 454 | .consumes_res_ptr = false, |
| 448 | }; | 455 | }; |
| 449 | _ = try astrl.expr(full.ast.then_expr, &new_block, ResultInfo.none); | 456 | _ = try astrl.expr(full.ast.then_expr, &new_block, ResultInfo.none); |
| 450 | 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: { |
| 451 | break :else_rl try astrl.expr(full.ast.else_expr, block, ri); | 458 | break :else_rl try astrl.expr(else_expr, block, ri); |
| 452 | } else false; | 459 | } else false; |
| 453 | if (new_block.consumes_res_ptr or else_consumes_rl) { | 460 | if (new_block.consumes_res_ptr or else_consumes_rl) { |
| 454 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | 461 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); |
| ... | @@ -459,66 +466,68 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -459,66 +466,68 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 459 | }, | 466 | }, |
| 460 | 467 | ||
| 461 | .slice_open => { | 468 | .slice_open => { |
| 462 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 469 | const sliced, const start = tree.nodeData(node).node_and_node; |
| 463 | _ = 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); | ||
| 464 | return false; | 472 | return false; |
| 465 | }, | 473 | }, |
| 466 | .slice => { | 474 | .slice => { |
| 467 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.Slice); | 475 | const sliced, const extra_index = tree.nodeData(node).node_and_extra; |
| 468 | _ = 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); | ||
| 469 | _ = try astrl.expr(extra.start, block, ResultInfo.type_only); | 478 | _ = try astrl.expr(extra.start, block, ResultInfo.type_only); |
| 470 | _ = try astrl.expr(extra.end, block, ResultInfo.type_only); | 479 | _ = try astrl.expr(extra.end, block, ResultInfo.type_only); |
| 471 | return false; | 480 | return false; |
| 472 | }, | 481 | }, |
| 473 | .slice_sentinel => { | 482 | .slice_sentinel => { |
| 474 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.SliceSentinel); | 483 | const sliced, const extra_index = tree.nodeData(node).node_and_extra; |
| 475 | _ = 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); | ||
| 476 | _ = try astrl.expr(extra.start, block, ResultInfo.type_only); | 486 | _ = try astrl.expr(extra.start, block, ResultInfo.type_only); |
| 477 | if (extra.end != 0) { | 487 | if (extra.end.unwrap()) |end| { |
| 478 | _ = try astrl.expr(extra.end, block, ResultInfo.type_only); | 488 | _ = try astrl.expr(end, block, ResultInfo.type_only); |
| 479 | } | 489 | } |
| 480 | _ = try astrl.expr(extra.sentinel, block, ResultInfo.none); | 490 | _ = try astrl.expr(extra.sentinel, block, ResultInfo.none); |
| 481 | return false; | 491 | return false; |
| 482 | }, | 492 | }, |
| 483 | .deref => { | 493 | .deref => { |
| 484 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 494 | _ = try astrl.expr(tree.nodeData(node).node, block, ResultInfo.none); |
| 485 | return false; | 495 | return false; |
| 486 | }, | 496 | }, |
| 487 | .address_of => { | 497 | .address_of => { |
| 488 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 498 | _ = try astrl.expr(tree.nodeData(node).node, block, ResultInfo.none); |
| 489 | return false; | 499 | return false; |
| 490 | }, | 500 | }, |
| 491 | .optional_type => { | 501 | .optional_type => { |
| 492 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | 502 | _ = try astrl.expr(tree.nodeData(node).node, block, ResultInfo.type_only); |
| 493 | return false; | 503 | return false; |
| 494 | }, | 504 | }, |
| 495 | .grouped_expression, | ||
| 496 | .@"try", | 505 | .@"try", |
| 497 | .@"await", | 506 | .@"await", |
| 498 | .@"nosuspend", | 507 | .@"nosuspend", |
| 508 | => return astrl.expr(tree.nodeData(node).node, block, ri), | ||
| 509 | .grouped_expression, | ||
| 499 | .unwrap_optional, | 510 | .unwrap_optional, |
| 500 | => return astrl.expr(node_datas[node].lhs, block, ri), | 511 | => return astrl.expr(tree.nodeData(node).node_and_token[0], block, ri), |
| 501 | 512 | ||
| 502 | .block_two, .block_two_semicolon => { | 513 | .block_two, |
| 503 | if (node_datas[node].lhs == 0) { | 514 | .block_two_semicolon, |
| 504 | return astrl.blockExpr(block, ri, node, &.{}); | 515 | .block, |
| 505 | } else if (node_datas[node].rhs == 0) { | 516 | .block_semicolon, |
| 506 | return astrl.blockExpr(block, ri, node, &.{node_datas[node].lhs}); | 517 | => { |
| 507 | } else { | 518 | var buf: [2]Ast.Node.Index = undefined; |
| 508 | return astrl.blockExpr(block, ri, node, &.{ node_datas[node].lhs, node_datas[node].rhs }); | 519 | const statements = tree.blockStatements(&buf, node).?; |
| 509 | } | ||
| 510 | }, | ||
| 511 | .block, .block_semicolon => { | ||
| 512 | const statements = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; | ||
| 513 | return astrl.blockExpr(block, ri, node, statements); | 520 | return astrl.blockExpr(block, ri, node, statements); |
| 514 | }, | 521 | }, |
| 515 | .anyframe_type => { | 522 | .anyframe_type => { |
| 516 | _ = 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); | ||
| 517 | return false; | 525 | return false; |
| 518 | }, | 526 | }, |
| 519 | .@"catch", .@"orelse" => { | 527 | .@"catch", .@"orelse" => { |
| 520 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 528 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 521 | 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); | ||
| 522 | if (rhs_consumes_rl) { | 531 | if (rhs_consumes_rl) { |
| 523 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); | 532 | try astrl.nodes_need_rl.putNoClobber(astrl.gpa, node, {}); |
| 524 | } | 533 | } |
| ... | @@ -532,19 +541,19 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -532,19 +541,19 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 532 | => { | 541 | => { |
| 533 | const full = tree.fullPtrType(node).?; | 542 | const full = tree.fullPtrType(node).?; |
| 534 | _ = try astrl.expr(full.ast.child_type, block, ResultInfo.type_only); | 543 | _ = try astrl.expr(full.ast.child_type, block, ResultInfo.type_only); |
| 535 | if (full.ast.sentinel != 0) { | 544 | if (full.ast.sentinel.unwrap()) |sentinel| { |
| 536 | _ = try astrl.expr(full.ast.sentinel, block, ResultInfo.type_only); | 545 | _ = try astrl.expr(sentinel, block, ResultInfo.type_only); |
| 537 | } | 546 | } |
| 538 | if (full.ast.addrspace_node != 0) { | 547 | if (full.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 539 | _ = try astrl.expr(full.ast.addrspace_node, block, ResultInfo.type_only); | 548 | _ = try astrl.expr(addrspace_node, block, ResultInfo.type_only); |
| 540 | } | 549 | } |
| 541 | if (full.ast.align_node != 0) { | 550 | if (full.ast.align_node.unwrap()) |align_node| { |
| 542 | _ = try astrl.expr(full.ast.align_node, block, ResultInfo.type_only); | 551 | _ = try astrl.expr(align_node, block, ResultInfo.type_only); |
| 543 | } | 552 | } |
| 544 | if (full.ast.bit_range_start != 0) { | 553 | if (full.ast.bit_range_start.unwrap()) |bit_range_start| { |
| 545 | assert(full.ast.bit_range_end != 0); | 554 | const bit_range_end = full.ast.bit_range_end.unwrap().?; |
| 546 | _ = try astrl.expr(full.ast.bit_range_start, block, ResultInfo.type_only); | 555 | _ = try astrl.expr(bit_range_start, block, ResultInfo.type_only); |
| 547 | _ = try astrl.expr(full.ast.bit_range_end, block, ResultInfo.type_only); | 556 | _ = try astrl.expr(bit_range_end, block, ResultInfo.type_only); |
| 548 | } | 557 | } |
| 549 | return false; | 558 | return false; |
| 550 | }, | 559 | }, |
| ... | @@ -568,63 +577,66 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -568,63 +577,66 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 568 | }, | 577 | }, |
| 569 | 578 | ||
| 570 | .@"break" => { | 579 | .@"break" => { |
| 571 | 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 { | ||
| 572 | // Breaks with void are not interesting | 582 | // Breaks with void are not interesting |
| 573 | return false; | 583 | return false; |
| 574 | } | 584 | }; |
| 575 | 585 | ||
| 576 | var opt_cur_block = block; | 586 | var opt_cur_block = block; |
| 577 | if (node_datas[node].lhs == 0) { | 587 | if (opt_label.unwrap()) |label_token| { |
| 578 | // No label - we're breaking from a loop. | 588 | const break_label = try astrl.identString(label_token); |
| 579 | 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) { |
| 580 | 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; | ||
| 581 | } | 592 | } |
| 582 | } else { | 593 | } else { |
| 583 | const break_label = try astrl.identString(node_datas[node].lhs); | 594 | // No label - we're breaking from a loop. |
| 584 | 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) { |
| 585 | const block_label = cur_block.label orelse continue; | 596 | if (cur_block.is_loop) break; |
| 586 | if (std.mem.eql(u8, block_label, break_label)) break; | ||
| 587 | } | 597 | } |
| 588 | } | 598 | } |
| 589 | 599 | ||
| 590 | if (opt_cur_block) |target_block| { | 600 | if (opt_cur_block) |target_block| { |
| 591 | 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); |
| 592 | if (consumes_break_rl) target_block.consumes_res_ptr = true; | 602 | if (consumes_break_rl) target_block.consumes_res_ptr = true; |
| 593 | } else { | 603 | } else { |
| 594 | // No corresponding scope to break from - AstGen will emit an error. | 604 | // No corresponding scope to break from - AstGen will emit an error. |
| 595 | _ = try astrl.expr(node_datas[node].rhs, block, ResultInfo.none); | 605 | _ = try astrl.expr(rhs, block, ResultInfo.none); |
| 596 | } | 606 | } |
| 597 | 607 | ||
| 598 | return false; | 608 | return false; |
| 599 | }, | 609 | }, |
| 600 | 610 | ||
| 601 | .array_type => { | 611 | .array_type => { |
| 602 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.type_only); | 612 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 603 | _ = 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); | ||
| 604 | return false; | 615 | return false; |
| 605 | }, | 616 | }, |
| 606 | .array_type_sentinel => { | 617 | .array_type_sentinel => { |
| 607 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.ArrayTypeSentinel); | 618 | const len_expr, const extra_index = tree.nodeData(node).node_and_extra; |
| 608 | _ = 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); | ||
| 609 | _ = try astrl.expr(extra.elem_type, block, ResultInfo.type_only); | 621 | _ = try astrl.expr(extra.elem_type, block, ResultInfo.type_only); |
| 610 | _ = try astrl.expr(extra.sentinel, block, ResultInfo.type_only); | 622 | _ = try astrl.expr(extra.sentinel, block, ResultInfo.type_only); |
| 611 | return false; | 623 | return false; |
| 612 | }, | 624 | }, |
| 613 | .array_access => { | 625 | .array_access => { |
| 614 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 626 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 615 | _ = 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); | ||
| 616 | return false; | 629 | return false; |
| 617 | }, | 630 | }, |
| 618 | .@"comptime" => { | 631 | .@"comptime" => { |
| 619 | // 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 |
| 620 | // not. This means the result location is not forwarded. | 633 | // not. This means the result location is not forwarded. |
| 621 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 634 | _ = try astrl.expr(tree.nodeData(node).node, block, ResultInfo.none); |
| 622 | return false; | 635 | return false; |
| 623 | }, | 636 | }, |
| 624 | .@"switch", .switch_comma => { | 637 | .@"switch", .switch_comma => { |
| 625 | const operand_node = node_datas[node].lhs; | 638 | const operand_node, const extra_index = tree.nodeData(node).node_and_extra; |
| 626 | 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); |
| 627 | const case_nodes = tree.extra_data[extra.start..extra.end]; | ||
| 628 | 640 | ||
| 629 | _ = try astrl.expr(operand_node, block, ResultInfo.none); | 641 | _ = try astrl.expr(operand_node, block, ResultInfo.none); |
| 630 | 642 | ||
| ... | @@ -632,9 +644,10 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -632,9 +644,10 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 632 | for (case_nodes) |case_node| { | 644 | for (case_nodes) |case_node| { |
| 633 | const case = tree.fullSwitchCase(case_node).?; | 645 | const case = tree.fullSwitchCase(case_node).?; |
| 634 | for (case.ast.values) |item_node| { | 646 | for (case.ast.values) |item_node| { |
| 635 | if (node_tags[item_node] == .switch_range) { | 647 | if (tree.nodeTag(item_node) == .switch_range) { |
| 636 | _ = try astrl.expr(node_datas[item_node].lhs, block, ResultInfo.none); | 648 | const lhs, const rhs = tree.nodeData(item_node).node_and_node; |
| 637 | _ = 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); | ||
| 638 | } else { | 651 | } else { |
| 639 | _ = try astrl.expr(item_node, block, ResultInfo.none); | 652 | _ = try astrl.expr(item_node, block, ResultInfo.none); |
| 640 | } | 653 | } |
| ... | @@ -649,11 +662,11 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -649,11 +662,11 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 649 | return any_prong_consumed_rl; | 662 | return any_prong_consumed_rl; |
| 650 | }, | 663 | }, |
| 651 | .@"suspend" => { | 664 | .@"suspend" => { |
| 652 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 665 | _ = try astrl.expr(tree.nodeData(node).node, block, ResultInfo.none); |
| 653 | return false; | 666 | return false; |
| 654 | }, | 667 | }, |
| 655 | .@"resume" => { | 668 | .@"resume" => { |
| 656 | _ = try astrl.expr(node_datas[node].lhs, block, ResultInfo.none); | 669 | _ = try astrl.expr(tree.nodeData(node).node, block, ResultInfo.none); |
| 657 | return false; | 670 | return false; |
| 658 | }, | 671 | }, |
| 659 | 672 | ||
| ... | @@ -669,9 +682,9 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -669,9 +682,9 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 669 | var buf: [2]Ast.Node.Index = undefined; | 682 | var buf: [2]Ast.Node.Index = undefined; |
| 670 | const full = tree.fullArrayInit(&buf, node).?; | 683 | const full = tree.fullArrayInit(&buf, node).?; |
| 671 | 684 | ||
| 672 | if (full.ast.type_expr != 0) { | 685 | if (full.ast.type_expr.unwrap()) |type_expr| { |
| 673 | // Explicitly typed init does not participate in RLS | 686 | // Explicitly typed init does not participate in RLS |
| 674 | _ = try astrl.expr(full.ast.type_expr, block, ResultInfo.none); | 687 | _ = try astrl.expr(type_expr, block, ResultInfo.none); |
| 675 | for (full.ast.elements) |elem_init| { | 688 | for (full.ast.elements) |elem_init| { |
| 676 | _ = try astrl.expr(elem_init, block, ResultInfo.type_only); | 689 | _ = try astrl.expr(elem_init, block, ResultInfo.type_only); |
| 677 | } | 690 | } |
| ... | @@ -706,9 +719,9 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -706,9 +719,9 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 706 | var buf: [2]Ast.Node.Index = undefined; | 719 | var buf: [2]Ast.Node.Index = undefined; |
| 707 | const full = tree.fullStructInit(&buf, node).?; | 720 | const full = tree.fullStructInit(&buf, node).?; |
| 708 | 721 | ||
| 709 | if (full.ast.type_expr != 0) { | 722 | if (full.ast.type_expr.unwrap()) |type_expr| { |
| 710 | // Explicitly typed init does not participate in RLS | 723 | // Explicitly typed init does not participate in RLS |
| 711 | _ = try astrl.expr(full.ast.type_expr, block, ResultInfo.none); | 724 | _ = try astrl.expr(type_expr, block, ResultInfo.none); |
| 712 | for (full.ast.fields) |field_init| { | 725 | for (full.ast.fields) |field_init| { |
| 713 | _ = try astrl.expr(field_init, block, ResultInfo.type_only); | 726 | _ = try astrl.expr(field_init, block, ResultInfo.type_only); |
| 714 | } | 727 | } |
| ... | @@ -736,33 +749,35 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -736,33 +749,35 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 736 | .fn_proto_one, | 749 | .fn_proto_one, |
| 737 | .fn_proto, | 750 | .fn_proto, |
| 738 | .fn_decl, | 751 | .fn_decl, |
| 739 | => { | 752 | => |tag| { |
| 740 | var buf: [1]Ast.Node.Index = undefined; | 753 | var buf: [1]Ast.Node.Index = undefined; |
| 741 | const full = tree.fullFnProto(&buf, node).?; | 754 | const full = tree.fullFnProto(&buf, node).?; |
| 742 | 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; |
| 743 | { | 756 | { |
| 744 | var it = full.iterate(tree); | 757 | var it = full.iterate(tree); |
| 745 | while (it.next()) |param| { | 758 | while (it.next()) |param| { |
| 746 | if (param.anytype_ellipsis3 == null) { | 759 | if (param.anytype_ellipsis3 == null) { |
| 747 | _ = 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); | ||
| 748 | } | 762 | } |
| 749 | } | 763 | } |
| 750 | } | 764 | } |
| 751 | if (full.ast.align_expr != 0) { | 765 | if (full.ast.align_expr.unwrap()) |align_expr| { |
| 752 | _ = try astrl.expr(full.ast.align_expr, block, ResultInfo.type_only); | 766 | _ = try astrl.expr(align_expr, block, ResultInfo.type_only); |
| 753 | } | 767 | } |
| 754 | if (full.ast.addrspace_expr != 0) { | 768 | if (full.ast.addrspace_expr.unwrap()) |addrspace_expr| { |
| 755 | _ = try astrl.expr(full.ast.addrspace_expr, block, ResultInfo.type_only); | 769 | _ = try astrl.expr(addrspace_expr, block, ResultInfo.type_only); |
| 756 | } | 770 | } |
| 757 | if (full.ast.section_expr != 0) { | 771 | if (full.ast.section_expr.unwrap()) |section_expr| { |
| 758 | _ = try astrl.expr(full.ast.section_expr, block, ResultInfo.type_only); | 772 | _ = try astrl.expr(section_expr, block, ResultInfo.type_only); |
| 759 | } | 773 | } |
| 760 | if (full.ast.callconv_expr != 0) { | 774 | if (full.ast.callconv_expr.unwrap()) |callconv_expr| { |
| 761 | _ = try astrl.expr(full.ast.callconv_expr, block, ResultInfo.type_only); | 775 | _ = try astrl.expr(callconv_expr, block, ResultInfo.type_only); |
| 762 | } | 776 | } |
| 763 | _ = try astrl.expr(full.ast.return_type, block, ResultInfo.type_only); | 777 | const return_type = full.ast.return_type.unwrap().?; |
| 764 | if (body_node != 0) { | 778 | _ = try astrl.expr(return_type, block, ResultInfo.type_only); |
| 765 | _ = try astrl.expr(body_node, block, ResultInfo.none); | 779 | if (body_node.unwrap()) |body| { |
| 780 | _ = try astrl.expr(body, block, ResultInfo.none); | ||
| 766 | } | 781 | } |
| 767 | return false; | 782 | return false; |
| 768 | }, | 783 | }, |
| ... | @@ -771,8 +786,7 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI | ... | @@ -771,8 +786,7 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI |
| 771 | 786 | ||
| 772 | fn identString(astrl: *AstRlAnnotate, token: Ast.TokenIndex) ![]const u8 { | 787 | fn identString(astrl: *AstRlAnnotate, token: Ast.TokenIndex) ![]const u8 { |
| 773 | const tree = astrl.tree; | 788 | const tree = astrl.tree; |
| 774 | const token_tags = tree.tokens.items(.tag); | 789 | assert(tree.tokenTag(token) == .identifier); |
| 775 | assert(token_tags[token] == .identifier); | ||
| 776 | const ident_name = tree.tokenSlice(token); | 790 | const ident_name = tree.tokenSlice(token); |
| 777 | if (!std.mem.startsWith(u8, ident_name, "@")) { | 791 | if (!std.mem.startsWith(u8, ident_name, "@")) { |
| 778 | return ident_name; | 792 | return ident_name; |
| ... | @@ -785,13 +799,9 @@ fn identString(astrl: *AstRlAnnotate, token: Ast.TokenIndex) ![]const u8 { | ... | @@ -785,13 +799,9 @@ fn identString(astrl: *AstRlAnnotate, token: Ast.TokenIndex) ![]const u8 { |
| 785 | 799 | ||
| 786 | 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 { |
| 787 | const tree = astrl.tree; | 801 | const tree = astrl.tree; |
| 788 | const token_tags = tree.tokens.items(.tag); | ||
| 789 | const main_tokens = tree.nodes.items(.main_token); | ||
| 790 | 802 | ||
| 791 | const lbrace = main_tokens[node]; | 803 | const lbrace = tree.nodeMainToken(node); |
| 792 | if (token_tags[lbrace - 1] == .colon and | 804 | if (tree.isTokenPrecededByTags(lbrace, &.{ .identifier, .colon })) { |
| 793 | token_tags[lbrace - 2] == .identifier) | ||
| 794 | { | ||
| 795 | // Labeled block | 805 | // Labeled block |
| 796 | var new_block: Block = .{ | 806 | var new_block: Block = .{ |
| 797 | .parent = parent_block, | 807 | .parent = parent_block, |
| ... | @@ -820,8 +830,7 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast. | ... | @@ -820,8 +830,7 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast. |
| 820 | _ = ri; // Currently, no builtin consumes its result location. | 830 | _ = ri; // Currently, no builtin consumes its result location. |
| 821 | 831 | ||
| 822 | const tree = astrl.tree; | 832 | const tree = astrl.tree; |
| 823 | const main_tokens = tree.nodes.items(.main_token); | 833 | const builtin_token = tree.nodeMainToken(node); |
| 824 | const builtin_token = main_tokens[node]; | ||
| 825 | const builtin_name = tree.tokenSlice(builtin_token); | 834 | const builtin_name = tree.tokenSlice(builtin_token); |
| 826 | const info = BuiltinFn.list.get(builtin_name) orelse return false; | 835 | const info = BuiltinFn.list.get(builtin_name) orelse return false; |
| 827 | 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+1076-1328| ... | @@ -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, |
| 453 | .trailing = trailing, | 472 | if (items.len >= 2) items[1].toOptional() else .none, |
| 454 | }, | 473 | } }, |
| 455 | 1 => return Members{ | ||
| 456 | .len = 1, | ||
| 457 | .lhs = items[0], | ||
| 458 | .rhs = 0, | ||
| 459 | .trailing = trailing, | 474 | .trailing = trailing, |
| 460 | }, | 475 | }; |
| 461 | 2 => return Members{ | 476 | } else { |
| 462 | .len = 2, | 477 | return Members{ |
| 463 | .lhs = items[0], | 478 | .len = items.len, |
| 464 | .rhs = items[1], | 479 | .data = .{ .extra_range = try p.listToSpan(items) }, |
| 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, | ||
| 2530 | .main_token = lparen, | ||
| 2531 | .data = .{ | ||
| 2532 | .lhs = res, | ||
| 2533 | .rhs = 0, | ||
| 2534 | }, | ||
| 2535 | }), | ||
| 2536 | 1 => return p.addNode(.{ | ||
| 2537 | .tag = if (comma) .async_call_one_comma else .async_call_one, | 2425 | .tag = if (comma) .async_call_one_comma else .async_call_one, |
| 2538 | .main_token = lparen, | 2426 | .main_token = lparen, |
| 2539 | .data = .{ | 2427 | .data = .{ .node_and_opt_node = .{ |
| 2540 | .lhs = res, | 2428 | res, |
| 2541 | .rhs = params[0], | 2429 | if (params.len >= 1) params[0].toOptional() else .none, |
| 2542 | }, | 2430 | } }, |
| 2543 | }), | 2431 | }); |
| 2544 | else => return p.addNode(.{ | 2432 | } else { |
| 2433 | return try 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,155 +2530,131 @@ fn parseSuffixExpr(p: *Parse) !Node.Index { | ... | @@ -2650,155 +2530,131 @@ 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 => { |
| 2795 | .tag = .enum_literal, | 2651 | p.tok_i += 1; |
| 2796 | .data = .{ | 2652 | return try p.addNode(.{ |
| 2797 | .lhs = p.nextToken(), // dot | 2653 | .tag = .enum_literal, |
| 2798 | .rhs = undefined, | 2654 | .main_token = p.nextToken(), // identifier |
| 2799 | }, | 2655 | .data = undefined, |
| 2800 | .main_token = p.nextToken(), // identifier | 2656 | }); |
| 2801 | }), | 2657 | }, |
| 2802 | .l_brace => { | 2658 | .l_brace => { |
| 2803 | const lbrace = p.tok_i + 1; | 2659 | const lbrace = p.tok_i + 1; |
| 2804 | p.tok_i = lbrace + 1; | 2660 | p.tok_i = lbrace + 1; |
| ... | @@ -2808,11 +2664,11 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2808,11 +2664,11 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2808 | 2664 | ||
| 2809 | const scratch_top = p.scratch.items.len; | 2665 | const scratch_top = p.scratch.items.len; |
| 2810 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 2666 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2811 | const field_init = try p.parseFieldInit(); | 2667 | const opt_field_init = try p.parseFieldInit(); |
| 2812 | if (field_init != 0) { | 2668 | if (opt_field_init) |field_init| { |
| 2813 | try p.scratch.append(p.gpa, field_init); | 2669 | try p.scratch.append(p.gpa, field_init); |
| 2814 | while (true) { | 2670 | while (true) { |
| 2815 | switch (p.token_tags[p.tok_i]) { | 2671 | switch (p.tokenTag(p.tok_i)) { |
| 2816 | .comma => p.tok_i += 1, | 2672 | .comma => p.tok_i += 1, |
| 2817 | .r_brace => { | 2673 | .r_brace => { |
| 2818 | p.tok_i += 1; | 2674 | p.tok_i += 1; |
| ... | @@ -2826,37 +2682,24 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2826,37 +2682,24 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2826 | const next = try p.expectFieldInit(); | 2682 | const next = try p.expectFieldInit(); |
| 2827 | try p.scratch.append(p.gpa, next); | 2683 | try p.scratch.append(p.gpa, next); |
| 2828 | } | 2684 | } |
| 2829 | const comma = (p.token_tags[p.tok_i - 2] == .comma); | 2685 | const comma = (p.tokenTag(p.tok_i - 2)) == .comma; |
| 2830 | const inits = p.scratch.items[scratch_top..]; | 2686 | const inits = p.scratch.items[scratch_top..]; |
| 2831 | switch (inits.len) { | 2687 | std.debug.assert(inits.len != 0); |
| 2832 | 0 => unreachable, | 2688 | if (inits.len <= 2) { |
| 2833 | 1 => return p.addNode(.{ | 2689 | return try p.addNode(.{ |
| 2834 | .tag = if (comma) .struct_init_dot_two_comma else .struct_init_dot_two, | 2690 | .tag = if (comma) .struct_init_dot_two_comma else .struct_init_dot_two, |
| 2835 | .main_token = lbrace, | 2691 | .main_token = lbrace, |
| 2836 | .data = .{ | 2692 | .data = .{ .opt_node_and_opt_node = .{ |
| 2837 | .lhs = inits[0], | 2693 | if (inits.len >= 1) .fromOptional(inits[0]) else .none, |
| 2838 | .rhs = 0, | 2694 | if (inits.len >= 2) .fromOptional(inits[1]) else .none, |
| 2839 | }, | 2695 | } }, |
| 2840 | }), | 2696 | }); |
| 2841 | 2 => return p.addNode(.{ | 2697 | } else { |
| 2842 | .tag = if (comma) .struct_init_dot_two_comma else .struct_init_dot_two, | 2698 | return try p.addNode(.{ |
| 2699 | .tag = if (comma) .struct_init_dot_comma else .struct_init_dot, | ||
| 2843 | .main_token = lbrace, | 2700 | .main_token = lbrace, |
| 2844 | .data = .{ | 2701 | .data = .{ .extra_range = try p.listToSpan(inits) }, |
| 2845 | .lhs = inits[0], | 2702 | }); |
| 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 | } | 2703 | } |
| 2861 | } | 2704 | } |
| 2862 | 2705 | ||
| ... | @@ -2864,7 +2707,7 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2864,7 +2707,7 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2864 | if (p.eatToken(.r_brace)) |_| break; | 2707 | if (p.eatToken(.r_brace)) |_| break; |
| 2865 | const elem_init = try p.expectExpr(); | 2708 | const elem_init = try p.expectExpr(); |
| 2866 | try p.scratch.append(p.gpa, elem_init); | 2709 | try p.scratch.append(p.gpa, elem_init); |
| 2867 | switch (p.token_tags[p.tok_i]) { | 2710 | switch (p.tokenTag(p.tok_i)) { |
| 2868 | .comma => p.tok_i += 1, | 2711 | .comma => p.tok_i += 1, |
| 2869 | .r_brace => { | 2712 | .r_brace => { |
| 2870 | p.tok_i += 1; | 2713 | p.tok_i += 1; |
| ... | @@ -2875,49 +2718,30 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2875,49 +2718,30 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2875 | else => try p.warn(.expected_comma_after_initializer), | 2718 | else => try p.warn(.expected_comma_after_initializer), |
| 2876 | } | 2719 | } |
| 2877 | } | 2720 | } |
| 2878 | const comma = (p.token_tags[p.tok_i - 2] == .comma); | 2721 | const comma = (p.tokenTag(p.tok_i - 2)) == .comma; |
| 2879 | const inits = p.scratch.items[scratch_top..]; | 2722 | const inits = p.scratch.items[scratch_top..]; |
| 2880 | switch (inits.len) { | 2723 | if (inits.len <= 2) { |
| 2881 | 0 => return p.addNode(.{ | 2724 | return try p.addNode(.{ |
| 2882 | .tag = .struct_init_dot_two, | 2725 | .tag = if (inits.len == 0) |
| 2726 | .struct_init_dot_two | ||
| 2727 | else if (comma) .array_init_dot_two_comma else .array_init_dot_two, | ||
| 2883 | .main_token = lbrace, | 2728 | .main_token = lbrace, |
| 2884 | .data = .{ | 2729 | .data = .{ .opt_node_and_opt_node = .{ |
| 2885 | .lhs = 0, | 2730 | if (inits.len >= 1) inits[0].toOptional() else .none, |
| 2886 | .rhs = 0, | 2731 | if (inits.len >= 2) inits[1].toOptional() else .none, |
| 2887 | }, | 2732 | } }, |
| 2888 | }), | 2733 | }); |
| 2889 | 1 => return p.addNode(.{ | 2734 | } else { |
| 2890 | .tag = if (comma) .array_init_dot_two_comma else .array_init_dot_two, | 2735 | return try p.addNode(.{ |
| 2891 | .main_token = lbrace, | 2736 | .tag = if (comma) .array_init_dot_comma else .array_init_dot, |
| 2892 | .data = .{ | ||
| 2893 | .lhs = inits[0], | ||
| 2894 | .rhs = 0, | ||
| 2895 | }, | ||
| 2896 | }), | ||
| 2897 | 2 => return p.addNode(.{ | ||
| 2898 | .tag = if (comma) .array_init_dot_two_comma else .array_init_dot_two, | ||
| 2899 | .main_token = lbrace, | 2737 | .main_token = lbrace, |
| 2900 | .data = .{ | 2738 | .data = .{ .extra_range = try p.listToSpan(inits) }, |
| 2901 | .lhs = inits[0], | 2739 | }); |
| 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 | } | 2740 | } |
| 2917 | }, | 2741 | }, |
| 2918 | else => return null_node, | 2742 | else => return null, |
| 2919 | }, | 2743 | }, |
| 2920 | .keyword_error => switch (p.token_tags[p.tok_i + 1]) { | 2744 | .keyword_error => switch (p.tokenTag(p.tok_i + 1)) { |
| 2921 | .l_brace => { | 2745 | .l_brace => { |
| 2922 | const error_token = p.tok_i; | 2746 | const error_token = p.tok_i; |
| 2923 | p.tok_i += 2; | 2747 | p.tok_i += 2; |
| ... | @@ -2925,7 +2749,7 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2925,7 +2749,7 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2925 | if (p.eatToken(.r_brace)) |_| break; | 2749 | if (p.eatToken(.r_brace)) |_| break; |
| 2926 | _ = try p.eatDocComments(); | 2750 | _ = try p.eatDocComments(); |
| 2927 | _ = try p.expectToken(.identifier); | 2751 | _ = try p.expectToken(.identifier); |
| 2928 | switch (p.token_tags[p.tok_i]) { | 2752 | switch (p.tokenTag(p.tok_i)) { |
| 2929 | .comma => p.tok_i += 1, | 2753 | .comma => p.tok_i += 1, |
| 2930 | .r_brace => { | 2754 | .r_brace => { |
| 2931 | p.tok_i += 1; | 2755 | p.tok_i += 1; |
| ... | @@ -2936,12 +2760,14 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2936,12 +2760,14 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2936 | else => try p.warn(.expected_comma_after_field), | 2760 | else => try p.warn(.expected_comma_after_field), |
| 2937 | } | 2761 | } |
| 2938 | } | 2762 | } |
| 2939 | return p.addNode(.{ | 2763 | return try p.addNode(.{ |
| 2940 | .tag = .error_set_decl, | 2764 | .tag = .error_set_decl, |
| 2941 | .main_token = error_token, | 2765 | .main_token = error_token, |
| 2942 | .data = .{ | 2766 | .data = .{ |
| 2943 | .lhs = undefined, | 2767 | .token_and_token = .{ |
| 2944 | .rhs = p.tok_i - 1, // rbrace | 2768 | error_token + 1, // lbrace |
| 2769 | p.tok_i - 1, // rbrace | ||
| 2770 | }, | ||
| 2945 | }, | 2771 | }, |
| 2946 | }); | 2772 | }); |
| 2947 | }, | 2773 | }, |
| ... | @@ -2951,41 +2777,34 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2951,41 +2777,34 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2951 | if (period == null) try p.warnExpected(.period); | 2777 | if (period == null) try p.warnExpected(.period); |
| 2952 | const identifier = p.eatToken(.identifier); | 2778 | const identifier = p.eatToken(.identifier); |
| 2953 | if (identifier == null) try p.warnExpected(.identifier); | 2779 | if (identifier == null) try p.warnExpected(.identifier); |
| 2954 | return p.addNode(.{ | 2780 | return try p.addNode(.{ |
| 2955 | .tag = .error_value, | 2781 | .tag = .error_value, |
| 2956 | .main_token = main_token, | 2782 | .main_token = main_token, |
| 2957 | .data = .{ | 2783 | .data = undefined, |
| 2958 | .lhs = period orelse 0, | ||
| 2959 | .rhs = identifier orelse 0, | ||
| 2960 | }, | ||
| 2961 | }); | 2784 | }); |
| 2962 | }, | 2785 | }, |
| 2963 | }, | 2786 | }, |
| 2964 | .l_paren => return p.addNode(.{ | 2787 | .l_paren => return try p.addNode(.{ |
| 2965 | .tag = .grouped_expression, | 2788 | .tag = .grouped_expression, |
| 2966 | .main_token = p.nextToken(), | 2789 | .main_token = p.nextToken(), |
| 2967 | .data = .{ | 2790 | .data = .{ .node_and_token = .{ |
| 2968 | .lhs = try p.expectExpr(), | 2791 | try p.expectExpr(), |
| 2969 | .rhs = try p.expectToken(.r_paren), | 2792 | try p.expectToken(.r_paren), |
| 2970 | }, | 2793 | } }, |
| 2971 | }), | 2794 | }), |
| 2972 | else => return null_node, | 2795 | else => return null, |
| 2973 | } | 2796 | } |
| 2974 | } | 2797 | } |
| 2975 | 2798 | ||
| 2976 | fn expectPrimaryTypeExpr(p: *Parse) !Node.Index { | 2799 | fn expectPrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2977 | const node = try p.parsePrimaryTypeExpr(); | 2800 | 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 | } | 2801 | } |
| 2983 | 2802 | ||
| 2984 | /// WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr? | 2803 | /// WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr? |
| 2985 | /// | 2804 | /// |
| 2986 | /// WhileTypeExpr <- WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)? | 2805 | /// WhileTypeExpr <- WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)? |
| 2987 | fn parseWhileTypeExpr(p: *Parse) !Node.Index { | 2806 | fn parseWhileTypeExpr(p: *Parse) !?Node.Index { |
| 2988 | const while_token = p.eatToken(.keyword_while) orelse return null_node; | 2807 | const while_token = p.eatToken(.keyword_while) orelse return null; |
| 2989 | _ = try p.expectToken(.l_paren); | 2808 | _ = try p.expectToken(.l_paren); |
| 2990 | const condition = try p.expectExpr(); | 2809 | const condition = try p.expectExpr(); |
| 2991 | _ = try p.expectToken(.r_paren); | 2810 | _ = try p.expectToken(.r_paren); |
| ... | @@ -2994,54 +2813,52 @@ fn parseWhileTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2994,54 +2813,52 @@ fn parseWhileTypeExpr(p: *Parse) !Node.Index { |
| 2994 | 2813 | ||
| 2995 | const then_expr = try p.expectTypeExpr(); | 2814 | const then_expr = try p.expectTypeExpr(); |
| 2996 | _ = p.eatToken(.keyword_else) orelse { | 2815 | _ = p.eatToken(.keyword_else) orelse { |
| 2997 | if (cont_expr == 0) { | 2816 | if (cont_expr == null) { |
| 2998 | return p.addNode(.{ | 2817 | return try p.addNode(.{ |
| 2999 | .tag = .while_simple, | 2818 | .tag = .while_simple, |
| 3000 | .main_token = while_token, | 2819 | .main_token = while_token, |
| 3001 | .data = .{ | 2820 | .data = .{ .node_and_node = .{ |
| 3002 | .lhs = condition, | 2821 | condition, |
| 3003 | .rhs = then_expr, | 2822 | then_expr, |
| 3004 | }, | 2823 | } }, |
| 3005 | }); | 2824 | }); |
| 3006 | } else { | 2825 | } else { |
| 3007 | return p.addNode(.{ | 2826 | return try p.addNode(.{ |
| 3008 | .tag = .while_cont, | 2827 | .tag = .while_cont, |
| 3009 | .main_token = while_token, | 2828 | .main_token = while_token, |
| 3010 | .data = .{ | 2829 | .data = .{ .node_and_extra = .{ |
| 3011 | .lhs = condition, | 2830 | condition, try p.addExtra(Node.WhileCont{ |
| 3012 | .rhs = try p.addExtra(Node.WhileCont{ | 2831 | .cont_expr = cont_expr.?, |
| 3013 | .cont_expr = cont_expr, | ||
| 3014 | .then_expr = then_expr, | 2832 | .then_expr = then_expr, |
| 3015 | }), | 2833 | }), |
| 3016 | }, | 2834 | } }, |
| 3017 | }); | 2835 | }); |
| 3018 | } | 2836 | } |
| 3019 | }; | 2837 | }; |
| 3020 | _ = try p.parsePayload(); | 2838 | _ = try p.parsePayload(); |
| 3021 | const else_expr = try p.expectTypeExpr(); | 2839 | const else_expr = try p.expectTypeExpr(); |
| 3022 | return p.addNode(.{ | 2840 | return try p.addNode(.{ |
| 3023 | .tag = .@"while", | 2841 | .tag = .@"while", |
| 3024 | .main_token = while_token, | 2842 | .main_token = while_token, |
| 3025 | .data = .{ | 2843 | .data = .{ .node_and_extra = .{ |
| 3026 | .lhs = condition, | 2844 | condition, try p.addExtra(Node.While{ |
| 3027 | .rhs = try p.addExtra(Node.While{ | 2845 | .cont_expr = .fromOptional(cont_expr), |
| 3028 | .cont_expr = cont_expr, | ||
| 3029 | .then_expr = then_expr, | 2846 | .then_expr = then_expr, |
| 3030 | .else_expr = else_expr, | 2847 | .else_expr = else_expr, |
| 3031 | }), | 2848 | }), |
| 3032 | }, | 2849 | } }, |
| 3033 | }); | 2850 | }); |
| 3034 | } | 2851 | } |
| 3035 | 2852 | ||
| 3036 | /// SwitchExpr <- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE | 2853 | /// SwitchExpr <- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE |
| 3037 | fn parseSwitchExpr(p: *Parse, is_labeled: bool) !Node.Index { | 2854 | fn parseSwitchExpr(p: *Parse, is_labeled: bool) !?Node.Index { |
| 3038 | const switch_token = p.eatToken(.keyword_switch) orelse return null_node; | 2855 | const switch_token = p.eatToken(.keyword_switch) orelse return null; |
| 3039 | 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); |
| 3040 | } | 2857 | } |
| 3041 | 2858 | ||
| 3042 | fn expectSwitchExpr(p: *Parse, is_labeled: bool) !Node.Index { | 2859 | fn expectSwitchExpr(p: *Parse, is_labeled: bool) !Node.Index { |
| 3043 | const switch_token = p.assertToken(.keyword_switch); | 2860 | const switch_token = p.assertToken(.keyword_switch); |
| 3044 | return p.expectSwitchSuffix(if (is_labeled) switch_token - 2 else switch_token); | 2861 | return try p.expectSwitchSuffix(if (is_labeled) switch_token - 2 else switch_token); |
| 3045 | } | 2862 | } |
| 3046 | 2863 | ||
| 3047 | fn expectSwitchSuffix(p: *Parse, main_token: TokenIndex) !Node.Index { | 2864 | fn expectSwitchSuffix(p: *Parse, main_token: TokenIndex) !Node.Index { |
| ... | @@ -3050,19 +2867,19 @@ fn expectSwitchSuffix(p: *Parse, main_token: TokenIndex) !Node.Index { | ... | @@ -3050,19 +2867,19 @@ fn expectSwitchSuffix(p: *Parse, main_token: TokenIndex) !Node.Index { |
| 3050 | _ = try p.expectToken(.r_paren); | 2867 | _ = try p.expectToken(.r_paren); |
| 3051 | _ = try p.expectToken(.l_brace); | 2868 | _ = try p.expectToken(.l_brace); |
| 3052 | const cases = try p.parseSwitchProngList(); | 2869 | const cases = try p.parseSwitchProngList(); |
| 3053 | const trailing_comma = p.token_tags[p.tok_i - 1] == .comma; | 2870 | const trailing_comma = p.tokenTag(p.tok_i - 1) == .comma; |
| 3054 | _ = try p.expectToken(.r_brace); | 2871 | _ = try p.expectToken(.r_brace); |
| 3055 | 2872 | ||
| 3056 | return p.addNode(.{ | 2873 | return p.addNode(.{ |
| 3057 | .tag = if (trailing_comma) .switch_comma else .@"switch", | 2874 | .tag = if (trailing_comma) .switch_comma else .@"switch", |
| 3058 | .main_token = main_token, | 2875 | .main_token = main_token, |
| 3059 | .data = .{ | 2876 | .data = .{ .node_and_extra = .{ |
| 3060 | .lhs = expr_node, | 2877 | expr_node, |
| 3061 | .rhs = try p.addExtra(Node.SubRange{ | 2878 | try p.addExtra(Node.SubRange{ |
| 3062 | .start = cases.start, | 2879 | .start = cases.start, |
| 3063 | .end = cases.end, | 2880 | .end = cases.end, |
| 3064 | }), | 2881 | }), |
| 3065 | }, | 2882 | } }, |
| 3066 | }); | 2883 | }); |
| 3067 | } | 2884 | } |
| 3068 | 2885 | ||
| ... | @@ -3089,10 +2906,10 @@ fn expectAsmExpr(p: *Parse) !Node.Index { | ... | @@ -3089,10 +2906,10 @@ fn expectAsmExpr(p: *Parse) !Node.Index { |
| 3089 | return p.addNode(.{ | 2906 | return p.addNode(.{ |
| 3090 | .tag = .asm_simple, | 2907 | .tag = .asm_simple, |
| 3091 | .main_token = asm_token, | 2908 | .main_token = asm_token, |
| 3092 | .data = .{ | 2909 | .data = .{ .node_and_token = .{ |
| 3093 | .lhs = template, | 2910 | template, |
| 3094 | .rhs = rparen, | 2911 | rparen, |
| 3095 | }, | 2912 | } }, |
| 3096 | }); | 2913 | }); |
| 3097 | } | 2914 | } |
| 3098 | 2915 | ||
| ... | @@ -3102,10 +2919,9 @@ fn expectAsmExpr(p: *Parse) !Node.Index { | ... | @@ -3102,10 +2919,9 @@ fn expectAsmExpr(p: *Parse) !Node.Index { |
| 3102 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 2919 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 3103 | 2920 | ||
| 3104 | while (true) { | 2921 | while (true) { |
| 3105 | const output_item = try p.parseAsmOutputItem(); | 2922 | const output_item = try p.parseAsmOutputItem() orelse break; |
| 3106 | if (output_item == 0) break; | ||
| 3107 | try p.scratch.append(p.gpa, output_item); | 2923 | try p.scratch.append(p.gpa, output_item); |
| 3108 | switch (p.token_tags[p.tok_i]) { | 2924 | switch (p.tokenTag(p.tok_i)) { |
| 3109 | .comma => p.tok_i += 1, | 2925 | .comma => p.tok_i += 1, |
| 3110 | // All possible delimiters. | 2926 | // All possible delimiters. |
| 3111 | .colon, .r_paren, .r_brace, .r_bracket => break, | 2927 | .colon, .r_paren, .r_brace, .r_bracket => break, |
| ... | @@ -3115,10 +2931,9 @@ fn expectAsmExpr(p: *Parse) !Node.Index { | ... | @@ -3115,10 +2931,9 @@ fn expectAsmExpr(p: *Parse) !Node.Index { |
| 3115 | } | 2931 | } |
| 3116 | if (p.eatToken(.colon)) |_| { | 2932 | if (p.eatToken(.colon)) |_| { |
| 3117 | while (true) { | 2933 | while (true) { |
| 3118 | const input_item = try p.parseAsmInputItem(); | 2934 | const input_item = try p.parseAsmInputItem() orelse break; |
| 3119 | if (input_item == 0) break; | ||
| 3120 | try p.scratch.append(p.gpa, input_item); | 2935 | try p.scratch.append(p.gpa, input_item); |
| 3121 | switch (p.token_tags[p.tok_i]) { | 2936 | switch (p.tokenTag(p.tok_i)) { |
| 3122 | .comma => p.tok_i += 1, | 2937 | .comma => p.tok_i += 1, |
| 3123 | // All possible delimiters. | 2938 | // All possible delimiters. |
| 3124 | .colon, .r_paren, .r_brace, .r_bracket => break, | 2939 | .colon, .r_paren, .r_brace, .r_bracket => break, |
| ... | @@ -3128,7 +2943,7 @@ fn expectAsmExpr(p: *Parse) !Node.Index { | ... | @@ -3128,7 +2943,7 @@ fn expectAsmExpr(p: *Parse) !Node.Index { |
| 3128 | } | 2943 | } |
| 3129 | if (p.eatToken(.colon)) |_| { | 2944 | if (p.eatToken(.colon)) |_| { |
| 3130 | while (p.eatToken(.string_literal)) |_| { | 2945 | while (p.eatToken(.string_literal)) |_| { |
| 3131 | switch (p.token_tags[p.tok_i]) { | 2946 | switch (p.tokenTag(p.tok_i)) { |
| 3132 | .comma => p.tok_i += 1, | 2947 | .comma => p.tok_i += 1, |
| 3133 | .colon, .r_paren, .r_brace, .r_bracket => break, | 2948 | .colon, .r_paren, .r_brace, .r_bracket => break, |
| 3134 | // Likely just a missing comma; give error but continue parsing. | 2949 | // Likely just a missing comma; give error but continue parsing. |
| ... | @@ -3142,121 +2957,106 @@ fn expectAsmExpr(p: *Parse) !Node.Index { | ... | @@ -3142,121 +2957,106 @@ fn expectAsmExpr(p: *Parse) !Node.Index { |
| 3142 | return p.addNode(.{ | 2957 | return p.addNode(.{ |
| 3143 | .tag = .@"asm", | 2958 | .tag = .@"asm", |
| 3144 | .main_token = asm_token, | 2959 | .main_token = asm_token, |
| 3145 | .data = .{ | 2960 | .data = .{ .node_and_extra = .{ |
| 3146 | .lhs = template, | 2961 | template, |
| 3147 | .rhs = try p.addExtra(Node.Asm{ | 2962 | try p.addExtra(Node.Asm{ |
| 3148 | .items_start = span.start, | 2963 | .items_start = span.start, |
| 3149 | .items_end = span.end, | 2964 | .items_end = span.end, |
| 3150 | .rparen = rparen, | 2965 | .rparen = rparen, |
| 3151 | }), | 2966 | }), |
| 3152 | }, | 2967 | } }, |
| 3153 | }); | 2968 | }); |
| 3154 | } | 2969 | } |
| 3155 | 2970 | ||
| 3156 | /// AsmOutputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN | 2971 | /// AsmOutputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN |
| 3157 | fn parseAsmOutputItem(p: *Parse) !Node.Index { | 2972 | fn parseAsmOutputItem(p: *Parse) !?Node.Index { |
| 3158 | _ = p.eatToken(.l_bracket) orelse return null_node; | 2973 | _ = p.eatToken(.l_bracket) orelse return null; |
| 3159 | const identifier = try p.expectToken(.identifier); | 2974 | const identifier = try p.expectToken(.identifier); |
| 3160 | _ = try p.expectToken(.r_bracket); | 2975 | _ = try p.expectToken(.r_bracket); |
| 3161 | _ = try p.expectToken(.string_literal); | 2976 | _ = try p.expectToken(.string_literal); |
| 3162 | _ = try p.expectToken(.l_paren); | 2977 | _ = try p.expectToken(.l_paren); |
| 3163 | const type_expr: Node.Index = blk: { | 2978 | const type_expr: Node.OptionalIndex = blk: { |
| 3164 | if (p.eatToken(.arrow)) |_| { | 2979 | if (p.eatToken(.arrow)) |_| { |
| 3165 | break :blk try p.expectTypeExpr(); | 2980 | break :blk .fromOptional(try p.expectTypeExpr()); |
| 3166 | } else { | 2981 | } else { |
| 3167 | _ = try p.expectToken(.identifier); | 2982 | _ = try p.expectToken(.identifier); |
| 3168 | break :blk null_node; | 2983 | break :blk .none; |
| 3169 | } | 2984 | } |
| 3170 | }; | 2985 | }; |
| 3171 | const rparen = try p.expectToken(.r_paren); | 2986 | const rparen = try p.expectToken(.r_paren); |
| 3172 | return p.addNode(.{ | 2987 | return try p.addNode(.{ |
| 3173 | .tag = .asm_output, | 2988 | .tag = .asm_output, |
| 3174 | .main_token = identifier, | 2989 | .main_token = identifier, |
| 3175 | .data = .{ | 2990 | .data = .{ .opt_node_and_token = .{ |
| 3176 | .lhs = type_expr, | 2991 | type_expr, |
| 3177 | .rhs = rparen, | 2992 | rparen, |
| 3178 | }, | 2993 | } }, |
| 3179 | }); | 2994 | }); |
| 3180 | } | 2995 | } |
| 3181 | 2996 | ||
| 3182 | /// AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN | 2997 | /// AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN |
| 3183 | fn parseAsmInputItem(p: *Parse) !Node.Index { | 2998 | fn parseAsmInputItem(p: *Parse) !?Node.Index { |
| 3184 | _ = p.eatToken(.l_bracket) orelse return null_node; | 2999 | _ = p.eatToken(.l_bracket) orelse return null; |
| 3185 | const identifier = try p.expectToken(.identifier); | 3000 | const identifier = try p.expectToken(.identifier); |
| 3186 | _ = try p.expectToken(.r_bracket); | 3001 | _ = try p.expectToken(.r_bracket); |
| 3187 | _ = try p.expectToken(.string_literal); | 3002 | _ = try p.expectToken(.string_literal); |
| 3188 | _ = try p.expectToken(.l_paren); | 3003 | _ = try p.expectToken(.l_paren); |
| 3189 | const expr = try p.expectExpr(); | 3004 | const expr = try p.expectExpr(); |
| 3190 | const rparen = try p.expectToken(.r_paren); | 3005 | const rparen = try p.expectToken(.r_paren); |
| 3191 | return p.addNode(.{ | 3006 | return try p.addNode(.{ |
| 3192 | .tag = .asm_input, | 3007 | .tag = .asm_input, |
| 3193 | .main_token = identifier, | 3008 | .main_token = identifier, |
| 3194 | .data = .{ | 3009 | .data = .{ .node_and_token = .{ |
| 3195 | .lhs = expr, | 3010 | expr, |
| 3196 | .rhs = rparen, | 3011 | rparen, |
| 3197 | }, | 3012 | } }, |
| 3198 | }); | 3013 | }); |
| 3199 | } | 3014 | } |
| 3200 | 3015 | ||
| 3201 | /// BreakLabel <- COLON IDENTIFIER | 3016 | /// BreakLabel <- COLON IDENTIFIER |
| 3202 | fn parseBreakLabel(p: *Parse) !TokenIndex { | 3017 | fn parseBreakLabel(p: *Parse) Error!OptionalTokenIndex { |
| 3203 | _ = p.eatToken(.colon) orelse return null_node; | 3018 | _ = p.eatToken(.colon) orelse return .none; |
| 3204 | return p.expectToken(.identifier); | 3019 | const next_token = try p.expectToken(.identifier); |
| 3020 | return .fromToken(next_token); | ||
| 3205 | } | 3021 | } |
| 3206 | 3022 | ||
| 3207 | /// BlockLabel <- IDENTIFIER COLON | 3023 | /// BlockLabel <- IDENTIFIER COLON |
| 3208 | fn parseBlockLabel(p: *Parse) TokenIndex { | 3024 | fn parseBlockLabel(p: *Parse) ?TokenIndex { |
| 3209 | if (p.token_tags[p.tok_i] == .identifier and | 3025 | 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 | } | 3026 | } |
| 3218 | 3027 | ||
| 3219 | /// FieldInit <- DOT IDENTIFIER EQUAL Expr | 3028 | /// FieldInit <- DOT IDENTIFIER EQUAL Expr |
| 3220 | fn parseFieldInit(p: *Parse) !Node.Index { | 3029 | fn parseFieldInit(p: *Parse) !?Node.Index { |
| 3221 | if (p.token_tags[p.tok_i + 0] == .period and | 3030 | if (p.eatTokens(&.{ .period, .identifier, .equal })) |_| { |
| 3222 | p.token_tags[p.tok_i + 1] == .identifier and | 3031 | 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 | } | 3032 | } |
| 3033 | return null; | ||
| 3230 | } | 3034 | } |
| 3231 | 3035 | ||
| 3232 | fn expectFieldInit(p: *Parse) !Node.Index { | 3036 | fn expectFieldInit(p: *Parse) !Node.Index { |
| 3233 | if (p.token_tags[p.tok_i] != .period or | 3037 | if (p.eatTokens(&.{ .period, .identifier, .equal })) |_| { |
| 3234 | p.token_tags[p.tok_i + 1] != .identifier or | 3038 | return try p.expectExpr(); |
| 3235 | p.token_tags[p.tok_i + 2] != .equal) | 3039 | } |
| 3236 | return p.fail(.expected_initializer); | 3040 | return p.fail(.expected_initializer); |
| 3237 | |||
| 3238 | p.tok_i += 3; | ||
| 3239 | return p.expectExpr(); | ||
| 3240 | } | 3041 | } |
| 3241 | 3042 | ||
| 3242 | /// WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN | 3043 | /// WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN |
| 3243 | fn parseWhileContinueExpr(p: *Parse) !Node.Index { | 3044 | fn parseWhileContinueExpr(p: *Parse) !?Node.Index { |
| 3244 | _ = p.eatToken(.colon) orelse { | 3045 | _ = p.eatToken(.colon) orelse { |
| 3245 | if (p.token_tags[p.tok_i] == .l_paren and | 3046 | if (p.tokenTag(p.tok_i) == .l_paren and |
| 3246 | p.tokensOnSameLine(p.tok_i - 1, p.tok_i)) | 3047 | p.tokensOnSameLine(p.tok_i - 1, p.tok_i)) |
| 3247 | return p.fail(.expected_continue_expr); | 3048 | return p.fail(.expected_continue_expr); |
| 3248 | return null_node; | 3049 | return null; |
| 3249 | }; | 3050 | }; |
| 3250 | _ = try p.expectToken(.l_paren); | 3051 | _ = try p.expectToken(.l_paren); |
| 3251 | const node = try p.parseAssignExpr(); | 3052 | 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); | 3053 | _ = try p.expectToken(.r_paren); |
| 3254 | return node; | 3054 | return node; |
| 3255 | } | 3055 | } |
| 3256 | 3056 | ||
| 3257 | /// LinkSection <- KEYWORD_linksection LPAREN Expr RPAREN | 3057 | /// LinkSection <- KEYWORD_linksection LPAREN Expr RPAREN |
| 3258 | fn parseLinkSection(p: *Parse) !Node.Index { | 3058 | fn parseLinkSection(p: *Parse) !?Node.Index { |
| 3259 | _ = p.eatToken(.keyword_linksection) orelse return null_node; | 3059 | _ = p.eatToken(.keyword_linksection) orelse return null; |
| 3260 | _ = try p.expectToken(.l_paren); | 3060 | _ = try p.expectToken(.l_paren); |
| 3261 | const expr_node = try p.expectExpr(); | 3061 | const expr_node = try p.expectExpr(); |
| 3262 | _ = try p.expectToken(.r_paren); | 3062 | _ = try p.expectToken(.r_paren); |
| ... | @@ -3264,8 +3064,8 @@ fn parseLinkSection(p: *Parse) !Node.Index { | ... | @@ -3264,8 +3064,8 @@ fn parseLinkSection(p: *Parse) !Node.Index { |
| 3264 | } | 3064 | } |
| 3265 | 3065 | ||
| 3266 | /// CallConv <- KEYWORD_callconv LPAREN Expr RPAREN | 3066 | /// CallConv <- KEYWORD_callconv LPAREN Expr RPAREN |
| 3267 | fn parseCallconv(p: *Parse) !Node.Index { | 3067 | fn parseCallconv(p: *Parse) !?Node.Index { |
| 3268 | _ = p.eatToken(.keyword_callconv) orelse return null_node; | 3068 | _ = p.eatToken(.keyword_callconv) orelse return null; |
| 3269 | _ = try p.expectToken(.l_paren); | 3069 | _ = try p.expectToken(.l_paren); |
| 3270 | const expr_node = try p.expectExpr(); | 3070 | const expr_node = try p.expectExpr(); |
| 3271 | _ = try p.expectToken(.r_paren); | 3071 | _ = try p.expectToken(.r_paren); |
| ... | @@ -3273,8 +3073,8 @@ fn parseCallconv(p: *Parse) !Node.Index { | ... | @@ -3273,8 +3073,8 @@ fn parseCallconv(p: *Parse) !Node.Index { |
| 3273 | } | 3073 | } |
| 3274 | 3074 | ||
| 3275 | /// AddrSpace <- KEYWORD_addrspace LPAREN Expr RPAREN | 3075 | /// AddrSpace <- KEYWORD_addrspace LPAREN Expr RPAREN |
| 3276 | fn parseAddrSpace(p: *Parse) !Node.Index { | 3076 | fn parseAddrSpace(p: *Parse) !?Node.Index { |
| 3277 | _ = p.eatToken(.keyword_addrspace) orelse return null_node; | 3077 | _ = p.eatToken(.keyword_addrspace) orelse return null; |
| 3278 | _ = try p.expectToken(.l_paren); | 3078 | _ = try p.expectToken(.l_paren); |
| 3279 | const expr_node = try p.expectExpr(); | 3079 | const expr_node = try p.expectExpr(); |
| 3280 | _ = try p.expectToken(.r_paren); | 3080 | _ = try p.expectToken(.r_paren); |
| ... | @@ -3292,59 +3092,53 @@ fn parseAddrSpace(p: *Parse) !Node.Index { | ... | @@ -3292,59 +3092,53 @@ fn parseAddrSpace(p: *Parse) !Node.Index { |
| 3292 | /// ParamType | 3092 | /// ParamType |
| 3293 | /// <- KEYWORD_anytype | 3093 | /// <- KEYWORD_anytype |
| 3294 | /// / TypeExpr | 3094 | /// / TypeExpr |
| 3295 | fn expectParamDecl(p: *Parse) !Node.Index { | 3095 | fn expectParamDecl(p: *Parse) !?Node.Index { |
| 3296 | _ = try p.eatDocComments(); | 3096 | _ = try p.eatDocComments(); |
| 3297 | switch (p.token_tags[p.tok_i]) { | 3097 | switch (p.tokenTag(p.tok_i)) { |
| 3298 | .keyword_noalias, .keyword_comptime => p.tok_i += 1, | 3098 | .keyword_noalias, .keyword_comptime => p.tok_i += 1, |
| 3299 | .ellipsis3 => { | 3099 | .ellipsis3 => { |
| 3300 | p.tok_i += 1; | 3100 | p.tok_i += 1; |
| 3301 | return null_node; | 3101 | return null; |
| 3302 | }, | 3102 | }, |
| 3303 | else => {}, | 3103 | else => {}, |
| 3304 | } | 3104 | } |
| 3305 | if (p.token_tags[p.tok_i] == .identifier and | 3105 | _ = p.eatTokens(&.{ .identifier, .colon }); |
| 3306 | p.token_tags[p.tok_i + 1] == .colon) | 3106 | if (p.eatToken(.keyword_anytype)) |_| { |
| 3307 | { | 3107 | return null; |
| 3308 | p.tok_i += 2; | 3108 | } else { |
| 3309 | } | 3109 | 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 | } | 3110 | } |
| 3317 | } | 3111 | } |
| 3318 | 3112 | ||
| 3319 | /// Payload <- PIPE IDENTIFIER PIPE | 3113 | /// Payload <- PIPE IDENTIFIER PIPE |
| 3320 | fn parsePayload(p: *Parse) !TokenIndex { | 3114 | fn parsePayload(p: *Parse) Error!OptionalTokenIndex { |
| 3321 | _ = p.eatToken(.pipe) orelse return null_node; | 3115 | _ = p.eatToken(.pipe) orelse return .none; |
| 3322 | const identifier = try p.expectToken(.identifier); | 3116 | const identifier = try p.expectToken(.identifier); |
| 3323 | _ = try p.expectToken(.pipe); | 3117 | _ = try p.expectToken(.pipe); |
| 3324 | return identifier; | 3118 | return .fromToken(identifier); |
| 3325 | } | 3119 | } |
| 3326 | 3120 | ||
| 3327 | /// PtrPayload <- PIPE ASTERISK? IDENTIFIER PIPE | 3121 | /// PtrPayload <- PIPE ASTERISK? IDENTIFIER PIPE |
| 3328 | fn parsePtrPayload(p: *Parse) !TokenIndex { | 3122 | fn parsePtrPayload(p: *Parse) Error!OptionalTokenIndex { |
| 3329 | _ = p.eatToken(.pipe) orelse return null_node; | 3123 | _ = p.eatToken(.pipe) orelse return .none; |
| 3330 | _ = p.eatToken(.asterisk); | 3124 | _ = p.eatToken(.asterisk); |
| 3331 | const identifier = try p.expectToken(.identifier); | 3125 | const identifier = try p.expectToken(.identifier); |
| 3332 | _ = try p.expectToken(.pipe); | 3126 | _ = try p.expectToken(.pipe); |
| 3333 | return identifier; | 3127 | return .fromToken(identifier); |
| 3334 | } | 3128 | } |
| 3335 | 3129 | ||
| 3336 | /// Returns the first identifier token, if any. | 3130 | /// Returns the first identifier token, if any. |
| 3337 | /// | 3131 | /// |
| 3338 | /// PtrIndexPayload <- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE | 3132 | /// PtrIndexPayload <- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE |
| 3339 | fn parsePtrIndexPayload(p: *Parse) !TokenIndex { | 3133 | fn parsePtrIndexPayload(p: *Parse) Error!OptionalTokenIndex { |
| 3340 | _ = p.eatToken(.pipe) orelse return null_node; | 3134 | _ = p.eatToken(.pipe) orelse return .none; |
| 3341 | _ = p.eatToken(.asterisk); | 3135 | _ = p.eatToken(.asterisk); |
| 3342 | const identifier = try p.expectToken(.identifier); | 3136 | const identifier = try p.expectToken(.identifier); |
| 3343 | if (p.eatToken(.comma) != null) { | 3137 | if (p.eatToken(.comma) != null) { |
| 3344 | _ = try p.expectToken(.identifier); | 3138 | _ = try p.expectToken(.identifier); |
| 3345 | } | 3139 | } |
| 3346 | _ = try p.expectToken(.pipe); | 3140 | _ = try p.expectToken(.pipe); |
| 3347 | return identifier; | 3141 | return .fromToken(identifier); |
| 3348 | } | 3142 | } |
| 3349 | 3143 | ||
| 3350 | /// SwitchProng <- KEYWORD_inline? SwitchCase EQUALRARROW PtrIndexPayload? AssignExpr | 3144 | /// SwitchProng <- KEYWORD_inline? SwitchCase EQUALRARROW PtrIndexPayload? AssignExpr |
| ... | @@ -3352,7 +3146,7 @@ fn parsePtrIndexPayload(p: *Parse) !TokenIndex { | ... | @@ -3352,7 +3146,7 @@ fn parsePtrIndexPayload(p: *Parse) !TokenIndex { |
| 3352 | /// SwitchCase | 3146 | /// SwitchCase |
| 3353 | /// <- SwitchItem (COMMA SwitchItem)* COMMA? | 3147 | /// <- SwitchItem (COMMA SwitchItem)* COMMA? |
| 3354 | /// / KEYWORD_else | 3148 | /// / KEYWORD_else |
| 3355 | fn parseSwitchProng(p: *Parse) !Node.Index { | 3149 | fn parseSwitchProng(p: *Parse) !?Node.Index { |
| 3356 | const scratch_top = p.scratch.items.len; | 3150 | const scratch_top = p.scratch.items.len; |
| 3357 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 3151 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 3358 | 3152 | ||
| ... | @@ -3360,97 +3154,92 @@ fn parseSwitchProng(p: *Parse) !Node.Index { | ... | @@ -3360,97 +3154,92 @@ fn parseSwitchProng(p: *Parse) !Node.Index { |
| 3360 | 3154 | ||
| 3361 | if (p.eatToken(.keyword_else) == null) { | 3155 | if (p.eatToken(.keyword_else) == null) { |
| 3362 | while (true) { | 3156 | while (true) { |
| 3363 | const item = try p.parseSwitchItem(); | 3157 | const item = try p.parseSwitchItem() orelse break; |
| 3364 | if (item == 0) break; | ||
| 3365 | try p.scratch.append(p.gpa, item); | 3158 | try p.scratch.append(p.gpa, item); |
| 3366 | if (p.eatToken(.comma) == null) break; | 3159 | if (p.eatToken(.comma) == null) break; |
| 3367 | } | 3160 | } |
| 3368 | if (scratch_top == p.scratch.items.len) { | 3161 | if (scratch_top == p.scratch.items.len) { |
| 3369 | if (is_inline) p.tok_i -= 1; | 3162 | if (is_inline) p.tok_i -= 1; |
| 3370 | return null_node; | 3163 | return null; |
| 3371 | } | 3164 | } |
| 3372 | } | 3165 | } |
| 3373 | const arrow_token = try p.expectToken(.equal_angle_bracket_right); | 3166 | const arrow_token = try p.expectToken(.equal_angle_bracket_right); |
| 3374 | _ = try p.parsePtrIndexPayload(); | 3167 | _ = try p.parsePtrIndexPayload(); |
| 3375 | 3168 | ||
| 3376 | const items = p.scratch.items[scratch_top..]; | 3169 | const items = p.scratch.items[scratch_top..]; |
| 3377 | switch (items.len) { | 3170 | if (items.len <= 1) { |
| 3378 | 0 => return p.addNode(.{ | 3171 | return try p.addNode(.{ |
| 3379 | .tag = if (is_inline) .switch_case_inline_one else .switch_case_one, | 3172 | .tag = if (is_inline) .switch_case_inline_one else .switch_case_one, |
| 3380 | .main_token = arrow_token, | 3173 | .main_token = arrow_token, |
| 3381 | .data = .{ | 3174 | .data = .{ .opt_node_and_node = .{ |
| 3382 | .lhs = 0, | 3175 | if (items.len >= 1) items[0].toOptional() else .none, |
| 3383 | .rhs = try p.expectSingleAssignExpr(), | 3176 | try p.expectSingleAssignExpr(), |
| 3384 | }, | 3177 | } }, |
| 3385 | }), | 3178 | }); |
| 3386 | 1 => return p.addNode(.{ | 3179 | } else { |
| 3387 | .tag = if (is_inline) .switch_case_inline_one else .switch_case_one, | 3180 | 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, | 3181 | .tag = if (is_inline) .switch_case_inline else .switch_case, |
| 3396 | .main_token = arrow_token, | 3182 | .main_token = arrow_token, |
| 3397 | .data = .{ | 3183 | .data = .{ .extra_and_node = .{ |
| 3398 | .lhs = try p.addExtra(try p.listToSpan(items)), | 3184 | try p.addExtra(try p.listToSpan(items)), |
| 3399 | .rhs = try p.expectSingleAssignExpr(), | 3185 | try p.expectSingleAssignExpr(), |
| 3400 | }, | 3186 | } }, |
| 3401 | }), | 3187 | }); |
| 3402 | } | 3188 | } |
| 3403 | } | 3189 | } |
| 3404 | 3190 | ||
| 3405 | /// SwitchItem <- Expr (DOT3 Expr)? | 3191 | /// SwitchItem <- Expr (DOT3 Expr)? |
| 3406 | fn parseSwitchItem(p: *Parse) !Node.Index { | 3192 | fn parseSwitchItem(p: *Parse) !?Node.Index { |
| 3407 | const expr = try p.parseExpr(); | 3193 | const expr = try p.parseExpr() orelse return null; |
| 3408 | if (expr == 0) return null_node; | ||
| 3409 | 3194 | ||
| 3410 | if (p.eatToken(.ellipsis3)) |token| { | 3195 | if (p.eatToken(.ellipsis3)) |token| { |
| 3411 | return p.addNode(.{ | 3196 | return try p.addNode(.{ |
| 3412 | .tag = .switch_range, | 3197 | .tag = .switch_range, |
| 3413 | .main_token = token, | 3198 | .main_token = token, |
| 3414 | .data = .{ | 3199 | .data = .{ .node_and_node = .{ |
| 3415 | .lhs = expr, | 3200 | expr, |
| 3416 | .rhs = try p.expectExpr(), | 3201 | try p.expectExpr(), |
| 3417 | }, | 3202 | } }, |
| 3418 | }); | 3203 | }); |
| 3419 | } | 3204 | } |
| 3420 | return expr; | 3205 | return expr; |
| 3421 | } | 3206 | } |
| 3422 | 3207 | ||
| 3208 | /// The following invariant will hold: | ||
| 3209 | /// - `(bit_range_start == .none) == (bit_range_end == .none)` | ||
| 3210 | /// - `bit_range_start != .none` implies `align_node != .none` | ||
| 3211 | /// - `bit_range_end != .none` implies `align_node != .none` | ||
| 3423 | const PtrModifiers = struct { | 3212 | const PtrModifiers = struct { |
| 3424 | align_node: Node.Index, | 3213 | align_node: Node.OptionalIndex, |
| 3425 | addrspace_node: Node.Index, | 3214 | addrspace_node: Node.OptionalIndex, |
| 3426 | bit_range_start: Node.Index, | 3215 | bit_range_start: Node.OptionalIndex, |
| 3427 | bit_range_end: Node.Index, | 3216 | bit_range_end: Node.OptionalIndex, |
| 3428 | }; | 3217 | }; |
| 3429 | 3218 | ||
| 3430 | fn parsePtrModifiers(p: *Parse) !PtrModifiers { | 3219 | fn parsePtrModifiers(p: *Parse) !PtrModifiers { |
| 3431 | var result: PtrModifiers = .{ | 3220 | var result: PtrModifiers = .{ |
| 3432 | .align_node = 0, | 3221 | .align_node = .none, |
| 3433 | .addrspace_node = 0, | 3222 | .addrspace_node = .none, |
| 3434 | .bit_range_start = 0, | 3223 | .bit_range_start = .none, |
| 3435 | .bit_range_end = 0, | 3224 | .bit_range_end = .none, |
| 3436 | }; | 3225 | }; |
| 3437 | var saw_const = false; | 3226 | var saw_const = false; |
| 3438 | var saw_volatile = false; | 3227 | var saw_volatile = false; |
| 3439 | var saw_allowzero = false; | 3228 | var saw_allowzero = false; |
| 3440 | while (true) { | 3229 | while (true) { |
| 3441 | switch (p.token_tags[p.tok_i]) { | 3230 | switch (p.tokenTag(p.tok_i)) { |
| 3442 | .keyword_align => { | 3231 | .keyword_align => { |
| 3443 | if (result.align_node != 0) { | 3232 | if (result.align_node != .none) { |
| 3444 | try p.warn(.extra_align_qualifier); | 3233 | try p.warn(.extra_align_qualifier); |
| 3445 | } | 3234 | } |
| 3446 | p.tok_i += 1; | 3235 | p.tok_i += 1; |
| 3447 | _ = try p.expectToken(.l_paren); | 3236 | _ = try p.expectToken(.l_paren); |
| 3448 | result.align_node = try p.expectExpr(); | 3237 | result.align_node = (try p.expectExpr()).toOptional(); |
| 3449 | 3238 | ||
| 3450 | if (p.eatToken(.colon)) |_| { | 3239 | if (p.eatToken(.colon)) |_| { |
| 3451 | result.bit_range_start = try p.expectExpr(); | 3240 | result.bit_range_start = (try p.expectExpr()).toOptional(); |
| 3452 | _ = try p.expectToken(.colon); | 3241 | _ = try p.expectToken(.colon); |
| 3453 | result.bit_range_end = try p.expectExpr(); | 3242 | result.bit_range_end = (try p.expectExpr()).toOptional(); |
| 3454 | } | 3243 | } |
| 3455 | 3244 | ||
| 3456 | _ = try p.expectToken(.r_paren); | 3245 | _ = try p.expectToken(.r_paren); |
| ... | @@ -3477,10 +3266,10 @@ fn parsePtrModifiers(p: *Parse) !PtrModifiers { | ... | @@ -3477,10 +3266,10 @@ fn parsePtrModifiers(p: *Parse) !PtrModifiers { |
| 3477 | saw_allowzero = true; | 3266 | saw_allowzero = true; |
| 3478 | }, | 3267 | }, |
| 3479 | .keyword_addrspace => { | 3268 | .keyword_addrspace => { |
| 3480 | if (result.addrspace_node != 0) { | 3269 | if (result.addrspace_node != .none) { |
| 3481 | try p.warn(.extra_addrspace_qualifier); | 3270 | try p.warn(.extra_addrspace_qualifier); |
| 3482 | } | 3271 | } |
| 3483 | result.addrspace_node = try p.parseAddrSpace(); | 3272 | result.addrspace_node = .fromOptional(try p.parseAddrSpace()); |
| 3484 | }, | 3273 | }, |
| 3485 | else => return result, | 3274 | else => return result, |
| 3486 | } | 3275 | } |
| ... | @@ -3492,110 +3281,102 @@ fn parsePtrModifiers(p: *Parse) !PtrModifiers { | ... | @@ -3492,110 +3281,102 @@ fn parsePtrModifiers(p: *Parse) !PtrModifiers { |
| 3492 | /// / DOT IDENTIFIER | 3281 | /// / DOT IDENTIFIER |
| 3493 | /// / DOTASTERISK | 3282 | /// / DOTASTERISK |
| 3494 | /// / DOTQUESTIONMARK | 3283 | /// / DOTQUESTIONMARK |
| 3495 | fn parseSuffixOp(p: *Parse, lhs: Node.Index) !Node.Index { | 3284 | fn parseSuffixOp(p: *Parse, lhs: Node.Index) !?Node.Index { |
| 3496 | switch (p.token_tags[p.tok_i]) { | 3285 | switch (p.tokenTag(p.tok_i)) { |
| 3497 | .l_bracket => { | 3286 | .l_bracket => { |
| 3498 | const lbracket = p.nextToken(); | 3287 | const lbracket = p.nextToken(); |
| 3499 | const index_expr = try p.expectExpr(); | 3288 | const index_expr = try p.expectExpr(); |
| 3500 | 3289 | ||
| 3501 | if (p.eatToken(.ellipsis2)) |_| { | 3290 | if (p.eatToken(.ellipsis2)) |_| { |
| 3502 | const end_expr = try p.parseExpr(); | 3291 | const opt_end_expr = try p.parseExpr(); |
| 3503 | if (p.eatToken(.colon)) |_| { | 3292 | if (p.eatToken(.colon)) |_| { |
| 3504 | const sentinel = try p.expectExpr(); | 3293 | const sentinel = try p.expectExpr(); |
| 3505 | _ = try p.expectToken(.r_bracket); | 3294 | _ = try p.expectToken(.r_bracket); |
| 3506 | return p.addNode(.{ | 3295 | return try p.addNode(.{ |
| 3507 | .tag = .slice_sentinel, | 3296 | .tag = .slice_sentinel, |
| 3508 | .main_token = lbracket, | 3297 | .main_token = lbracket, |
| 3509 | .data = .{ | 3298 | .data = .{ .node_and_extra = .{ |
| 3510 | .lhs = lhs, | 3299 | lhs, try p.addExtra(Node.SliceSentinel{ |
| 3511 | .rhs = try p.addExtra(Node.SliceSentinel{ | ||
| 3512 | .start = index_expr, | 3300 | .start = index_expr, |
| 3513 | .end = end_expr, | 3301 | .end = .fromOptional(opt_end_expr), |
| 3514 | .sentinel = sentinel, | 3302 | .sentinel = sentinel, |
| 3515 | }), | 3303 | }), |
| 3516 | }, | 3304 | } }, |
| 3517 | }); | 3305 | }); |
| 3518 | } | 3306 | } |
| 3519 | _ = try p.expectToken(.r_bracket); | 3307 | _ = try p.expectToken(.r_bracket); |
| 3520 | if (end_expr == 0) { | 3308 | const end_expr = opt_end_expr orelse { |
| 3521 | return p.addNode(.{ | 3309 | return try p.addNode(.{ |
| 3522 | .tag = .slice_open, | 3310 | .tag = .slice_open, |
| 3523 | .main_token = lbracket, | 3311 | .main_token = lbracket, |
| 3524 | .data = .{ | 3312 | .data = .{ .node_and_node = .{ |
| 3525 | .lhs = lhs, | 3313 | lhs, |
| 3526 | .rhs = index_expr, | 3314 | index_expr, |
| 3527 | }, | 3315 | } }, |
| 3528 | }); | 3316 | }); |
| 3529 | } | 3317 | }; |
| 3530 | return p.addNode(.{ | 3318 | return try p.addNode(.{ |
| 3531 | .tag = .slice, | 3319 | .tag = .slice, |
| 3532 | .main_token = lbracket, | 3320 | .main_token = lbracket, |
| 3533 | .data = .{ | 3321 | .data = .{ .node_and_extra = .{ |
| 3534 | .lhs = lhs, | 3322 | lhs, try p.addExtra(Node.Slice{ |
| 3535 | .rhs = try p.addExtra(Node.Slice{ | ||
| 3536 | .start = index_expr, | 3323 | .start = index_expr, |
| 3537 | .end = end_expr, | 3324 | .end = end_expr, |
| 3538 | }), | 3325 | }), |
| 3539 | }, | 3326 | } }, |
| 3540 | }); | 3327 | }); |
| 3541 | } | 3328 | } |
| 3542 | _ = try p.expectToken(.r_bracket); | 3329 | _ = try p.expectToken(.r_bracket); |
| 3543 | return p.addNode(.{ | 3330 | return try p.addNode(.{ |
| 3544 | .tag = .array_access, | 3331 | .tag = .array_access, |
| 3545 | .main_token = lbracket, | 3332 | .main_token = lbracket, |
| 3546 | .data = .{ | 3333 | .data = .{ .node_and_node = .{ |
| 3547 | .lhs = lhs, | 3334 | lhs, |
| 3548 | .rhs = index_expr, | 3335 | index_expr, |
| 3549 | }, | 3336 | } }, |
| 3550 | }); | 3337 | }); |
| 3551 | }, | 3338 | }, |
| 3552 | .period_asterisk => return p.addNode(.{ | 3339 | .period_asterisk => return try p.addNode(.{ |
| 3553 | .tag = .deref, | 3340 | .tag = .deref, |
| 3554 | .main_token = p.nextToken(), | 3341 | .main_token = p.nextToken(), |
| 3555 | .data = .{ | 3342 | .data = .{ .node = lhs }, |
| 3556 | .lhs = lhs, | ||
| 3557 | .rhs = undefined, | ||
| 3558 | }, | ||
| 3559 | }), | 3343 | }), |
| 3560 | .invalid_periodasterisks => { | 3344 | .invalid_periodasterisks => { |
| 3561 | try p.warn(.asterisk_after_ptr_deref); | 3345 | try p.warn(.asterisk_after_ptr_deref); |
| 3562 | return p.addNode(.{ | 3346 | return try p.addNode(.{ |
| 3563 | .tag = .deref, | 3347 | .tag = .deref, |
| 3564 | .main_token = p.nextToken(), | 3348 | .main_token = p.nextToken(), |
| 3565 | .data = .{ | 3349 | .data = .{ .node = lhs }, |
| 3566 | .lhs = lhs, | ||
| 3567 | .rhs = undefined, | ||
| 3568 | }, | ||
| 3569 | }); | 3350 | }); |
| 3570 | }, | 3351 | }, |
| 3571 | .period => switch (p.token_tags[p.tok_i + 1]) { | 3352 | .period => switch (p.tokenTag(p.tok_i + 1)) { |
| 3572 | .identifier => return p.addNode(.{ | 3353 | .identifier => return try p.addNode(.{ |
| 3573 | .tag = .field_access, | 3354 | .tag = .field_access, |
| 3574 | .main_token = p.nextToken(), | 3355 | .main_token = p.nextToken(), |
| 3575 | .data = .{ | 3356 | .data = .{ .node_and_token = .{ |
| 3576 | .lhs = lhs, | 3357 | lhs, |
| 3577 | .rhs = p.nextToken(), | 3358 | p.nextToken(), |
| 3578 | }, | 3359 | } }, |
| 3579 | }), | 3360 | }), |
| 3580 | .question_mark => return p.addNode(.{ | 3361 | .question_mark => return try p.addNode(.{ |
| 3581 | .tag = .unwrap_optional, | 3362 | .tag = .unwrap_optional, |
| 3582 | .main_token = p.nextToken(), | 3363 | .main_token = p.nextToken(), |
| 3583 | .data = .{ | 3364 | .data = .{ .node_and_token = .{ |
| 3584 | .lhs = lhs, | 3365 | lhs, |
| 3585 | .rhs = p.nextToken(), | 3366 | p.nextToken(), |
| 3586 | }, | 3367 | } }, |
| 3587 | }), | 3368 | }), |
| 3588 | .l_brace => { | 3369 | .l_brace => { |
| 3589 | // this a misplaced `.{`, handle the error somewhere else | 3370 | // this a misplaced `.{`, handle the error somewhere else |
| 3590 | return null_node; | 3371 | return null; |
| 3591 | }, | 3372 | }, |
| 3592 | else => { | 3373 | else => { |
| 3593 | p.tok_i += 1; | 3374 | p.tok_i += 1; |
| 3594 | try p.warn(.expected_suffix_op); | 3375 | try p.warn(.expected_suffix_op); |
| 3595 | return null_node; | 3376 | return null; |
| 3596 | }, | 3377 | }, |
| 3597 | }, | 3378 | }, |
| 3598 | else => return null_node, | 3379 | else => return null, |
| 3599 | } | 3380 | } |
| 3600 | } | 3381 | } |
| 3601 | 3382 | ||
| ... | @@ -3608,17 +3389,17 @@ fn parseSuffixOp(p: *Parse, lhs: Node.Index) !Node.Index { | ... | @@ -3608,17 +3389,17 @@ fn parseSuffixOp(p: *Parse, lhs: Node.Index) !Node.Index { |
| 3608 | /// / KEYWORD_opaque | 3389 | /// / KEYWORD_opaque |
| 3609 | /// / KEYWORD_enum (LPAREN Expr RPAREN)? | 3390 | /// / KEYWORD_enum (LPAREN Expr RPAREN)? |
| 3610 | /// / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)? | 3391 | /// / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)? |
| 3611 | fn parseContainerDeclAuto(p: *Parse) !Node.Index { | 3392 | fn parseContainerDeclAuto(p: *Parse) !?Node.Index { |
| 3612 | const main_token = p.nextToken(); | 3393 | const main_token = p.nextToken(); |
| 3613 | const arg_expr = switch (p.token_tags[main_token]) { | 3394 | const arg_expr = switch (p.tokenTag(main_token)) { |
| 3614 | .keyword_opaque => null_node, | 3395 | .keyword_opaque => null, |
| 3615 | .keyword_struct, .keyword_enum => blk: { | 3396 | .keyword_struct, .keyword_enum => blk: { |
| 3616 | if (p.eatToken(.l_paren)) |_| { | 3397 | if (p.eatToken(.l_paren)) |_| { |
| 3617 | const expr = try p.expectExpr(); | 3398 | const expr = try p.expectExpr(); |
| 3618 | _ = try p.expectToken(.r_paren); | 3399 | _ = try p.expectToken(.r_paren); |
| 3619 | break :blk expr; | 3400 | break :blk expr; |
| 3620 | } else { | 3401 | } else { |
| 3621 | break :blk null_node; | 3402 | break :blk null; |
| 3622 | } | 3403 | } |
| 3623 | }, | 3404 | }, |
| 3624 | .keyword_union => blk: { | 3405 | .keyword_union => blk: { |
| ... | @@ -3633,16 +3414,16 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { | ... | @@ -3633,16 +3414,16 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { |
| 3633 | const members = try p.parseContainerMembers(); | 3414 | const members = try p.parseContainerMembers(); |
| 3634 | const members_span = try members.toSpan(p); | 3415 | const members_span = try members.toSpan(p); |
| 3635 | _ = try p.expectToken(.r_brace); | 3416 | _ = try p.expectToken(.r_brace); |
| 3636 | return p.addNode(.{ | 3417 | return try p.addNode(.{ |
| 3637 | .tag = switch (members.trailing) { | 3418 | .tag = switch (members.trailing) { |
| 3638 | true => .tagged_union_enum_tag_trailing, | 3419 | true => .tagged_union_enum_tag_trailing, |
| 3639 | false => .tagged_union_enum_tag, | 3420 | false => .tagged_union_enum_tag, |
| 3640 | }, | 3421 | }, |
| 3641 | .main_token = main_token, | 3422 | .main_token = main_token, |
| 3642 | .data = .{ | 3423 | .data = .{ .node_and_extra = .{ |
| 3643 | .lhs = enum_tag_expr, | 3424 | enum_tag_expr, |
| 3644 | .rhs = try p.addExtra(members_span), | 3425 | try p.addExtra(members_span), |
| 3645 | }, | 3426 | } }, |
| 3646 | }); | 3427 | }); |
| 3647 | } else { | 3428 | } else { |
| 3648 | _ = try p.expectToken(.r_paren); | 3429 | _ = try p.expectToken(.r_paren); |
| ... | @@ -3651,29 +3432,23 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { | ... | @@ -3651,29 +3432,23 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { |
| 3651 | const members = try p.parseContainerMembers(); | 3432 | const members = try p.parseContainerMembers(); |
| 3652 | _ = try p.expectToken(.r_brace); | 3433 | _ = try p.expectToken(.r_brace); |
| 3653 | if (members.len <= 2) { | 3434 | if (members.len <= 2) { |
| 3654 | return p.addNode(.{ | 3435 | return try p.addNode(.{ |
| 3655 | .tag = switch (members.trailing) { | 3436 | .tag = switch (members.trailing) { |
| 3656 | true => .tagged_union_two_trailing, | 3437 | true => .tagged_union_two_trailing, |
| 3657 | false => .tagged_union_two, | 3438 | false => .tagged_union_two, |
| 3658 | }, | 3439 | }, |
| 3659 | .main_token = main_token, | 3440 | .main_token = main_token, |
| 3660 | .data = .{ | 3441 | .data = members.data, |
| 3661 | .lhs = members.lhs, | ||
| 3662 | .rhs = members.rhs, | ||
| 3663 | }, | ||
| 3664 | }); | 3442 | }); |
| 3665 | } else { | 3443 | } else { |
| 3666 | const span = try members.toSpan(p); | 3444 | const span = try members.toSpan(p); |
| 3667 | return p.addNode(.{ | 3445 | return try p.addNode(.{ |
| 3668 | .tag = switch (members.trailing) { | 3446 | .tag = switch (members.trailing) { |
| 3669 | true => .tagged_union_trailing, | 3447 | true => .tagged_union_trailing, |
| 3670 | false => .tagged_union, | 3448 | false => .tagged_union, |
| 3671 | }, | 3449 | }, |
| 3672 | .main_token = main_token, | 3450 | .main_token = main_token, |
| 3673 | .data = .{ | 3451 | .data = .{ .extra_range = span }, |
| 3674 | .lhs = span.start, | ||
| 3675 | .rhs = span.end, | ||
| 3676 | }, | ||
| 3677 | }); | 3452 | }); |
| 3678 | } | 3453 | } |
| 3679 | } | 3454 | } |
| ... | @@ -3683,7 +3458,7 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { | ... | @@ -3683,7 +3458,7 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { |
| 3683 | break :blk expr; | 3458 | break :blk expr; |
| 3684 | } | 3459 | } |
| 3685 | } else { | 3460 | } else { |
| 3686 | break :blk null_node; | 3461 | break :blk null; |
| 3687 | } | 3462 | } |
| 3688 | }, | 3463 | }, |
| 3689 | else => { | 3464 | else => { |
| ... | @@ -3694,48 +3469,42 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { | ... | @@ -3694,48 +3469,42 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { |
| 3694 | _ = try p.expectToken(.l_brace); | 3469 | _ = try p.expectToken(.l_brace); |
| 3695 | const members = try p.parseContainerMembers(); | 3470 | const members = try p.parseContainerMembers(); |
| 3696 | _ = try p.expectToken(.r_brace); | 3471 | _ = try p.expectToken(.r_brace); |
| 3697 | if (arg_expr == 0) { | 3472 | if (arg_expr == null) { |
| 3698 | if (members.len <= 2) { | 3473 | if (members.len <= 2) { |
| 3699 | return p.addNode(.{ | 3474 | return try p.addNode(.{ |
| 3700 | .tag = switch (members.trailing) { | 3475 | .tag = switch (members.trailing) { |
| 3701 | true => .container_decl_two_trailing, | 3476 | true => .container_decl_two_trailing, |
| 3702 | false => .container_decl_two, | 3477 | false => .container_decl_two, |
| 3703 | }, | 3478 | }, |
| 3704 | .main_token = main_token, | 3479 | .main_token = main_token, |
| 3705 | .data = .{ | 3480 | .data = members.data, |
| 3706 | .lhs = members.lhs, | ||
| 3707 | .rhs = members.rhs, | ||
| 3708 | }, | ||
| 3709 | }); | 3481 | }); |
| 3710 | } else { | 3482 | } else { |
| 3711 | const span = try members.toSpan(p); | 3483 | const span = try members.toSpan(p); |
| 3712 | return p.addNode(.{ | 3484 | return try p.addNode(.{ |
| 3713 | .tag = switch (members.trailing) { | 3485 | .tag = switch (members.trailing) { |
| 3714 | true => .container_decl_trailing, | 3486 | true => .container_decl_trailing, |
| 3715 | false => .container_decl, | 3487 | false => .container_decl, |
| 3716 | }, | 3488 | }, |
| 3717 | .main_token = main_token, | 3489 | .main_token = main_token, |
| 3718 | .data = .{ | 3490 | .data = .{ .extra_range = span }, |
| 3719 | .lhs = span.start, | ||
| 3720 | .rhs = span.end, | ||
| 3721 | }, | ||
| 3722 | }); | 3491 | }); |
| 3723 | } | 3492 | } |
| 3724 | } else { | 3493 | } else { |
| 3725 | const span = try members.toSpan(p); | 3494 | const span = try members.toSpan(p); |
| 3726 | return p.addNode(.{ | 3495 | return try p.addNode(.{ |
| 3727 | .tag = switch (members.trailing) { | 3496 | .tag = switch (members.trailing) { |
| 3728 | true => .container_decl_arg_trailing, | 3497 | true => .container_decl_arg_trailing, |
| 3729 | false => .container_decl_arg, | 3498 | false => .container_decl_arg, |
| 3730 | }, | 3499 | }, |
| 3731 | .main_token = main_token, | 3500 | .main_token = main_token, |
| 3732 | .data = .{ | 3501 | .data = .{ .node_and_extra = .{ |
| 3733 | .lhs = arg_expr, | 3502 | arg_expr.?, |
| 3734 | .rhs = try p.addExtra(Node.SubRange{ | 3503 | try p.addExtra(Node.SubRange{ |
| 3735 | .start = span.start, | 3504 | .start = span.start, |
| 3736 | .end = span.end, | 3505 | .end = span.end, |
| 3737 | }), | 3506 | }), |
| 3738 | }, | 3507 | } }, |
| 3739 | }); | 3508 | }); |
| 3740 | } | 3509 | } |
| 3741 | } | 3510 | } |
| ... | @@ -3744,24 +3513,24 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { | ... | @@ -3744,24 +3513,24 @@ fn parseContainerDeclAuto(p: *Parse) !Node.Index { |
| 3744 | /// C's 'struct Foo {};' to Zig's 'const Foo = struct {};'. | 3513 | /// C's 'struct Foo {};' to Zig's 'const Foo = struct {};'. |
| 3745 | fn parseCStyleContainer(p: *Parse) Error!bool { | 3514 | fn parseCStyleContainer(p: *Parse) Error!bool { |
| 3746 | const main_token = p.tok_i; | 3515 | const main_token = p.tok_i; |
| 3747 | switch (p.token_tags[p.tok_i]) { | 3516 | switch (p.tokenTag(p.tok_i)) { |
| 3748 | .keyword_enum, .keyword_union, .keyword_struct => {}, | 3517 | .keyword_enum, .keyword_union, .keyword_struct => {}, |
| 3749 | else => return false, | 3518 | else => return false, |
| 3750 | } | 3519 | } |
| 3751 | const identifier = p.tok_i + 1; | 3520 | const identifier = p.tok_i + 1; |
| 3752 | if (p.token_tags[identifier] != .identifier) return false; | 3521 | if (p.tokenTag(identifier) != .identifier) return false; |
| 3753 | p.tok_i += 2; | 3522 | p.tok_i += 2; |
| 3754 | 3523 | ||
| 3755 | try p.warnMsg(.{ | 3524 | try p.warnMsg(.{ |
| 3756 | .tag = .c_style_container, | 3525 | .tag = .c_style_container, |
| 3757 | .token = identifier, | 3526 | .token = identifier, |
| 3758 | .extra = .{ .expected_tag = p.token_tags[main_token] }, | 3527 | .extra = .{ .expected_tag = p.tokenTag(main_token) }, |
| 3759 | }); | 3528 | }); |
| 3760 | try p.warnMsg(.{ | 3529 | try p.warnMsg(.{ |
| 3761 | .tag = .zig_style_container, | 3530 | .tag = .zig_style_container, |
| 3762 | .is_note = true, | 3531 | .is_note = true, |
| 3763 | .token = identifier, | 3532 | .token = identifier, |
| 3764 | .extra = .{ .expected_tag = p.token_tags[main_token] }, | 3533 | .extra = .{ .expected_tag = p.tokenTag(main_token) }, |
| 3765 | }); | 3534 | }); |
| 3766 | 3535 | ||
| 3767 | _ = try p.expectToken(.l_brace); | 3536 | _ = try p.expectToken(.l_brace); |
| ... | @@ -3774,8 +3543,8 @@ fn parseCStyleContainer(p: *Parse) Error!bool { | ... | @@ -3774,8 +3543,8 @@ fn parseCStyleContainer(p: *Parse) Error!bool { |
| 3774 | /// Holds temporary data until we are ready to construct the full ContainerDecl AST node. | 3543 | /// Holds temporary data until we are ready to construct the full ContainerDecl AST node. |
| 3775 | /// | 3544 | /// |
| 3776 | /// ByteAlign <- KEYWORD_align LPAREN Expr RPAREN | 3545 | /// ByteAlign <- KEYWORD_align LPAREN Expr RPAREN |
| 3777 | fn parseByteAlign(p: *Parse) !Node.Index { | 3546 | fn parseByteAlign(p: *Parse) !?Node.Index { |
| 3778 | _ = p.eatToken(.keyword_align) orelse return null_node; | 3547 | _ = p.eatToken(.keyword_align) orelse return null; |
| 3779 | _ = try p.expectToken(.l_paren); | 3548 | _ = try p.expectToken(.l_paren); |
| 3780 | const expr = try p.expectExpr(); | 3549 | const expr = try p.expectExpr(); |
| 3781 | _ = try p.expectToken(.r_paren); | 3550 | _ = try p.expectToken(.r_paren); |
| ... | @@ -3788,12 +3557,11 @@ fn parseSwitchProngList(p: *Parse) !Node.SubRange { | ... | @@ -3788,12 +3557,11 @@ fn parseSwitchProngList(p: *Parse) !Node.SubRange { |
| 3788 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 3557 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 3789 | 3558 | ||
| 3790 | while (true) { | 3559 | while (true) { |
| 3791 | const item = try parseSwitchProng(p); | 3560 | const item = try parseSwitchProng(p) orelse break; |
| 3792 | if (item == 0) break; | ||
| 3793 | 3561 | ||
| 3794 | try p.scratch.append(p.gpa, item); | 3562 | try p.scratch.append(p.gpa, item); |
| 3795 | 3563 | ||
| 3796 | switch (p.token_tags[p.tok_i]) { | 3564 | switch (p.tokenTag(p.tok_i)) { |
| 3797 | .comma => p.tok_i += 1, | 3565 | .comma => p.tok_i += 1, |
| 3798 | // All possible delimiters. | 3566 | // All possible delimiters. |
| 3799 | .colon, .r_paren, .r_brace, .r_bracket => break, | 3567 | .colon, .r_paren, .r_brace, .r_bracket => break, |
| ... | @@ -3813,13 +3581,13 @@ fn parseParamDeclList(p: *Parse) !SmallSpan { | ... | @@ -3813,13 +3581,13 @@ fn parseParamDeclList(p: *Parse) !SmallSpan { |
| 3813 | while (true) { | 3581 | while (true) { |
| 3814 | if (p.eatToken(.r_paren)) |_| break; | 3582 | if (p.eatToken(.r_paren)) |_| break; |
| 3815 | if (varargs == .seen) varargs = .{ .nonfinal = p.tok_i }; | 3583 | if (varargs == .seen) varargs = .{ .nonfinal = p.tok_i }; |
| 3816 | const param = try p.expectParamDecl(); | 3584 | const opt_param = try p.expectParamDecl(); |
| 3817 | if (param != 0) { | 3585 | if (opt_param) |param| { |
| 3818 | try p.scratch.append(p.gpa, param); | 3586 | try p.scratch.append(p.gpa, param); |
| 3819 | } else if (p.token_tags[p.tok_i - 1] == .ellipsis3) { | 3587 | } else if (p.tokenTag(p.tok_i - 1) == .ellipsis3) { |
| 3820 | if (varargs == .none) varargs = .seen; | 3588 | if (varargs == .none) varargs = .seen; |
| 3821 | } | 3589 | } |
| 3822 | switch (p.token_tags[p.tok_i]) { | 3590 | switch (p.tokenTag(p.tok_i)) { |
| 3823 | .comma => p.tok_i += 1, | 3591 | .comma => p.tok_i += 1, |
| 3824 | .r_paren => { | 3592 | .r_paren => { |
| 3825 | p.tok_i += 1; | 3593 | p.tok_i += 1; |
| ... | @@ -3835,9 +3603,9 @@ fn parseParamDeclList(p: *Parse) !SmallSpan { | ... | @@ -3835,9 +3603,9 @@ fn parseParamDeclList(p: *Parse) !SmallSpan { |
| 3835 | } | 3603 | } |
| 3836 | const params = p.scratch.items[scratch_top..]; | 3604 | const params = p.scratch.items[scratch_top..]; |
| 3837 | return switch (params.len) { | 3605 | return switch (params.len) { |
| 3838 | 0 => SmallSpan{ .zero_or_one = 0 }, | 3606 | 0 => .{ .zero_or_one = .none }, |
| 3839 | 1 => SmallSpan{ .zero_or_one = params[0] }, | 3607 | 1 => .{ .zero_or_one = params[0].toOptional() }, |
| 3840 | else => SmallSpan{ .multi = try p.listToSpan(params) }, | 3608 | else => .{ .multi = try p.listToSpan(params) }, |
| 3841 | }; | 3609 | }; |
| 3842 | } | 3610 | } |
| 3843 | 3611 | ||
| ... | @@ -3852,10 +3620,7 @@ fn parseBuiltinCall(p: *Parse) !Node.Index { | ... | @@ -3852,10 +3620,7 @@ fn parseBuiltinCall(p: *Parse) !Node.Index { |
| 3852 | return p.addNode(.{ | 3620 | return p.addNode(.{ |
| 3853 | .tag = .identifier, | 3621 | .tag = .identifier, |
| 3854 | .main_token = builtin_token, | 3622 | .main_token = builtin_token, |
| 3855 | .data = .{ | 3623 | .data = undefined, |
| 3856 | .lhs = undefined, | ||
| 3857 | .rhs = undefined, | ||
| 3858 | }, | ||
| 3859 | }); | 3624 | }); |
| 3860 | }; | 3625 | }; |
| 3861 | const scratch_top = p.scratch.items.len; | 3626 | const scratch_top = p.scratch.items.len; |
| ... | @@ -3864,7 +3629,7 @@ fn parseBuiltinCall(p: *Parse) !Node.Index { | ... | @@ -3864,7 +3629,7 @@ fn parseBuiltinCall(p: *Parse) !Node.Index { |
| 3864 | if (p.eatToken(.r_paren)) |_| break; | 3629 | if (p.eatToken(.r_paren)) |_| break; |
| 3865 | const param = try p.expectExpr(); | 3630 | const param = try p.expectExpr(); |
| 3866 | try p.scratch.append(p.gpa, param); | 3631 | try p.scratch.append(p.gpa, param); |
| 3867 | switch (p.token_tags[p.tok_i]) { | 3632 | switch (p.tokenTag(p.tok_i)) { |
| 3868 | .comma => p.tok_i += 1, | 3633 | .comma => p.tok_i += 1, |
| 3869 | .r_paren => { | 3634 | .r_paren => { |
| 3870 | p.tok_i += 1; | 3635 | p.tok_i += 1; |
| ... | @@ -3874,88 +3639,66 @@ fn parseBuiltinCall(p: *Parse) !Node.Index { | ... | @@ -3874,88 +3639,66 @@ fn parseBuiltinCall(p: *Parse) !Node.Index { |
| 3874 | else => try p.warn(.expected_comma_after_arg), | 3639 | else => try p.warn(.expected_comma_after_arg), |
| 3875 | } | 3640 | } |
| 3876 | } | 3641 | } |
| 3877 | const comma = (p.token_tags[p.tok_i - 2] == .comma); | 3642 | const comma = (p.tokenTag(p.tok_i - 2)) == .comma; |
| 3878 | const params = p.scratch.items[scratch_top..]; | 3643 | const params = p.scratch.items[scratch_top..]; |
| 3879 | switch (params.len) { | 3644 | if (params.len <= 2) { |
| 3880 | 0 => return p.addNode(.{ | 3645 | 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, | 3646 | .tag = if (comma) .builtin_call_two_comma else .builtin_call_two, |
| 3890 | .main_token = builtin_token, | 3647 | .main_token = builtin_token, |
| 3891 | .data = .{ | 3648 | .data = .{ .opt_node_and_opt_node = .{ |
| 3892 | .lhs = params[0], | 3649 | if (params.len >= 1) .fromOptional(params[0]) else .none, |
| 3893 | .rhs = 0, | 3650 | if (params.len >= 2) .fromOptional(params[1]) else .none, |
| 3894 | }, | 3651 | } }, |
| 3895 | }), | 3652 | }); |
| 3896 | 2 => return p.addNode(.{ | 3653 | } else { |
| 3897 | .tag = if (comma) .builtin_call_two_comma else .builtin_call_two, | 3654 | const span = try p.listToSpan(params); |
| 3655 | return p.addNode(.{ | ||
| 3656 | .tag = if (comma) .builtin_call_comma else .builtin_call, | ||
| 3898 | .main_token = builtin_token, | 3657 | .main_token = builtin_token, |
| 3899 | .data = .{ | 3658 | .data = .{ .extra_range = span }, |
| 3900 | .lhs = params[0], | 3659 | }); |
| 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 | } | 3660 | } |
| 3916 | } | 3661 | } |
| 3917 | 3662 | ||
| 3918 | /// IfPrefix <- KEYWORD_if LPAREN Expr RPAREN PtrPayload? | 3663 | /// IfPrefix <- KEYWORD_if LPAREN Expr RPAREN PtrPayload? |
| 3919 | fn parseIf(p: *Parse, comptime bodyParseFn: fn (p: *Parse) Error!Node.Index) !Node.Index { | 3664 | 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; | 3665 | const if_token = p.eatToken(.keyword_if) orelse return null; |
| 3921 | _ = try p.expectToken(.l_paren); | 3666 | _ = try p.expectToken(.l_paren); |
| 3922 | const condition = try p.expectExpr(); | 3667 | const condition = try p.expectExpr(); |
| 3923 | _ = try p.expectToken(.r_paren); | 3668 | _ = try p.expectToken(.r_paren); |
| 3924 | _ = try p.parsePtrPayload(); | 3669 | _ = try p.parsePtrPayload(); |
| 3925 | 3670 | ||
| 3926 | const then_expr = try bodyParseFn(p); | 3671 | const then_expr = try bodyParseFn(p); |
| 3927 | assert(then_expr != 0); | ||
| 3928 | 3672 | ||
| 3929 | _ = p.eatToken(.keyword_else) orelse return p.addNode(.{ | 3673 | _ = p.eatToken(.keyword_else) orelse return try p.addNode(.{ |
| 3930 | .tag = .if_simple, | 3674 | .tag = .if_simple, |
| 3931 | .main_token = if_token, | 3675 | .main_token = if_token, |
| 3932 | .data = .{ | 3676 | .data = .{ .node_and_node = .{ |
| 3933 | .lhs = condition, | 3677 | condition, |
| 3934 | .rhs = then_expr, | 3678 | then_expr, |
| 3935 | }, | 3679 | } }, |
| 3936 | }); | 3680 | }); |
| 3937 | _ = try p.parsePayload(); | 3681 | _ = try p.parsePayload(); |
| 3938 | const else_expr = try bodyParseFn(p); | 3682 | const else_expr = try bodyParseFn(p); |
| 3939 | assert(else_expr != 0); | ||
| 3940 | 3683 | ||
| 3941 | return p.addNode(.{ | 3684 | return try p.addNode(.{ |
| 3942 | .tag = .@"if", | 3685 | .tag = .@"if", |
| 3943 | .main_token = if_token, | 3686 | .main_token = if_token, |
| 3944 | .data = .{ | 3687 | .data = .{ .node_and_extra = .{ |
| 3945 | .lhs = condition, | 3688 | condition, |
| 3946 | .rhs = try p.addExtra(Node.If{ | 3689 | try p.addExtra(Node.If{ |
| 3947 | .then_expr = then_expr, | 3690 | .then_expr = then_expr, |
| 3948 | .else_expr = else_expr, | 3691 | .else_expr = else_expr, |
| 3949 | }), | 3692 | }), |
| 3950 | }, | 3693 | } }, |
| 3951 | }); | 3694 | }); |
| 3952 | } | 3695 | } |
| 3953 | 3696 | ||
| 3954 | /// ForExpr <- ForPrefix Expr (KEYWORD_else Expr)? | 3697 | /// ForExpr <- ForPrefix Expr (KEYWORD_else Expr)? |
| 3955 | /// | 3698 | /// |
| 3956 | /// ForTypeExpr <- ForPrefix TypeExpr (KEYWORD_else TypeExpr)? | 3699 | /// ForTypeExpr <- ForPrefix TypeExpr (KEYWORD_else TypeExpr)? |
| 3957 | fn parseFor(p: *Parse, comptime bodyParseFn: fn (p: *Parse) Error!Node.Index) !Node.Index { | 3700 | 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; | 3701 | const for_token = p.eatToken(.keyword_for) orelse return null; |
| 3959 | 3702 | ||
| 3960 | const scratch_top = p.scratch.items.len; | 3703 | const scratch_top = p.scratch.items.len; |
| 3961 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 3704 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| ... | @@ -3969,27 +3712,24 @@ fn parseFor(p: *Parse, comptime bodyParseFn: fn (p: *Parse) Error!Node.Index) !N | ... | @@ -3969,27 +3712,24 @@ fn parseFor(p: *Parse, comptime bodyParseFn: fn (p: *Parse) Error!Node.Index) !N |
| 3969 | try p.scratch.append(p.gpa, else_expr); | 3712 | try p.scratch.append(p.gpa, else_expr); |
| 3970 | has_else = true; | 3713 | has_else = true; |
| 3971 | } else if (inputs == 1) { | 3714 | } else if (inputs == 1) { |
| 3972 | return p.addNode(.{ | 3715 | return try p.addNode(.{ |
| 3973 | .tag = .for_simple, | 3716 | .tag = .for_simple, |
| 3974 | .main_token = for_token, | 3717 | .main_token = for_token, |
| 3975 | .data = .{ | 3718 | .data = .{ .node_and_node = .{ |
| 3976 | .lhs = p.scratch.items[scratch_top], | 3719 | p.scratch.items[scratch_top], |
| 3977 | .rhs = then_expr, | 3720 | then_expr, |
| 3978 | }, | 3721 | } }, |
| 3979 | }); | 3722 | }); |
| 3980 | } else { | 3723 | } else { |
| 3981 | try p.scratch.append(p.gpa, then_expr); | 3724 | try p.scratch.append(p.gpa, then_expr); |
| 3982 | } | 3725 | } |
| 3983 | return p.addNode(.{ | 3726 | return try p.addNode(.{ |
| 3984 | .tag = .@"for", | 3727 | .tag = .@"for", |
| 3985 | .main_token = for_token, | 3728 | .main_token = for_token, |
| 3986 | .data = .{ | 3729 | .data = .{ .@"for" = .{ |
| 3987 | .lhs = (try p.listToSpan(p.scratch.items[scratch_top..])).start, | 3730 | (try p.listToSpan(p.scratch.items[scratch_top..])).start, |
| 3988 | .rhs = @as(u32, @bitCast(Node.For{ | 3731 | .{ .inputs = @intCast(inputs), .has_else = has_else }, |
| 3989 | .inputs = @as(u31, @intCast(inputs)), | 3732 | } }, |
| 3990 | .has_else = has_else, | ||
| 3991 | })), | ||
| 3992 | }, | ||
| 3993 | }); | 3733 | }); |
| 3994 | } | 3734 | } |
| 3995 | 3735 | ||
| ... | @@ -4011,21 +3751,29 @@ fn eatDocComments(p: *Parse) Allocator.Error!?TokenIndex { | ... | @@ -4011,21 +3751,29 @@ fn eatDocComments(p: *Parse) Allocator.Error!?TokenIndex { |
| 4011 | } | 3751 | } |
| 4012 | 3752 | ||
| 4013 | fn tokensOnSameLine(p: *Parse, token1: TokenIndex, token2: TokenIndex) bool { | 3753 | 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; | 3754 | return std.mem.indexOfScalar(u8, p.source[p.tokenStart(token1)..p.tokenStart(token2)], '\n') == null; |
| 4015 | } | 3755 | } |
| 4016 | 3756 | ||
| 4017 | fn eatToken(p: *Parse, tag: Token.Tag) ?TokenIndex { | 3757 | fn eatToken(p: *Parse, tag: Token.Tag) ?TokenIndex { |
| 4018 | return if (p.token_tags[p.tok_i] == tag) p.nextToken() else null; | 3758 | return if (p.tokenTag(p.tok_i) == tag) p.nextToken() else null; |
| 3759 | } | ||
| 3760 | |||
| 3761 | fn eatTokens(p: *Parse, tags: []const Token.Tag) ?TokenIndex { | ||
| 3762 | const available_tags = p.tokens.items(.tag)[p.tok_i..]; | ||
| 3763 | if (!std.mem.startsWith(Token.Tag, available_tags, tags)) return null; | ||
| 3764 | const result = p.tok_i; | ||
| 3765 | p.tok_i += @intCast(tags.len); | ||
| 3766 | return result; | ||
| 4019 | } | 3767 | } |
| 4020 | 3768 | ||
| 4021 | fn assertToken(p: *Parse, tag: Token.Tag) TokenIndex { | 3769 | fn assertToken(p: *Parse, tag: Token.Tag) TokenIndex { |
| 4022 | const token = p.nextToken(); | 3770 | const token = p.nextToken(); |
| 4023 | assert(p.token_tags[token] == tag); | 3771 | assert(p.tokenTag(token) == tag); |
| 4024 | return token; | 3772 | return token; |
| 4025 | } | 3773 | } |
| 4026 | 3774 | ||
| 4027 | fn expectToken(p: *Parse, tag: Token.Tag) Error!TokenIndex { | 3775 | fn expectToken(p: *Parse, tag: Token.Tag) Error!TokenIndex { |
| 4028 | if (p.token_tags[p.tok_i] != tag) { | 3776 | if (p.tokenTag(p.tok_i) != tag) { |
| 4029 | return p.failMsg(.{ | 3777 | return p.failMsg(.{ |
| 4030 | .tag = .expected_token, | 3778 | .tag = .expected_token, |
| 4031 | .token = p.tok_i, | 3779 | .token = p.tok_i, |
| ... | @@ -4036,7 +3784,7 @@ fn expectToken(p: *Parse, tag: Token.Tag) Error!TokenIndex { | ... | @@ -4036,7 +3784,7 @@ fn expectToken(p: *Parse, tag: Token.Tag) Error!TokenIndex { |
| 4036 | } | 3784 | } |
| 4037 | 3785 | ||
| 4038 | fn expectSemicolon(p: *Parse, error_tag: AstError.Tag, recoverable: bool) Error!void { | 3786 | fn expectSemicolon(p: *Parse, error_tag: AstError.Tag, recoverable: bool) Error!void { |
| 4039 | if (p.token_tags[p.tok_i] == .semicolon) { | 3787 | if (p.tokenTag(p.tok_i) == .semicolon) { |
| 4040 | _ = p.nextToken(); | 3788 | _ = p.nextToken(); |
| 4041 | return; | 3789 | return; |
| 4042 | } | 3790 | } |
| ... | @@ -4050,8 +3798,6 @@ fn nextToken(p: *Parse) TokenIndex { | ... | @@ -4050,8 +3798,6 @@ fn nextToken(p: *Parse) TokenIndex { |
| 4050 | return result; | 3798 | return result; |
| 4051 | } | 3799 | } |
| 4052 | 3800 | ||
| 4053 | const null_node: Node.Index = 0; | ||
| 4054 | |||
| 4055 | const Parse = @This(); | 3801 | const Parse = @This(); |
| 4056 | const std = @import("../std.zig"); | 3802 | const std = @import("../std.zig"); |
| 4057 | const assert = std.debug.assert; | 3803 | const assert = std.debug.assert; |
| ... | @@ -4060,6 +3806,8 @@ const Ast = std.zig.Ast; | ... | @@ -4060,6 +3806,8 @@ const Ast = std.zig.Ast; |
| 4060 | const Node = Ast.Node; | 3806 | const Node = Ast.Node; |
| 4061 | const AstError = Ast.Error; | 3807 | const AstError = Ast.Error; |
| 4062 | const TokenIndex = Ast.TokenIndex; | 3808 | const TokenIndex = Ast.TokenIndex; |
| 3809 | const OptionalTokenIndex = Ast.OptionalTokenIndex; | ||
| 3810 | const ExtraIndex = Ast.ExtraIndex; | ||
| 4063 | const Token = std.zig.Token; | 3811 | const Token = std.zig.Token; |
| 4064 | 3812 | ||
| 4065 | test { | 3813 | 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+44-56| ... | @@ -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,23 +248,20 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator | ... | @@ -251,23 +248,20 @@ 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.addErrorTok(node, "array indexing is not allowed in ZON", .{}), | 255 | .array_access => try zg.addErrorNode(node, "array indexing is not allowed in ZON", .{}), |
| 259 | 256 | ||
| 260 | .block_two, | 257 | .block_two, |
| 261 | .block_two_semicolon, | 258 | .block_two_semicolon, |
| 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+469-530| ... | @@ -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,24 +142,20 @@ fn renderMember( | ... | @@ -141,24 +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 node_tags = tree.nodes.items(.tag); | ||
| 145 | const token_tags = tree.tokens.items(.tag); | ||
| 146 | const main_tokens = tree.nodes.items(.main_token); | ||
| 147 | const datas = tree.nodes.items(.data); | ||
| 148 | if (r.fixups.omit_nodes.contains(decl)) return; | 145 | if (r.fixups.omit_nodes.contains(decl)) return; |
| 149 | try renderDocComments(r, tree.firstToken(decl)); | 146 | try renderDocComments(r, tree.firstToken(decl)); |
| 150 | switch (tree.nodes.items(.tag)[decl]) { | 147 | switch (tree.nodeTag(decl)) { |
| 151 | .fn_decl => { | 148 | .fn_decl => { |
| 152 | // Some examples: | 149 | // Some examples: |
| 153 | // pub extern "foo" fn ... | 150 | // pub extern "foo" fn ... |
| 154 | // export fn ... | 151 | // export fn ... |
| 155 | const fn_proto = datas[decl].lhs; | 152 | const fn_proto, const body_node = tree.nodeData(decl).node_and_node; |
| 156 | const fn_token = main_tokens[fn_proto]; | 153 | const fn_token = tree.nodeMainToken(fn_proto); |
| 157 | // Go back to the first token we should render here. | 154 | // Go back to the first token we should render here. |
| 158 | var i = fn_token; | 155 | var i = fn_token; |
| 159 | while (i > 0) { | 156 | while (i > 0) { |
| 160 | i -= 1; | 157 | i -= 1; |
| 161 | switch (token_tags[i]) { | 158 | switch (tree.tokenTag(i)) { |
| 162 | .keyword_extern, | 159 | .keyword_extern, |
| 163 | .keyword_export, | 160 | .keyword_export, |
| 164 | .keyword_pub, | 161 | .keyword_pub, |
| ... | @@ -173,31 +170,34 @@ fn renderMember( | ... | @@ -173,31 +170,34 @@ fn renderMember( |
| 173 | }, | 170 | }, |
| 174 | } | 171 | } |
| 175 | } | 172 | } |
| 173 | |||
| 176 | while (i < fn_token) : (i += 1) { | 174 | while (i < fn_token) : (i += 1) { |
| 177 | try renderToken(r, i, .space); | 175 | try renderToken(r, i, .space); |
| 178 | } | 176 | } |
| 179 | switch (tree.nodes.items(.tag)[fn_proto]) { | 177 | switch (tree.nodeTag(fn_proto)) { |
| 180 | .fn_proto_one, .fn_proto => { | 178 | .fn_proto_one, .fn_proto => { |
| 181 | const callconv_expr = if (tree.nodes.items(.tag)[fn_proto] == .fn_proto_one) | 179 | var buf: [1]Ast.Node.Index = undefined; |
| 182 | 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 | ||
| 183 | else | 182 | else |
| 184 | tree.extraData(datas[fn_proto].lhs, Ast.Node.FnProto).callconv_expr; | 183 | tree.fnProto(fn_proto).ast.callconv_expr; |
| 184 | |||
| 185 | // 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 |
| 186 | if (callconv_expr != 0 and tree.nodes.items(.tag)[callconv_expr] == .enum_literal) { | 186 | if (opt_callconv_expr.unwrap()) |callconv_expr| { |
| 187 | if (mem.eql(u8, "@\"inline\"", tree.tokenSlice(main_tokens[callconv_expr]))) { | 187 | if (tree.nodeTag(callconv_expr) == .enum_literal) { |
| 188 | try ais.writer().writeAll("inline "); | 188 | if (mem.eql(u8, "@\"inline\"", tree.tokenSlice(tree.nodeMainToken(callconv_expr)))) { |
| 189 | try ais.writer().writeAll("inline "); | ||
| 190 | } | ||
| 189 | } | 191 | } |
| 190 | } | 192 | } |
| 191 | }, | 193 | }, |
| 192 | .fn_proto_simple, .fn_proto_multi => {}, | 194 | .fn_proto_simple, .fn_proto_multi => {}, |
| 193 | else => unreachable, | 195 | else => unreachable, |
| 194 | } | 196 | } |
| 195 | assert(datas[decl].rhs != 0); | ||
| 196 | try renderExpression(r, fn_proto, .space); | 197 | try renderExpression(r, fn_proto, .space); |
| 197 | const body_node = datas[decl].rhs; | ||
| 198 | if (r.fixups.gut_functions.contains(decl)) { | 198 | if (r.fixups.gut_functions.contains(decl)) { |
| 199 | try ais.pushIndent(.normal); | 199 | try ais.pushIndent(.normal); |
| 200 | const lbrace = tree.nodes.items(.main_token)[body_node]; | 200 | const lbrace = tree.nodeMainToken(body_node); |
| 201 | try renderToken(r, lbrace, .newline); | 201 | try renderToken(r, lbrace, .newline); |
| 202 | try discardAllParams(r, fn_proto); | 202 | try discardAllParams(r, fn_proto); |
| 203 | try ais.writer().writeAll("@trap();"); | 203 | try ais.writer().writeAll("@trap();"); |
| ... | @@ -206,7 +206,7 @@ fn renderMember( | ... | @@ -206,7 +206,7 @@ fn renderMember( |
| 206 | try renderToken(r, tree.lastToken(body_node), space); // rbrace | 206 | try renderToken(r, tree.lastToken(body_node), space); // rbrace |
| 207 | } else if (r.fixups.unused_var_decls.count() != 0) { | 207 | } else if (r.fixups.unused_var_decls.count() != 0) { |
| 208 | try ais.pushIndent(.normal); | 208 | try ais.pushIndent(.normal); |
| 209 | const lbrace = tree.nodes.items(.main_token)[body_node]; | 209 | const lbrace = tree.nodeMainToken(body_node); |
| 210 | try renderToken(r, lbrace, .newline); | 210 | try renderToken(r, lbrace, .newline); |
| 211 | 211 | ||
| 212 | var fn_proto_buf: [1]Ast.Node.Index = undefined; | 212 | var fn_proto_buf: [1]Ast.Node.Index = undefined; |
| ... | @@ -214,7 +214,7 @@ fn renderMember( | ... | @@ -214,7 +214,7 @@ fn renderMember( |
| 214 | var it = full_fn_proto.iterate(&tree); | 214 | var it = full_fn_proto.iterate(&tree); |
| 215 | while (it.next()) |param| { | 215 | while (it.next()) |param| { |
| 216 | const name_ident = param.name_token.?; | 216 | const name_ident = param.name_token.?; |
| 217 | assert(token_tags[name_ident] == .identifier); | 217 | assert(tree.tokenTag(name_ident) == .identifier); |
| 218 | if (r.fixups.unused_var_decls.contains(name_ident)) { | 218 | if (r.fixups.unused_var_decls.contains(name_ident)) { |
| 219 | const w = ais.writer(); | 219 | const w = ais.writer(); |
| 220 | try w.writeAll("_ = "); | 220 | try w.writeAll("_ = "); |
| ... | @@ -223,25 +223,7 @@ fn renderMember( | ... | @@ -223,25 +223,7 @@ fn renderMember( |
| 223 | } | 223 | } |
| 224 | } | 224 | } |
| 225 | var statements_buf: [2]Ast.Node.Index = undefined; | 225 | var statements_buf: [2]Ast.Node.Index = undefined; |
| 226 | const statements = switch (node_tags[body_node]) { | 226 | const statements = tree.blockStatements(&statements_buf, body_node).?; |
| 227 | .block_two, | ||
| 228 | .block_two_semicolon, | ||
| 229 | => b: { | ||
| 230 | statements_buf = .{ datas[body_node].lhs, datas[body_node].rhs }; | ||
| 231 | if (datas[body_node].lhs == 0) { | ||
| 232 | break :b statements_buf[0..0]; | ||
| 233 | } else if (datas[body_node].rhs == 0) { | ||
| 234 | break :b statements_buf[0..1]; | ||
| 235 | } else { | ||
| 236 | break :b statements_buf[0..2]; | ||
| 237 | } | ||
| 238 | }, | ||
| 239 | .block, | ||
| 240 | .block_semicolon, | ||
| 241 | => tree.extra_data[datas[body_node].lhs..datas[body_node].rhs], | ||
| 242 | |||
| 243 | else => unreachable, | ||
| 244 | }; | ||
| 245 | return finishRenderBlock(r, body_node, statements, space); | 227 | return finishRenderBlock(r, body_node, statements, space); |
| 246 | } else { | 228 | } else { |
| 247 | return renderExpression(r, body_node, space); | 229 | return renderExpression(r, body_node, space); |
| ... | @@ -254,11 +236,11 @@ fn renderMember( | ... | @@ -254,11 +236,11 @@ fn renderMember( |
| 254 | => { | 236 | => { |
| 255 | // Extern function prototypes are parsed as these tags. | 237 | // Extern function prototypes are parsed as these tags. |
| 256 | // Go back to the first token we should render here. | 238 | // Go back to the first token we should render here. |
| 257 | const fn_token = main_tokens[decl]; | 239 | const fn_token = tree.nodeMainToken(decl); |
| 258 | var i = fn_token; | 240 | var i = fn_token; |
| 259 | while (i > 0) { | 241 | while (i > 0) { |
| 260 | i -= 1; | 242 | i -= 1; |
| 261 | switch (token_tags[i]) { | 243 | switch (tree.tokenTag(i)) { |
| 262 | .keyword_extern, | 244 | .keyword_extern, |
| 263 | .keyword_export, | 245 | .keyword_export, |
| 264 | .keyword_pub, | 246 | .keyword_pub, |
| ... | @@ -281,9 +263,9 @@ fn renderMember( | ... | @@ -281,9 +263,9 @@ fn renderMember( |
| 281 | }, | 263 | }, |
| 282 | 264 | ||
| 283 | .@"usingnamespace" => { | 265 | .@"usingnamespace" => { |
| 284 | const main_token = main_tokens[decl]; | 266 | const main_token = tree.nodeMainToken(decl); |
| 285 | const expr = datas[decl].lhs; | 267 | const expr = tree.nodeData(decl).node; |
| 286 | if (main_token > 0 and token_tags[main_token - 1] == .keyword_pub) { | 268 | if (tree.isTokenPrecededByTags(main_token, &.{.keyword_pub})) { |
| 287 | try renderToken(r, main_token - 1, .space); // pub | 269 | try renderToken(r, main_token - 1, .space); // pub |
| 288 | } | 270 | } |
| 289 | try renderToken(r, main_token, .space); // usingnamespace | 271 | try renderToken(r, main_token, .space); // usingnamespace |
| ... | @@ -302,15 +284,17 @@ fn renderMember( | ... | @@ -302,15 +284,17 @@ fn renderMember( |
| 302 | }, | 284 | }, |
| 303 | 285 | ||
| 304 | .test_decl => { | 286 | .test_decl => { |
| 305 | 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; | ||
| 306 | try renderToken(r, test_token, .space); | 289 | try renderToken(r, test_token, .space); |
| 307 | const test_name_tag = token_tags[test_token + 1]; | 290 | if (opt_name_token.unwrap()) |name_token| { |
| 308 | switch (test_name_tag) { | 291 | switch (tree.tokenTag(name_token)) { |
| 309 | .string_literal => try renderToken(r, test_token + 1, .space), | 292 | .string_literal => try renderToken(r, name_token, .space), |
| 310 | .identifier => try renderIdentifier(r, test_token + 1, .space, .preserve_when_shadowing), | 293 | .identifier => try renderIdentifier(r, name_token, .space, .preserve_when_shadowing), |
| 311 | else => {}, | 294 | else => unreachable, |
| 295 | } | ||
| 312 | } | 296 | } |
| 313 | try renderExpression(r, datas[decl].rhs, space); | 297 | try renderExpression(r, block_node, space); |
| 314 | }, | 298 | }, |
| 315 | 299 | ||
| 316 | .container_field_init, | 300 | .container_field_init, |
| ... | @@ -338,10 +322,6 @@ fn renderExpressions(r: *Render, expressions: []const Ast.Node.Index, space: Spa | ... | @@ -338,10 +322,6 @@ fn renderExpressions(r: *Render, expressions: []const Ast.Node.Index, space: Spa |
| 338 | 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 { |
| 339 | const tree = r.tree; | 323 | const tree = r.tree; |
| 340 | const ais = r.ais; | 324 | const ais = r.ais; |
| 341 | const token_tags = tree.tokens.items(.tag); | ||
| 342 | const main_tokens = tree.nodes.items(.main_token); | ||
| 343 | const node_tags = tree.nodes.items(.tag); | ||
| 344 | const datas = tree.nodes.items(.data); | ||
| 345 | if (r.fixups.replace_nodes_with_string.get(node)) |replacement| { | 325 | if (r.fixups.replace_nodes_with_string.get(node)) |replacement| { |
| 346 | try ais.writer().writeAll(replacement); | 326 | try ais.writer().writeAll(replacement); |
| 347 | try renderOnlySpace(r, space); | 327 | try renderOnlySpace(r, space); |
| ... | @@ -349,9 +329,9 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -349,9 +329,9 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 349 | } else if (r.fixups.replace_nodes_with_node.get(node)) |replacement| { | 329 | } else if (r.fixups.replace_nodes_with_node.get(node)) |replacement| { |
| 350 | return renderExpression(r, replacement, space); | 330 | return renderExpression(r, replacement, space); |
| 351 | } | 331 | } |
| 352 | switch (node_tags[node]) { | 332 | switch (tree.nodeTag(node)) { |
| 353 | .identifier => { | 333 | .identifier => { |
| 354 | const token_index = main_tokens[node]; | 334 | const token_index = tree.nodeMainToken(node); |
| 355 | return renderIdentifier(r, token_index, space, .preserve_when_shadowing); | 335 | return renderIdentifier(r, token_index, space, .preserve_when_shadowing); |
| 356 | }, | 336 | }, |
| 357 | 337 | ||
| ... | @@ -360,18 +340,23 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -360,18 +340,23 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 360 | .unreachable_literal, | 340 | .unreachable_literal, |
| 361 | .anyframe_literal, | 341 | .anyframe_literal, |
| 362 | .string_literal, | 342 | .string_literal, |
| 363 | => return renderToken(r, main_tokens[node], space), | 343 | => return renderToken(r, tree.nodeMainToken(node), space), |
| 364 | 344 | ||
| 365 | .multiline_string_literal => { | 345 | .multiline_string_literal => { |
| 366 | try ais.maybeInsertNewline(); | 346 | try ais.maybeInsertNewline(); |
| 367 | 347 | ||
| 368 | var i = datas[node].lhs; | 348 | const first_tok, const last_tok = tree.nodeData(node).token_and_token; |
| 369 | 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); | ||
| 370 | 355 | ||
| 371 | // dedent the next thing that comes after a multiline string literal | 356 | // dedent the next thing that comes after a multiline string literal |
| 372 | if (!ais.indentStackEmpty() and | 357 | if (!ais.indentStackEmpty() and |
| 373 | token_tags[i] != .colon and | 358 | next_token_tag != .colon and |
| 374 | ((token_tags[i] != .semicolon and token_tags[i] != .comma) or | 359 | ((next_token_tag != .semicolon and next_token_tag != .comma) or |
| 375 | ais.lastSpaceModeIndent() < ais.currentIndent())) | 360 | ais.lastSpaceModeIndent() < ais.currentIndent())) |
| 376 | { | 361 | { |
| 377 | ais.popIndent(); | 362 | ais.popIndent(); |
| ... | @@ -380,44 +365,35 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -380,44 +365,35 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 380 | 365 | ||
| 381 | switch (space) { | 366 | switch (space) { |
| 382 | .none, .space, .newline, .skip => {}, | 367 | .none, .space, .newline, .skip => {}, |
| 383 | .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), |
| 384 | .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), |
| 385 | .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), |
| 386 | } | 371 | } |
| 387 | }, | 372 | }, |
| 388 | 373 | ||
| 389 | .error_value => { | 374 | .error_value => { |
| 390 | try renderToken(r, main_tokens[node], .none); | 375 | const main_token = tree.nodeMainToken(node); |
| 391 | try renderToken(r, main_tokens[node] + 1, .none); | 376 | try renderToken(r, main_token, .none); |
| 392 | 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); | ||
| 393 | }, | 379 | }, |
| 394 | 380 | ||
| 395 | .block_two, | 381 | .block_two, |
| 396 | .block_two_semicolon, | 382 | .block_two_semicolon, |
| 397 | => { | ||
| 398 | const statements = [2]Ast.Node.Index{ datas[node].lhs, datas[node].rhs }; | ||
| 399 | if (datas[node].lhs == 0) { | ||
| 400 | return renderBlock(r, node, statements[0..0], space); | ||
| 401 | } else if (datas[node].rhs == 0) { | ||
| 402 | return renderBlock(r, node, statements[0..1], space); | ||
| 403 | } else { | ||
| 404 | return renderBlock(r, node, statements[0..2], space); | ||
| 405 | } | ||
| 406 | }, | ||
| 407 | .block, | 383 | .block, |
| 408 | .block_semicolon, | 384 | .block_semicolon, |
| 409 | => { | 385 | => { |
| 410 | const statements = tree.extra_data[datas[node].lhs..datas[node].rhs]; | 386 | var buf: [2]Ast.Node.Index = undefined; |
| 387 | const statements = tree.blockStatements(&buf, node).?; | ||
| 411 | return renderBlock(r, node, statements, space); | 388 | return renderBlock(r, node, statements, space); |
| 412 | }, | 389 | }, |
| 413 | 390 | ||
| 414 | .@"errdefer" => { | 391 | .@"errdefer" => { |
| 415 | const defer_token = main_tokens[node]; | 392 | const defer_token = tree.nodeMainToken(node); |
| 416 | const payload_token = datas[node].lhs; | 393 | const maybe_payload_token, const expr = tree.nodeData(node).opt_token_and_node; |
| 417 | const expr = datas[node].rhs; | ||
| 418 | 394 | ||
| 419 | try renderToken(r, defer_token, .space); | 395 | try renderToken(r, defer_token, .space); |
| 420 | if (payload_token != 0) { | 396 | if (maybe_payload_token.unwrap()) |payload_token| { |
| 421 | try renderToken(r, payload_token - 1, .none); // | | 397 | try renderToken(r, payload_token - 1, .none); // | |
| 422 | try renderIdentifier(r, payload_token, .none, .preserve_when_shadowing); // identifier | 398 | try renderIdentifier(r, payload_token, .none, .preserve_when_shadowing); // identifier |
| 423 | try renderToken(r, payload_token + 1, .space); // | | 399 | try renderToken(r, payload_token + 1, .space); // | |
| ... | @@ -425,84 +401,76 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -425,84 +401,76 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 425 | return renderExpression(r, expr, space); | 401 | return renderExpression(r, expr, space); |
| 426 | }, | 402 | }, |
| 427 | 403 | ||
| 428 | .@"defer" => { | 404 | .@"defer", |
| 429 | const defer_token = main_tokens[node]; | 405 | .@"comptime", |
| 430 | const expr = datas[node].rhs; | 406 | .@"nosuspend", |
| 431 | try renderToken(r, defer_token, .space); | 407 | .@"suspend", |
| 432 | return renderExpression(r, expr, space); | 408 | => { |
| 433 | }, | 409 | const main_token = tree.nodeMainToken(node); |
| 434 | .@"comptime", .@"nosuspend" => { | 410 | const item = tree.nodeData(node).node; |
| 435 | const comptime_token = main_tokens[node]; | 411 | try renderToken(r, main_token, .space); |
| 436 | const block = datas[node].lhs; | 412 | return renderExpression(r, item, space); |
| 437 | try renderToken(r, comptime_token, .space); | ||
| 438 | return renderExpression(r, block, space); | ||
| 439 | }, | ||
| 440 | |||
| 441 | .@"suspend" => { | ||
| 442 | const suspend_token = main_tokens[node]; | ||
| 443 | const body = datas[node].lhs; | ||
| 444 | try renderToken(r, suspend_token, .space); | ||
| 445 | return renderExpression(r, body, space); | ||
| 446 | }, | 413 | }, |
| 447 | 414 | ||
| 448 | .@"catch" => { | 415 | .@"catch" => { |
| 449 | const main_token = main_tokens[node]; | 416 | const main_token = tree.nodeMainToken(node); |
| 450 | 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); | ||
| 451 | 419 | ||
| 452 | const same_line = tree.tokensOnSameLine(main_token, fallback_first); | 420 | const same_line = tree.tokensOnSameLine(main_token, fallback_first); |
| 453 | 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; |
| 454 | 422 | ||
| 455 | try renderExpression(r, datas[node].lhs, .space); // target | 423 | try renderExpression(r, lhs, .space); // target |
| 456 | 424 | ||
| 457 | try ais.pushIndent(.normal); | 425 | try ais.pushIndent(.normal); |
| 458 | if (token_tags[fallback_first - 1] == .pipe) { | 426 | if (tree.tokenTag(fallback_first - 1) == .pipe) { |
| 459 | try renderToken(r, main_token, .space); // catch keyword | 427 | try renderToken(r, main_token, .space); // catch keyword |
| 460 | try renderToken(r, main_token + 1, .none); // pipe | 428 | try renderToken(r, main_token + 1, .none); // pipe |
| 461 | 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 |
| 462 | try renderToken(r, main_token + 3, after_op_space); // pipe | 430 | try renderToken(r, main_token + 3, after_op_space); // pipe |
| 463 | } else { | 431 | } else { |
| 464 | assert(token_tags[fallback_first - 1] == .keyword_catch); | 432 | assert(tree.tokenTag(fallback_first - 1) == .keyword_catch); |
| 465 | try renderToken(r, main_token, after_op_space); // catch keyword | 433 | try renderToken(r, main_token, after_op_space); // catch keyword |
| 466 | } | 434 | } |
| 467 | try renderExpression(r, datas[node].rhs, space); // fallback | 435 | try renderExpression(r, rhs, space); // fallback |
| 468 | ais.popIndent(); | 436 | ais.popIndent(); |
| 469 | }, | 437 | }, |
| 470 | 438 | ||
| 471 | .field_access => { | 439 | .field_access => { |
| 472 | const main_token = main_tokens[node]; | 440 | const lhs, const name_token = tree.nodeData(node).node_and_token; |
| 473 | const field_access = datas[node]; | 441 | const dot_token = name_token - 1; |
| 474 | 442 | ||
| 475 | try ais.pushIndent(.field_access); | 443 | try ais.pushIndent(.field_access); |
| 476 | try renderExpression(r, field_access.lhs, .none); | 444 | try renderExpression(r, lhs, .none); |
| 477 | 445 | ||
| 478 | // 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 |
| 479 | // are on different lines. | 447 | // are on different lines. |
| 480 | const lhs_last_token = tree.lastToken(field_access.lhs); | 448 | const lhs_last_token = tree.lastToken(lhs); |
| 481 | const same_line = tree.tokensOnSameLine(lhs_last_token, main_token + 1); | 449 | const same_line = tree.tokensOnSameLine(lhs_last_token, name_token); |
| 482 | 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(); |
| 483 | 451 | ||
| 484 | try renderToken(r, main_token, .none); // . | 452 | try renderToken(r, dot_token, .none); |
| 485 | 453 | ||
| 486 | try renderIdentifier(r, field_access.rhs, space, .eagerly_unquote); // field | 454 | try renderIdentifier(r, name_token, space, .eagerly_unquote); // field |
| 487 | ais.popIndent(); | 455 | ais.popIndent(); |
| 488 | }, | 456 | }, |
| 489 | 457 | ||
| 490 | .error_union, | 458 | .error_union, |
| 491 | .switch_range, | 459 | .switch_range, |
| 492 | => { | 460 | => { |
| 493 | const infix = datas[node]; | 461 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 494 | try renderExpression(r, infix.lhs, .none); | 462 | try renderExpression(r, lhs, .none); |
| 495 | try renderToken(r, main_tokens[node], .none); | 463 | try renderToken(r, tree.nodeMainToken(node), .none); |
| 496 | return renderExpression(r, infix.rhs, space); | 464 | return renderExpression(r, rhs, space); |
| 497 | }, | 465 | }, |
| 498 | .for_range => { | 466 | .for_range => { |
| 499 | const infix = datas[node]; | 467 | const start, const opt_end = tree.nodeData(node).node_and_opt_node; |
| 500 | try renderExpression(r, infix.lhs, .none); | 468 | try renderExpression(r, start, .none); |
| 501 | if (infix.rhs != 0) { | 469 | if (opt_end.unwrap()) |end| { |
| 502 | try renderToken(r, main_tokens[node], .none); | 470 | try renderToken(r, tree.nodeMainToken(node), .none); |
| 503 | return renderExpression(r, infix.rhs, space); | 471 | return renderExpression(r, end, space); |
| 504 | } else { | 472 | } else { |
| 505 | return renderToken(r, main_tokens[node], space); | 473 | return renderToken(r, tree.nodeMainToken(node), space); |
| 506 | } | 474 | } |
| 507 | }, | 475 | }, |
| 508 | 476 | ||
| ... | @@ -525,16 +493,16 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -525,16 +493,16 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 525 | .assign_mul_wrap, | 493 | .assign_mul_wrap, |
| 526 | .assign_mul_sat, | 494 | .assign_mul_sat, |
| 527 | => { | 495 | => { |
| 528 | const infix = datas[node]; | 496 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 529 | try renderExpression(r, infix.lhs, .space); | 497 | try renderExpression(r, lhs, .space); |
| 530 | const op_token = main_tokens[node]; | 498 | const op_token = tree.nodeMainToken(node); |
| 531 | try ais.pushIndent(.after_equals); | 499 | try ais.pushIndent(.after_equals); |
| 532 | if (tree.tokensOnSameLine(op_token, op_token + 1)) { | 500 | if (tree.tokensOnSameLine(op_token, op_token + 1)) { |
| 533 | try renderToken(r, op_token, .space); | 501 | try renderToken(r, op_token, .space); |
| 534 | } else { | 502 | } else { |
| 535 | try renderToken(r, op_token, .newline); | 503 | try renderToken(r, op_token, .newline); |
| 536 | } | 504 | } |
| 537 | try renderExpression(r, infix.rhs, space); | 505 | try renderExpression(r, rhs, space); |
| 538 | ais.popIndent(); | 506 | ais.popIndent(); |
| 539 | }, | 507 | }, |
| 540 | 508 | ||
| ... | @@ -568,16 +536,16 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -568,16 +536,16 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 568 | .sub_sat, | 536 | .sub_sat, |
| 569 | .@"orelse", | 537 | .@"orelse", |
| 570 | => { | 538 | => { |
| 571 | const infix = datas[node]; | 539 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 572 | try renderExpression(r, infix.lhs, .space); | 540 | try renderExpression(r, lhs, .space); |
| 573 | const op_token = main_tokens[node]; | 541 | const op_token = tree.nodeMainToken(node); |
| 574 | try ais.pushIndent(.binop); | 542 | try ais.pushIndent(.binop); |
| 575 | if (tree.tokensOnSameLine(op_token, op_token + 1)) { | 543 | if (tree.tokensOnSameLine(op_token, op_token + 1)) { |
| 576 | try renderToken(r, op_token, .space); | 544 | try renderToken(r, op_token, .space); |
| 577 | } else { | 545 | } else { |
| 578 | try renderToken(r, op_token, .newline); | 546 | try renderToken(r, op_token, .newline); |
| 579 | } | 547 | } |
| 580 | try renderExpression(r, infix.rhs, space); | 548 | try renderExpression(r, rhs, space); |
| 581 | ais.popIndent(); | 549 | ais.popIndent(); |
| 582 | }, | 550 | }, |
| 583 | 551 | ||
| ... | @@ -589,7 +557,7 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -589,7 +557,7 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 589 | 557 | ||
| 590 | for (full.ast.variables, 0..) |variable_node, i| { | 558 | for (full.ast.variables, 0..) |variable_node, i| { |
| 591 | 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; |
| 592 | switch (node_tags[variable_node]) { | 560 | switch (tree.nodeTag(variable_node)) { |
| 593 | .global_var_decl, | 561 | .global_var_decl, |
| 594 | .local_var_decl, | 562 | .local_var_decl, |
| 595 | .simple_var_decl, | 563 | .simple_var_decl, |
| ... | @@ -617,16 +585,16 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -617,16 +585,16 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 617 | .optional_type, | 585 | .optional_type, |
| 618 | .address_of, | 586 | .address_of, |
| 619 | => { | 587 | => { |
| 620 | try renderToken(r, main_tokens[node], .none); | 588 | try renderToken(r, tree.nodeMainToken(node), .none); |
| 621 | return renderExpression(r, datas[node].lhs, space); | 589 | return renderExpression(r, tree.nodeData(node).node, space); |
| 622 | }, | 590 | }, |
| 623 | 591 | ||
| 624 | .@"try", | 592 | .@"try", |
| 625 | .@"resume", | 593 | .@"resume", |
| 626 | .@"await", | 594 | .@"await", |
| 627 | => { | 595 | => { |
| 628 | try renderToken(r, main_tokens[node], .space); | 596 | try renderToken(r, tree.nodeMainToken(node), .space); |
| 629 | return renderExpression(r, datas[node].lhs, space); | 597 | return renderExpression(r, tree.nodeData(node).node, space); |
| 630 | }, | 598 | }, |
| 631 | 599 | ||
| 632 | .array_type, | 600 | .array_type, |
| ... | @@ -679,68 +647,77 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -679,68 +647,77 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 679 | }, | 647 | }, |
| 680 | 648 | ||
| 681 | .array_access => { | 649 | .array_access => { |
| 682 | const suffix = datas[node]; | 650 | const lhs, const rhs = tree.nodeData(node).node_and_node; |
| 683 | const lbracket = tree.firstToken(suffix.rhs) - 1; | 651 | const lbracket = tree.firstToken(rhs) - 1; |
| 684 | const rbracket = tree.lastToken(suffix.rhs) + 1; | 652 | const rbracket = tree.lastToken(rhs) + 1; |
| 685 | const one_line = tree.tokensOnSameLine(lbracket, rbracket); | 653 | const one_line = tree.tokensOnSameLine(lbracket, rbracket); |
| 686 | const inner_space = if (one_line) Space.none else Space.newline; | 654 | const inner_space = if (one_line) Space.none else Space.newline; |
| 687 | try renderExpression(r, suffix.lhs, .none); | 655 | try renderExpression(r, lhs, .none); |
| 688 | try ais.pushIndent(.normal); | 656 | try ais.pushIndent(.normal); |
| 689 | try renderToken(r, lbracket, inner_space); // [ | 657 | try renderToken(r, lbracket, inner_space); // [ |
| 690 | try renderExpression(r, suffix.rhs, inner_space); | 658 | try renderExpression(r, rhs, inner_space); |
| 691 | ais.popIndent(); | 659 | ais.popIndent(); |
| 692 | return renderToken(r, rbracket, space); // ] | 660 | return renderToken(r, rbracket, space); // ] |
| 693 | }, | 661 | }, |
| 694 | 662 | ||
| 695 | .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), | ||
| 696 | 667 | ||
| 697 | .deref => { | 668 | .deref => { |
| 698 | try renderExpression(r, datas[node].lhs, .none); | 669 | try renderExpression(r, tree.nodeData(node).node, .none); |
| 699 | return renderToken(r, main_tokens[node], space); | 670 | return renderToken(r, tree.nodeMainToken(node), space); |
| 700 | }, | 671 | }, |
| 701 | 672 | ||
| 702 | .unwrap_optional => { | 673 | .unwrap_optional => { |
| 703 | try renderExpression(r, datas[node].lhs, .none); | 674 | const lhs, const question_mark = tree.nodeData(node).node_and_token; |
| 704 | try renderToken(r, main_tokens[node], .none); | 675 | const dot_token = question_mark - 1; |
| 705 | 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); | ||
| 706 | }, | 679 | }, |
| 707 | 680 | ||
| 708 | .@"break", .@"continue" => { | 681 | .@"break", .@"continue" => { |
| 709 | const main_token = main_tokens[node]; | 682 | const main_token = tree.nodeMainToken(node); |
| 710 | const label_token = datas[node].lhs; | 683 | const opt_label_token, const opt_target = tree.nodeData(node).opt_token_and_opt_node; |
| 711 | const target = datas[node].rhs; | 684 | if (opt_label_token == .none and opt_target == .none) { |
| 712 | if (label_token == 0 and target == 0) { | ||
| 713 | try renderToken(r, main_token, space); // break/continue | 685 | try renderToken(r, main_token, space); // break/continue |
| 714 | } 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().?; | ||
| 715 | try renderToken(r, main_token, .space); // break/continue | 688 | try renderToken(r, main_token, .space); // break/continue |
| 716 | try renderExpression(r, target, space); | 689 | try renderExpression(r, target, space); |
| 717 | } 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().?; | ||
| 718 | try renderToken(r, main_token, .space); // break/continue | 692 | try renderToken(r, main_token, .space); // break/continue |
| 719 | try renderToken(r, label_token - 1, .none); // : | 693 | try renderToken(r, label_token - 1, .none); // : |
| 720 | try renderIdentifier(r, label_token, space, .eagerly_unquote); // identifier | 694 | try renderIdentifier(r, label_token, space, .eagerly_unquote); // identifier |
| 721 | } 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().?; | ||
| 722 | try renderToken(r, main_token, .space); // break/continue | 698 | try renderToken(r, main_token, .space); // break/continue |
| 723 | try renderToken(r, label_token - 1, .none); // : | 699 | try renderToken(r, label_token - 1, .none); // : |
| 724 | try renderIdentifier(r, label_token, .space, .eagerly_unquote); // identifier | 700 | try renderIdentifier(r, label_token, .space, .eagerly_unquote); // identifier |
| 725 | try renderExpression(r, target, space); | 701 | try renderExpression(r, target, space); |
| 726 | } | 702 | } else unreachable; |
| 727 | }, | 703 | }, |
| 728 | 704 | ||
| 729 | .@"return" => { | 705 | .@"return" => { |
| 730 | if (datas[node].lhs != 0) { | 706 | if (tree.nodeData(node).opt_node.unwrap()) |expr| { |
| 731 | try renderToken(r, main_tokens[node], .space); | 707 | try renderToken(r, tree.nodeMainToken(node), .space); |
| 732 | try renderExpression(r, datas[node].lhs, space); | 708 | try renderExpression(r, expr, space); |
| 733 | } else { | 709 | } else { |
| 734 | try renderToken(r, main_tokens[node], space); | 710 | try renderToken(r, tree.nodeMainToken(node), space); |
| 735 | } | 711 | } |
| 736 | }, | 712 | }, |
| 737 | 713 | ||
| 738 | .grouped_expression => { | 714 | .grouped_expression => { |
| 715 | const expr, const rparen = tree.nodeData(node).node_and_token; | ||
| 739 | try ais.pushIndent(.normal); | 716 | try ais.pushIndent(.normal); |
| 740 | try renderToken(r, main_tokens[node], .none); // lparen | 717 | try renderToken(r, tree.nodeMainToken(node), .none); // lparen |
| 741 | try renderExpression(r, datas[node].lhs, .none); | 718 | try renderExpression(r, expr, .none); |
| 742 | ais.popIndent(); | 719 | ais.popIndent(); |
| 743 | return renderToken(r, datas[node].rhs, space); // rparen | 720 | return renderToken(r, rparen, space); |
| 744 | }, | 721 | }, |
| 745 | 722 | ||
| 746 | .container_decl, | 723 | .container_decl, |
| ... | @@ -761,9 +738,8 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -761,9 +738,8 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 761 | }, | 738 | }, |
| 762 | 739 | ||
| 763 | .error_set_decl => { | 740 | .error_set_decl => { |
| 764 | const error_token = main_tokens[node]; | 741 | const error_token = tree.nodeMainToken(node); |
| 765 | const lbrace = error_token + 1; | 742 | const lbrace, const rbrace = tree.nodeData(node).token_and_token; |
| 766 | const rbrace = datas[node].rhs; | ||
| 767 | 743 | ||
| 768 | try renderToken(r, error_token, .none); | 744 | try renderToken(r, error_token, .none); |
| 769 | 745 | ||
| ... | @@ -771,20 +747,20 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -771,20 +747,20 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 771 | // There is nothing between the braces so render condensed: `error{}` | 747 | // There is nothing between the braces so render condensed: `error{}` |
| 772 | try renderToken(r, lbrace, .none); | 748 | try renderToken(r, lbrace, .none); |
| 773 | return renderToken(r, rbrace, space); | 749 | return renderToken(r, rbrace, space); |
| 774 | } else if (lbrace + 2 == rbrace and token_tags[lbrace + 1] == .identifier) { | 750 | } else if (lbrace + 2 == rbrace and tree.tokenTag(lbrace + 1) == .identifier) { |
| 775 | // There is exactly one member and no trailing comma or | 751 | // There is exactly one member and no trailing comma or |
| 776 | // comments, so render without surrounding spaces: `error{Foo}` | 752 | // comments, so render without surrounding spaces: `error{Foo}` |
| 777 | try renderToken(r, lbrace, .none); | 753 | try renderToken(r, lbrace, .none); |
| 778 | try renderIdentifier(r, lbrace + 1, .none, .eagerly_unquote); // identifier | 754 | try renderIdentifier(r, lbrace + 1, .none, .eagerly_unquote); // identifier |
| 779 | return renderToken(r, rbrace, space); | 755 | return renderToken(r, rbrace, space); |
| 780 | } else if (token_tags[rbrace - 1] == .comma) { | 756 | } else if (tree.tokenTag(rbrace - 1) == .comma) { |
| 781 | // There is a trailing comma so render each member on a new line. | 757 | // There is a trailing comma so render each member on a new line. |
| 782 | try ais.pushIndent(.normal); | 758 | try ais.pushIndent(.normal); |
| 783 | try renderToken(r, lbrace, .newline); | 759 | try renderToken(r, lbrace, .newline); |
| 784 | var i = lbrace + 1; | 760 | var i = lbrace + 1; |
| 785 | while (i < rbrace) : (i += 1) { | 761 | while (i < rbrace) : (i += 1) { |
| 786 | if (i > lbrace + 1) try renderExtraNewlineToken(r, i); | 762 | if (i > lbrace + 1) try renderExtraNewlineToken(r, i); |
| 787 | switch (token_tags[i]) { | 763 | switch (tree.tokenTag(i)) { |
| 788 | .doc_comment => try renderToken(r, i, .newline), | 764 | .doc_comment => try renderToken(r, i, .newline), |
| 789 | .identifier => { | 765 | .identifier => { |
| 790 | try ais.pushSpace(.comma); | 766 | try ais.pushSpace(.comma); |
| ... | @@ -802,7 +778,7 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -802,7 +778,7 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 802 | try renderToken(r, lbrace, .space); | 778 | try renderToken(r, lbrace, .space); |
| 803 | var i = lbrace + 1; | 779 | var i = lbrace + 1; |
| 804 | while (i < rbrace) : (i += 1) { | 780 | while (i < rbrace) : (i += 1) { |
| 805 | switch (token_tags[i]) { | 781 | switch (tree.tokenTag(i)) { |
| 806 | .doc_comment => unreachable, // TODO | 782 | .doc_comment => unreachable, // TODO |
| 807 | .identifier => try renderIdentifier(r, i, .comma_space, .eagerly_unquote), | 783 | .identifier => try renderIdentifier(r, i, .comma_space, .eagerly_unquote), |
| 808 | .comma => {}, | 784 | .comma => {}, |
| ... | @@ -813,18 +789,14 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -813,18 +789,14 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 813 | } | 789 | } |
| 814 | }, | 790 | }, |
| 815 | 791 | ||
| 816 | .builtin_call_two, .builtin_call_two_comma => { | 792 | .builtin_call_two, |
| 817 | if (datas[node].lhs == 0) { | 793 | .builtin_call_two_comma, |
| 818 | return renderBuiltinCall(r, main_tokens[node], &.{}, space); | 794 | .builtin_call, |
| 819 | } else if (datas[node].rhs == 0) { | 795 | .builtin_call_comma, |
| 820 | return renderBuiltinCall(r, main_tokens[node], &.{datas[node].lhs}, space); | 796 | => { |
| 821 | } else { | 797 | var buf: [2]Ast.Node.Index = undefined; |
| 822 | return renderBuiltinCall(r, main_tokens[node], &.{ datas[node].lhs, datas[node].rhs }, space); | 798 | const params = tree.builtinCallParams(&buf, node).?; |
| 823 | } | 799 | return renderBuiltinCall(r, tree.nodeMainToken(node), params, space); |
| 824 | }, | ||
| 825 | .builtin_call, .builtin_call_comma => { | ||
| 826 | const params = tree.extra_data[datas[node].lhs..datas[node].rhs]; | ||
| 827 | return renderBuiltinCall(r, main_tokens[node], params, space); | ||
| 828 | }, | 800 | }, |
| 829 | 801 | ||
| 830 | .fn_proto_simple, | 802 | .fn_proto_simple, |
| ... | @@ -837,14 +809,10 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -837,14 +809,10 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 837 | }, | 809 | }, |
| 838 | 810 | ||
| 839 | .anyframe_type => { | 811 | .anyframe_type => { |
| 840 | const main_token = main_tokens[node]; | 812 | const main_token = tree.nodeMainToken(node); |
| 841 | if (datas[node].rhs != 0) { | 813 | try renderToken(r, main_token, .none); // anyframe |
| 842 | try renderToken(r, main_token, .none); // anyframe | 814 | try renderToken(r, main_token + 1, .none); // -> |
| 843 | try renderToken(r, main_token + 1, .none); // -> | 815 | return renderExpression(r, tree.nodeData(node).token_and_node[1], space); |
| 844 | return renderExpression(r, datas[node].rhs, space); | ||
| 845 | } else { | ||
| 846 | return renderToken(r, main_token, space); // anyframe | ||
| 847 | } | ||
| 848 | }, | 816 | }, |
| 849 | 817 | ||
| 850 | .@"switch", | 818 | .@"switch", |
| ... | @@ -901,8 +869,8 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | ... | @@ -901,8 +869,8 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 901 | => return renderAsm(r, tree.fullAsm(node).?, space), | 869 | => return renderAsm(r, tree.fullAsm(node).?, space), |
| 902 | 870 | ||
| 903 | .enum_literal => { | 871 | .enum_literal => { |
| 904 | try renderToken(r, main_tokens[node] - 1, .none); // . | 872 | try renderToken(r, tree.nodeMainToken(node) - 1, .none); // . |
| 905 | return renderIdentifier(r, main_tokens[node], space, .eagerly_unquote); // name | 873 | return renderIdentifier(r, tree.nodeMainToken(node), space, .eagerly_unquote); // name |
| 906 | }, | 874 | }, |
| 907 | 875 | ||
| 908 | .fn_decl => unreachable, | 876 | .fn_decl => unreachable, |
| ... | @@ -944,9 +912,9 @@ fn renderArrayType( | ... | @@ -944,9 +912,9 @@ fn renderArrayType( |
| 944 | try ais.pushIndent(.normal); | 912 | try ais.pushIndent(.normal); |
| 945 | try renderToken(r, array_type.ast.lbracket, inner_space); // lbracket | 913 | try renderToken(r, array_type.ast.lbracket, inner_space); // lbracket |
| 946 | try renderExpression(r, array_type.ast.elem_count, inner_space); | 914 | try renderExpression(r, array_type.ast.elem_count, inner_space); |
| 947 | if (array_type.ast.sentinel != 0) { | 915 | if (array_type.ast.sentinel.unwrap()) |sentinel| { |
| 948 | try renderToken(r, tree.firstToken(array_type.ast.sentinel) - 1, inner_space); // colon | 916 | try renderToken(r, tree.firstToken(sentinel) - 1, inner_space); // colon |
| 949 | try renderExpression(r, array_type.ast.sentinel, inner_space); | 917 | try renderExpression(r, sentinel, inner_space); |
| 950 | } | 918 | } |
| 951 | ais.popIndent(); | 919 | ais.popIndent(); |
| 952 | try renderToken(r, rbracket, .none); // rbracket | 920 | try renderToken(r, rbracket, .none); // rbracket |
| ... | @@ -955,6 +923,7 @@ fn renderArrayType( | ... | @@ -955,6 +923,7 @@ fn renderArrayType( |
| 955 | 923 | ||
| 956 | fn renderPtrType(r: *Render, ptr_type: Ast.full.PtrType, space: Space) Error!void { | 924 | fn renderPtrType(r: *Render, ptr_type: Ast.full.PtrType, space: Space) Error!void { |
| 957 | const tree = r.tree; | 925 | const tree = r.tree; |
| 926 | const main_token = ptr_type.ast.main_token; | ||
| 958 | switch (ptr_type.size) { | 927 | switch (ptr_type.size) { |
| 959 | .one => { | 928 | .one => { |
| 960 | // Since ** tokens exist and the same token is shared by two | 929 | // Since ** tokens exist and the same token is shared by two |
| ... | @@ -962,41 +931,41 @@ fn renderPtrType(r: *Render, ptr_type: Ast.full.PtrType, space: Space) Error!voi | ... | @@ -962,41 +931,41 @@ fn renderPtrType(r: *Render, ptr_type: Ast.full.PtrType, space: Space) Error!voi |
| 962 | // in such a relationship. If so, skip rendering anything for | 931 | // in such a relationship. If so, skip rendering anything for |
| 963 | // this pointer type and rely on the child to render our asterisk | 932 | // this pointer type and rely on the child to render our asterisk |
| 964 | // as well when it renders the ** token. | 933 | // as well when it renders the ** token. |
| 965 | if (tree.tokens.items(.tag)[ptr_type.ast.main_token] == .asterisk_asterisk and | 934 | if (tree.tokenTag(main_token) == .asterisk_asterisk and |
| 966 | ptr_type.ast.main_token == tree.nodes.items(.main_token)[ptr_type.ast.child_type]) | 935 | main_token == tree.nodeMainToken(ptr_type.ast.child_type)) |
| 967 | { | 936 | { |
| 968 | return renderExpression(r, ptr_type.ast.child_type, space); | 937 | return renderExpression(r, ptr_type.ast.child_type, space); |
| 969 | } | 938 | } |
| 970 | try renderToken(r, ptr_type.ast.main_token, .none); // asterisk | 939 | try renderToken(r, main_token, .none); // asterisk |
| 971 | }, | 940 | }, |
| 972 | .many => { | 941 | .many => { |
| 973 | if (ptr_type.ast.sentinel == 0) { | 942 | if (ptr_type.ast.sentinel.unwrap()) |sentinel| { |
| 974 | try renderToken(r, ptr_type.ast.main_token, .none); // lbracket | 943 | try renderToken(r, main_token, .none); // lbracket |
| 975 | try renderToken(r, ptr_type.ast.main_token + 1, .none); // asterisk | 944 | try renderToken(r, main_token + 1, .none); // asterisk |
| 976 | try renderToken(r, ptr_type.ast.main_token + 2, .none); // rbracket | 945 | try renderToken(r, main_token + 2, .none); // colon |
| 946 | try renderExpression(r, sentinel, .none); | ||
| 947 | try renderToken(r, tree.lastToken(sentinel) + 1, .none); // rbracket | ||
| 977 | } else { | 948 | } else { |
| 978 | try renderToken(r, ptr_type.ast.main_token, .none); // lbracket | 949 | try renderToken(r, main_token, .none); // lbracket |
| 979 | try renderToken(r, ptr_type.ast.main_token + 1, .none); // asterisk | 950 | try renderToken(r, main_token + 1, .none); // asterisk |
| 980 | try renderToken(r, ptr_type.ast.main_token + 2, .none); // colon | 951 | try renderToken(r, main_token + 2, .none); // rbracket |
| 981 | try renderExpression(r, ptr_type.ast.sentinel, .none); | ||
| 982 | try renderToken(r, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket | ||
| 983 | } | 952 | } |
| 984 | }, | 953 | }, |
| 985 | .c => { | 954 | .c => { |
| 986 | try renderToken(r, ptr_type.ast.main_token, .none); // lbracket | 955 | try renderToken(r, main_token, .none); // lbracket |
| 987 | try renderToken(r, ptr_type.ast.main_token + 1, .none); // asterisk | 956 | try renderToken(r, main_token + 1, .none); // asterisk |
| 988 | try renderToken(r, ptr_type.ast.main_token + 2, .none); // c | 957 | try renderToken(r, main_token + 2, .none); // c |
| 989 | try renderToken(r, ptr_type.ast.main_token + 3, .none); // rbracket | 958 | try renderToken(r, main_token + 3, .none); // rbracket |
| 990 | }, | 959 | }, |
| 991 | .slice => { | 960 | .slice => { |
| 992 | if (ptr_type.ast.sentinel == 0) { | 961 | if (ptr_type.ast.sentinel.unwrap()) |sentinel| { |
| 993 | try renderToken(r, ptr_type.ast.main_token, .none); // lbracket | 962 | try renderToken(r, main_token, .none); // lbracket |
| 994 | try renderToken(r, ptr_type.ast.main_token + 1, .none); // rbracket | 963 | try renderToken(r, main_token + 1, .none); // colon |
| 964 | try renderExpression(r, sentinel, .none); | ||
| 965 | try renderToken(r, tree.lastToken(sentinel) + 1, .none); // rbracket | ||
| 995 | } else { | 966 | } else { |
| 996 | try renderToken(r, ptr_type.ast.main_token, .none); // lbracket | 967 | try renderToken(r, main_token, .none); // lbracket |
| 997 | try renderToken(r, ptr_type.ast.main_token + 1, .none); // colon | 968 | try renderToken(r, main_token + 1, .none); // rbracket |
| 998 | try renderExpression(r, ptr_type.ast.sentinel, .none); | ||
| 999 | try renderToken(r, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket | ||
| 1000 | } | 969 | } |
| 1001 | }, | 970 | }, |
| 1002 | } | 971 | } |
| ... | @@ -1005,29 +974,29 @@ fn renderPtrType(r: *Render, ptr_type: Ast.full.PtrType, space: Space) Error!voi | ... | @@ -1005,29 +974,29 @@ fn renderPtrType(r: *Render, ptr_type: Ast.full.PtrType, space: Space) Error!voi |
| 1005 | try renderToken(r, allowzero_token, .space); | 974 | try renderToken(r, allowzero_token, .space); |
| 1006 | } | 975 | } |
| 1007 | 976 | ||
| 1008 | if (ptr_type.ast.align_node != 0) { | 977 | if (ptr_type.ast.align_node.unwrap()) |align_node| { |
| 1009 | const align_first = tree.firstToken(ptr_type.ast.align_node); | 978 | const align_first = tree.firstToken(align_node); |
| 1010 | try renderToken(r, align_first - 2, .none); // align | 979 | try renderToken(r, align_first - 2, .none); // align |
| 1011 | try renderToken(r, align_first - 1, .none); // lparen | 980 | try renderToken(r, align_first - 1, .none); // lparen |
| 1012 | try renderExpression(r, ptr_type.ast.align_node, .none); | 981 | try renderExpression(r, align_node, .none); |
| 1013 | if (ptr_type.ast.bit_range_start != 0) { | 982 | if (ptr_type.ast.bit_range_start.unwrap()) |bit_range_start| { |
| 1014 | assert(ptr_type.ast.bit_range_end != 0); | 983 | const bit_range_end = ptr_type.ast.bit_range_end.unwrap().?; |
| 1015 | try renderToken(r, tree.firstToken(ptr_type.ast.bit_range_start) - 1, .none); // colon | 984 | try renderToken(r, tree.firstToken(bit_range_start) - 1, .none); // colon |
| 1016 | try renderExpression(r, ptr_type.ast.bit_range_start, .none); | 985 | try renderExpression(r, bit_range_start, .none); |
| 1017 | try renderToken(r, tree.firstToken(ptr_type.ast.bit_range_end) - 1, .none); // colon | 986 | try renderToken(r, tree.firstToken(bit_range_end) - 1, .none); // colon |
| 1018 | try renderExpression(r, ptr_type.ast.bit_range_end, .none); | 987 | try renderExpression(r, bit_range_end, .none); |
| 1019 | try renderToken(r, tree.lastToken(ptr_type.ast.bit_range_end) + 1, .space); // rparen | 988 | try renderToken(r, tree.lastToken(bit_range_end) + 1, .space); // rparen |
| 1020 | } else { | 989 | } else { |
| 1021 | try renderToken(r, tree.lastToken(ptr_type.ast.align_node) + 1, .space); // rparen | 990 | try renderToken(r, tree.lastToken(align_node) + 1, .space); // rparen |
| 1022 | } | 991 | } |
| 1023 | } | 992 | } |
| 1024 | 993 | ||
| 1025 | if (ptr_type.ast.addrspace_node != 0) { | 994 | if (ptr_type.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 1026 | const addrspace_first = tree.firstToken(ptr_type.ast.addrspace_node); | 995 | const addrspace_first = tree.firstToken(addrspace_node); |
| 1027 | try renderToken(r, addrspace_first - 2, .none); // addrspace | 996 | try renderToken(r, addrspace_first - 2, .none); // addrspace |
| 1028 | try renderToken(r, addrspace_first - 1, .none); // lparen | 997 | try renderToken(r, addrspace_first - 1, .none); // lparen |
| 1029 | try renderExpression(r, ptr_type.ast.addrspace_node, .none); | 998 | try renderExpression(r, addrspace_node, .none); |
| 1030 | try renderToken(r, tree.lastToken(ptr_type.ast.addrspace_node) + 1, .space); // rparen | 999 | try renderToken(r, tree.lastToken(addrspace_node) + 1, .space); // rparen |
| 1031 | } | 1000 | } |
| 1032 | 1001 | ||
| 1033 | if (ptr_type.const_token) |const_token| { | 1002 | if (ptr_type.const_token) |const_token| { |
| ... | @@ -1048,13 +1017,12 @@ fn renderSlice( | ... | @@ -1048,13 +1017,12 @@ fn renderSlice( |
| 1048 | space: Space, | 1017 | space: Space, |
| 1049 | ) Error!void { | 1018 | ) Error!void { |
| 1050 | const tree = r.tree; | 1019 | const tree = r.tree; |
| 1051 | const node_tags = tree.nodes.items(.tag); | 1020 | const after_start_space_bool = nodeCausesSliceOpSpace(tree.nodeTag(slice.ast.start)) or |
| 1052 | const after_start_space_bool = nodeCausesSliceOpSpace(node_tags[slice.ast.start]) or | 1021 | if (slice.ast.end.unwrap()) |end| nodeCausesSliceOpSpace(tree.nodeTag(end)) else false; |
| 1053 | if (slice.ast.end != 0) nodeCausesSliceOpSpace(node_tags[slice.ast.end]) else false; | ||
| 1054 | const after_start_space = if (after_start_space_bool) Space.space else Space.none; | 1022 | const after_start_space = if (after_start_space_bool) Space.space else Space.none; |
| 1055 | const after_dots_space = if (slice.ast.end != 0) | 1023 | const after_dots_space = if (slice.ast.end != .none) |
| 1056 | after_start_space | 1024 | after_start_space |
| 1057 | else if (slice.ast.sentinel != 0) Space.space else Space.none; | 1025 | else if (slice.ast.sentinel != .none) Space.space else Space.none; |
| 1058 | 1026 | ||
| 1059 | try renderExpression(r, slice.ast.sliced, .none); | 1027 | try renderExpression(r, slice.ast.sliced, .none); |
| 1060 | try renderToken(r, slice.ast.lbracket, .none); // lbracket | 1028 | try renderToken(r, slice.ast.lbracket, .none); // lbracket |
| ... | @@ -1063,14 +1031,14 @@ fn renderSlice( | ... | @@ -1063,14 +1031,14 @@ fn renderSlice( |
| 1063 | try renderExpression(r, slice.ast.start, after_start_space); | 1031 | try renderExpression(r, slice.ast.start, after_start_space); |
| 1064 | try renderToken(r, start_last + 1, after_dots_space); // ellipsis2 ("..") | 1032 | try renderToken(r, start_last + 1, after_dots_space); // ellipsis2 ("..") |
| 1065 | 1033 | ||
| 1066 | if (slice.ast.end != 0) { | 1034 | if (slice.ast.end.unwrap()) |end| { |
| 1067 | const after_end_space = if (slice.ast.sentinel != 0) Space.space else Space.none; | 1035 | const after_end_space = if (slice.ast.sentinel != .none) Space.space else Space.none; |
| 1068 | try renderExpression(r, slice.ast.end, after_end_space); | 1036 | try renderExpression(r, end, after_end_space); |
| 1069 | } | 1037 | } |
| 1070 | 1038 | ||
| 1071 | if (slice.ast.sentinel != 0) { | 1039 | if (slice.ast.sentinel.unwrap()) |sentinel| { |
| 1072 | try renderToken(r, tree.firstToken(slice.ast.sentinel) - 1, .none); // colon | 1040 | try renderToken(r, tree.firstToken(sentinel) - 1, .none); // colon |
| 1073 | try renderExpression(r, slice.ast.sentinel, .none); | 1041 | try renderExpression(r, sentinel, .none); |
| 1074 | } | 1042 | } |
| 1075 | 1043 | ||
| 1076 | try renderToken(r, tree.lastToken(slice_node), space); // rbracket | 1044 | try renderToken(r, tree.lastToken(slice_node), space); // rbracket |
| ... | @@ -1082,12 +1050,8 @@ fn renderAsmOutput( | ... | @@ -1082,12 +1050,8 @@ fn renderAsmOutput( |
| 1082 | space: Space, | 1050 | space: Space, |
| 1083 | ) Error!void { | 1051 | ) Error!void { |
| 1084 | const tree = r.tree; | 1052 | const tree = r.tree; |
| 1085 | const token_tags = tree.tokens.items(.tag); | 1053 | assert(tree.nodeTag(asm_output) == .asm_output); |
| 1086 | const node_tags = tree.nodes.items(.tag); | 1054 | const symbolic_name = tree.nodeMainToken(asm_output); |
| 1087 | const main_tokens = tree.nodes.items(.main_token); | ||
| 1088 | const datas = tree.nodes.items(.data); | ||
| 1089 | assert(node_tags[asm_output] == .asm_output); | ||
| 1090 | const symbolic_name = main_tokens[asm_output]; | ||
| 1091 | 1055 | ||
| 1092 | try renderToken(r, symbolic_name - 1, .none); // lbracket | 1056 | try renderToken(r, symbolic_name - 1, .none); // lbracket |
| 1093 | try renderIdentifier(r, symbolic_name, .none, .eagerly_unquote); // ident | 1057 | try renderIdentifier(r, symbolic_name, .none, .eagerly_unquote); // ident |
| ... | @@ -1095,10 +1059,11 @@ fn renderAsmOutput( | ... | @@ -1095,10 +1059,11 @@ fn renderAsmOutput( |
| 1095 | try renderToken(r, symbolic_name + 2, .space); // "constraint" | 1059 | try renderToken(r, symbolic_name + 2, .space); // "constraint" |
| 1096 | try renderToken(r, symbolic_name + 3, .none); // lparen | 1060 | try renderToken(r, symbolic_name + 3, .none); // lparen |
| 1097 | 1061 | ||
| 1098 | if (token_tags[symbolic_name + 4] == .arrow) { | 1062 | if (tree.tokenTag(symbolic_name + 4) == .arrow) { |
| 1063 | const type_expr, const rparen = tree.nodeData(asm_output).opt_node_and_token; | ||
| 1099 | try renderToken(r, symbolic_name + 4, .space); // -> | 1064 | try renderToken(r, symbolic_name + 4, .space); // -> |
| 1100 | try renderExpression(r, datas[asm_output].lhs, Space.none); | 1065 | try renderExpression(r, type_expr.unwrap().?, Space.none); |
| 1101 | return renderToken(r, datas[asm_output].rhs, space); // rparen | 1066 | return renderToken(r, rparen, space); |
| 1102 | } else { | 1067 | } else { |
| 1103 | try renderIdentifier(r, symbolic_name + 4, .none, .eagerly_unquote); // ident | 1068 | try renderIdentifier(r, symbolic_name + 4, .none, .eagerly_unquote); // ident |
| 1104 | return renderToken(r, symbolic_name + 5, space); // rparen | 1069 | return renderToken(r, symbolic_name + 5, space); // rparen |
| ... | @@ -1111,19 +1076,17 @@ fn renderAsmInput( | ... | @@ -1111,19 +1076,17 @@ fn renderAsmInput( |
| 1111 | space: Space, | 1076 | space: Space, |
| 1112 | ) Error!void { | 1077 | ) Error!void { |
| 1113 | const tree = r.tree; | 1078 | const tree = r.tree; |
| 1114 | const node_tags = tree.nodes.items(.tag); | 1079 | assert(tree.nodeTag(asm_input) == .asm_input); |
| 1115 | const main_tokens = tree.nodes.items(.main_token); | 1080 | const symbolic_name = tree.nodeMainToken(asm_input); |
| 1116 | const datas = tree.nodes.items(.data); | 1081 | const expr, const rparen = tree.nodeData(asm_input).node_and_token; |
| 1117 | assert(node_tags[asm_input] == .asm_input); | ||
| 1118 | const symbolic_name = main_tokens[asm_input]; | ||
| 1119 | 1082 | ||
| 1120 | try renderToken(r, symbolic_name - 1, .none); // lbracket | 1083 | try renderToken(r, symbolic_name - 1, .none); // lbracket |
| 1121 | try renderIdentifier(r, symbolic_name, .none, .eagerly_unquote); // ident | 1084 | try renderIdentifier(r, symbolic_name, .none, .eagerly_unquote); // ident |
| 1122 | try renderToken(r, symbolic_name + 1, .space); // rbracket | 1085 | try renderToken(r, symbolic_name + 1, .space); // rbracket |
| 1123 | try renderToken(r, symbolic_name + 2, .space); // "constraint" | 1086 | try renderToken(r, symbolic_name + 2, .space); // "constraint" |
| 1124 | try renderToken(r, symbolic_name + 3, .none); // lparen | 1087 | try renderToken(r, symbolic_name + 3, .none); // lparen |
| 1125 | try renderExpression(r, datas[asm_input].lhs, Space.none); | 1088 | try renderExpression(r, expr, Space.none); |
| 1126 | return renderToken(r, datas[asm_input].rhs, space); // rparen | 1089 | return renderToken(r, rparen, space); |
| 1127 | } | 1090 | } |
| 1128 | 1091 | ||
| 1129 | fn renderVarDecl( | 1092 | fn renderVarDecl( |
| ... | @@ -1179,15 +1142,15 @@ fn renderVarDeclWithoutFixups( | ... | @@ -1179,15 +1142,15 @@ fn renderVarDeclWithoutFixups( |
| 1179 | 1142 | ||
| 1180 | try renderToken(r, var_decl.ast.mut_token, .space); // var | 1143 | try renderToken(r, var_decl.ast.mut_token, .space); // var |
| 1181 | 1144 | ||
| 1182 | if (var_decl.ast.type_node != 0 or var_decl.ast.align_node != 0 or | 1145 | if (var_decl.ast.type_node != .none or var_decl.ast.align_node != .none or |
| 1183 | var_decl.ast.addrspace_node != 0 or var_decl.ast.section_node != 0 or | 1146 | var_decl.ast.addrspace_node != .none or var_decl.ast.section_node != .none or |
| 1184 | var_decl.ast.init_node != 0) | 1147 | var_decl.ast.init_node != .none) |
| 1185 | { | 1148 | { |
| 1186 | const name_space = if (var_decl.ast.type_node == 0 and | 1149 | const name_space = if (var_decl.ast.type_node == .none and |
| 1187 | (var_decl.ast.align_node != 0 or | 1150 | (var_decl.ast.align_node != .none or |
| 1188 | var_decl.ast.addrspace_node != 0 or | 1151 | var_decl.ast.addrspace_node != .none or |
| 1189 | var_decl.ast.section_node != 0 or | 1152 | var_decl.ast.section_node != .none or |
| 1190 | var_decl.ast.init_node != 0)) | 1153 | var_decl.ast.init_node != .none)) |
| 1191 | Space.space | 1154 | Space.space |
| 1192 | else | 1155 | else |
| 1193 | Space.none; | 1156 | Space.none; |
| ... | @@ -1197,26 +1160,26 @@ fn renderVarDeclWithoutFixups( | ... | @@ -1197,26 +1160,26 @@ fn renderVarDeclWithoutFixups( |
| 1197 | return renderIdentifier(r, var_decl.ast.mut_token + 1, space, .preserve_when_shadowing); // name | 1160 | return renderIdentifier(r, var_decl.ast.mut_token + 1, space, .preserve_when_shadowing); // name |
| 1198 | } | 1161 | } |
| 1199 | 1162 | ||
| 1200 | if (var_decl.ast.type_node != 0) { | 1163 | if (var_decl.ast.type_node.unwrap()) |type_node| { |
| 1201 | try renderToken(r, var_decl.ast.mut_token + 2, Space.space); // : | 1164 | try renderToken(r, var_decl.ast.mut_token + 2, Space.space); // : |
| 1202 | if (var_decl.ast.align_node != 0 or var_decl.ast.addrspace_node != 0 or | 1165 | if (var_decl.ast.align_node != .none or var_decl.ast.addrspace_node != .none or |
| 1203 | var_decl.ast.section_node != 0 or var_decl.ast.init_node != 0) | 1166 | var_decl.ast.section_node != .none or var_decl.ast.init_node != .none) |
| 1204 | { | 1167 | { |
| 1205 | try renderExpression(r, var_decl.ast.type_node, .space); | 1168 | try renderExpression(r, type_node, .space); |
| 1206 | } else { | 1169 | } else { |
| 1207 | return renderExpression(r, var_decl.ast.type_node, space); | 1170 | return renderExpression(r, type_node, space); |
| 1208 | } | 1171 | } |
| 1209 | } | 1172 | } |
| 1210 | 1173 | ||
| 1211 | if (var_decl.ast.align_node != 0) { | 1174 | if (var_decl.ast.align_node.unwrap()) |align_node| { |
| 1212 | const lparen = tree.firstToken(var_decl.ast.align_node) - 1; | 1175 | const lparen = tree.firstToken(align_node) - 1; |
| 1213 | const align_kw = lparen - 1; | 1176 | const align_kw = lparen - 1; |
| 1214 | const rparen = tree.lastToken(var_decl.ast.align_node) + 1; | 1177 | const rparen = tree.lastToken(align_node) + 1; |
| 1215 | try renderToken(r, align_kw, Space.none); // align | 1178 | try renderToken(r, align_kw, Space.none); // align |
| 1216 | try renderToken(r, lparen, Space.none); // ( | 1179 | try renderToken(r, lparen, Space.none); // ( |
| 1217 | try renderExpression(r, var_decl.ast.align_node, Space.none); | 1180 | try renderExpression(r, align_node, Space.none); |
| 1218 | if (var_decl.ast.addrspace_node != 0 or var_decl.ast.section_node != 0 or | 1181 | if (var_decl.ast.addrspace_node != .none or var_decl.ast.section_node != .none or |
| 1219 | var_decl.ast.init_node != 0) | 1182 | var_decl.ast.init_node != .none) |
| 1220 | { | 1183 | { |
| 1221 | try renderToken(r, rparen, .space); // ) | 1184 | try renderToken(r, rparen, .space); // ) |
| 1222 | } else { | 1185 | } else { |
| ... | @@ -1224,14 +1187,14 @@ fn renderVarDeclWithoutFixups( | ... | @@ -1224,14 +1187,14 @@ fn renderVarDeclWithoutFixups( |
| 1224 | } | 1187 | } |
| 1225 | } | 1188 | } |
| 1226 | 1189 | ||
| 1227 | if (var_decl.ast.addrspace_node != 0) { | 1190 | if (var_decl.ast.addrspace_node.unwrap()) |addrspace_node| { |
| 1228 | const lparen = tree.firstToken(var_decl.ast.addrspace_node) - 1; | 1191 | const lparen = tree.firstToken(addrspace_node) - 1; |
| 1229 | const addrspace_kw = lparen - 1; | 1192 | const addrspace_kw = lparen - 1; |
| 1230 | const rparen = tree.lastToken(var_decl.ast.addrspace_node) + 1; | 1193 | const rparen = tree.lastToken(addrspace_node) + 1; |
| 1231 | try renderToken(r, addrspace_kw, Space.none); // addrspace | 1194 | try renderToken(r, addrspace_kw, Space.none); // addrspace |
| 1232 | try renderToken(r, lparen, Space.none); // ( | 1195 | try renderToken(r, lparen, Space.none); // ( |
| 1233 | try renderExpression(r, var_decl.ast.addrspace_node, Space.none); | 1196 | try renderExpression(r, addrspace_node, Space.none); |
| 1234 | if (var_decl.ast.section_node != 0 or var_decl.ast.init_node != 0) { | 1197 | if (var_decl.ast.section_node != .none or var_decl.ast.init_node != .none) { |
| 1235 | try renderToken(r, rparen, .space); // ) | 1198 | try renderToken(r, rparen, .space); // ) |
| 1236 | } else { | 1199 | } else { |
| 1237 | try renderToken(r, rparen, .none); // ) | 1200 | try renderToken(r, rparen, .none); // ) |
| ... | @@ -1239,27 +1202,27 @@ fn renderVarDeclWithoutFixups( | ... | @@ -1239,27 +1202,27 @@ fn renderVarDeclWithoutFixups( |
| 1239 | } | 1202 | } |
| 1240 | } | 1203 | } |
| 1241 | 1204 | ||
| 1242 | if (var_decl.ast.section_node != 0) { | 1205 | if (var_decl.ast.section_node.unwrap()) |section_node| { |
| 1243 | const lparen = tree.firstToken(var_decl.ast.section_node) - 1; | 1206 | const lparen = tree.firstToken(section_node) - 1; |
| 1244 | const section_kw = lparen - 1; | 1207 | const section_kw = lparen - 1; |
| 1245 | const rparen = tree.lastToken(var_decl.ast.section_node) + 1; | 1208 | const rparen = tree.lastToken(section_node) + 1; |
| 1246 | try renderToken(r, section_kw, Space.none); // linksection | 1209 | try renderToken(r, section_kw, Space.none); // linksection |
| 1247 | try renderToken(r, lparen, Space.none); // ( | 1210 | try renderToken(r, lparen, Space.none); // ( |
| 1248 | try renderExpression(r, var_decl.ast.section_node, Space.none); | 1211 | try renderExpression(r, section_node, Space.none); |
| 1249 | if (var_decl.ast.init_node != 0) { | 1212 | if (var_decl.ast.init_node != .none) { |
| 1250 | try renderToken(r, rparen, .space); // ) | 1213 | try renderToken(r, rparen, .space); // ) |
| 1251 | } else { | 1214 | } else { |
| 1252 | return renderToken(r, rparen, space); // ) | 1215 | return renderToken(r, rparen, space); // ) |
| 1253 | } | 1216 | } |
| 1254 | } | 1217 | } |
| 1255 | 1218 | ||
| 1256 | assert(var_decl.ast.init_node != 0); | 1219 | const init_node = var_decl.ast.init_node.unwrap().?; |
| 1257 | 1220 | ||
| 1258 | const eq_token = tree.firstToken(var_decl.ast.init_node) - 1; | 1221 | const eq_token = tree.firstToken(init_node) - 1; |
| 1259 | const eq_space: Space = if (tree.tokensOnSameLine(eq_token, eq_token + 1)) .space else .newline; | 1222 | const eq_space: Space = if (tree.tokensOnSameLine(eq_token, eq_token + 1)) .space else .newline; |
| 1260 | try ais.pushIndent(.after_equals); | 1223 | try ais.pushIndent(.after_equals); |
| 1261 | try renderToken(r, eq_token, eq_space); // = | 1224 | try renderToken(r, eq_token, eq_space); // = |
| 1262 | try renderExpression(r, var_decl.ast.init_node, space); // ; | 1225 | try renderExpression(r, init_node, space); // ; |
| 1263 | ais.popIndent(); | 1226 | ais.popIndent(); |
| 1264 | } | 1227 | } |
| 1265 | 1228 | ||
| ... | @@ -1268,7 +1231,7 @@ fn renderIf(r: *Render, if_node: Ast.full.If, space: Space) Error!void { | ... | @@ -1268,7 +1231,7 @@ fn renderIf(r: *Render, if_node: Ast.full.If, space: Space) Error!void { |
| 1268 | .ast = .{ | 1231 | .ast = .{ |
| 1269 | .while_token = if_node.ast.if_token, | 1232 | .while_token = if_node.ast.if_token, |
| 1270 | .cond_expr = if_node.ast.cond_expr, | 1233 | .cond_expr = if_node.ast.cond_expr, |
| 1271 | .cont_expr = 0, | 1234 | .cont_expr = .none, |
| 1272 | .then_expr = if_node.ast.then_expr, | 1235 | .then_expr = if_node.ast.then_expr, |
| 1273 | .else_expr = if_node.ast.else_expr, | 1236 | .else_expr = if_node.ast.else_expr, |
| 1274 | }, | 1237 | }, |
| ... | @@ -1284,7 +1247,6 @@ fn renderIf(r: *Render, if_node: Ast.full.If, space: Space) Error!void { | ... | @@ -1284,7 +1247,6 @@ fn renderIf(r: *Render, if_node: Ast.full.If, space: Space) Error!void { |
| 1284 | /// respective values set to null. | 1247 | /// respective values set to null. |
| 1285 | fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void { | 1248 | fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void { |
| 1286 | const tree = r.tree; | 1249 | const tree = r.tree; |
| 1287 | const token_tags = tree.tokens.items(.tag); | ||
| 1288 | 1250 | ||
| 1289 | if (while_node.label_token) |label| { | 1251 | if (while_node.label_token) |label| { |
| 1290 | try renderIdentifier(r, label, .none, .eagerly_unquote); // label | 1252 | try renderIdentifier(r, label, .none, .eagerly_unquote); // label |
| ... | @@ -1305,7 +1267,7 @@ fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void | ... | @@ -1305,7 +1267,7 @@ fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void |
| 1305 | try renderToken(r, last_prefix_token, .space); | 1267 | try renderToken(r, last_prefix_token, .space); |
| 1306 | try renderToken(r, payload_token - 1, .none); // | | 1268 | try renderToken(r, payload_token - 1, .none); // | |
| 1307 | const ident = blk: { | 1269 | const ident = blk: { |
| 1308 | if (token_tags[payload_token] == .asterisk) { | 1270 | if (tree.tokenTag(payload_token) == .asterisk) { |
| 1309 | try renderToken(r, payload_token, .none); // * | 1271 | try renderToken(r, payload_token, .none); // * |
| 1310 | break :blk payload_token + 1; | 1272 | break :blk payload_token + 1; |
| 1311 | } else { | 1273 | } else { |
| ... | @@ -1314,7 +1276,7 @@ fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void | ... | @@ -1314,7 +1276,7 @@ fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void |
| 1314 | }; | 1276 | }; |
| 1315 | try renderIdentifier(r, ident, .none, .preserve_when_shadowing); // identifier | 1277 | try renderIdentifier(r, ident, .none, .preserve_when_shadowing); // identifier |
| 1316 | const pipe = blk: { | 1278 | const pipe = blk: { |
| 1317 | if (token_tags[ident + 1] == .comma) { | 1279 | if (tree.tokenTag(ident + 1) == .comma) { |
| 1318 | try renderToken(r, ident + 1, .space); // , | 1280 | try renderToken(r, ident + 1, .space); // , |
| 1319 | try renderIdentifier(r, ident + 2, .none, .preserve_when_shadowing); // index | 1281 | try renderIdentifier(r, ident + 2, .none, .preserve_when_shadowing); // index |
| 1320 | break :blk ident + 3; | 1282 | break :blk ident + 3; |
| ... | @@ -1325,13 +1287,13 @@ fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void | ... | @@ -1325,13 +1287,13 @@ fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void |
| 1325 | last_prefix_token = pipe; | 1287 | last_prefix_token = pipe; |
| 1326 | } | 1288 | } |
| 1327 | 1289 | ||
| 1328 | if (while_node.ast.cont_expr != 0) { | 1290 | if (while_node.ast.cont_expr.unwrap()) |cont_expr| { |
| 1329 | try renderToken(r, last_prefix_token, .space); | 1291 | try renderToken(r, last_prefix_token, .space); |
| 1330 | const lparen = tree.firstToken(while_node.ast.cont_expr) - 1; | 1292 | const lparen = tree.firstToken(cont_expr) - 1; |
| 1331 | try renderToken(r, lparen - 1, .space); // : | 1293 | try renderToken(r, lparen - 1, .space); // : |
| 1332 | try renderToken(r, lparen, .none); // lparen | 1294 | try renderToken(r, lparen, .none); // lparen |
| 1333 | try renderExpression(r, while_node.ast.cont_expr, .none); | 1295 | try renderExpression(r, cont_expr, .none); |
| 1334 | last_prefix_token = tree.lastToken(while_node.ast.cont_expr) + 1; // rparen | 1296 | last_prefix_token = tree.lastToken(cont_expr) + 1; // rparen |
| 1335 | } | 1297 | } |
| 1336 | 1298 | ||
| 1337 | try renderThenElse( | 1299 | try renderThenElse( |
| ... | @@ -1349,15 +1311,14 @@ fn renderThenElse( | ... | @@ -1349,15 +1311,14 @@ fn renderThenElse( |
| 1349 | r: *Render, | 1311 | r: *Render, |
| 1350 | last_prefix_token: Ast.TokenIndex, | 1312 | last_prefix_token: Ast.TokenIndex, |
| 1351 | then_expr: Ast.Node.Index, | 1313 | then_expr: Ast.Node.Index, |
| 1352 | else_token: Ast.TokenIndex, | 1314 | else_token: ?Ast.TokenIndex, |
| 1353 | maybe_error_token: ?Ast.TokenIndex, | 1315 | maybe_error_token: ?Ast.TokenIndex, |
| 1354 | else_expr: Ast.Node.Index, | 1316 | opt_else_expr: Ast.Node.OptionalIndex, |
| 1355 | space: Space, | 1317 | space: Space, |
| 1356 | ) Error!void { | 1318 | ) Error!void { |
| 1357 | const tree = r.tree; | 1319 | const tree = r.tree; |
| 1358 | const ais = r.ais; | 1320 | const ais = r.ais; |
| 1359 | const node_tags = tree.nodes.items(.tag); | 1321 | const then_expr_is_block = nodeIsBlock(tree.nodeTag(then_expr)); |
| 1360 | const then_expr_is_block = nodeIsBlock(node_tags[then_expr]); | ||
| 1361 | const indent_then_expr = !then_expr_is_block and | 1322 | const indent_then_expr = !then_expr_is_block and |
| 1362 | !tree.tokensOnSameLine(last_prefix_token, tree.firstToken(then_expr)); | 1323 | !tree.tokensOnSameLine(last_prefix_token, tree.firstToken(then_expr)); |
| 1363 | 1324 | ||
| ... | @@ -1373,7 +1334,7 @@ fn renderThenElse( | ... | @@ -1373,7 +1334,7 @@ fn renderThenElse( |
| 1373 | try renderToken(r, last_prefix_token, .space); | 1334 | try renderToken(r, last_prefix_token, .space); |
| 1374 | } | 1335 | } |
| 1375 | 1336 | ||
| 1376 | if (else_expr != 0) { | 1337 | if (opt_else_expr.unwrap()) |else_expr| { |
| 1377 | if (indent_then_expr) { | 1338 | if (indent_then_expr) { |
| 1378 | try renderExpression(r, then_expr, .newline); | 1339 | try renderExpression(r, then_expr, .newline); |
| 1379 | } else { | 1340 | } else { |
| ... | @@ -1382,18 +1343,18 @@ fn renderThenElse( | ... | @@ -1382,18 +1343,18 @@ fn renderThenElse( |
| 1382 | 1343 | ||
| 1383 | if (indent_then_expr) ais.popIndent(); | 1344 | if (indent_then_expr) ais.popIndent(); |
| 1384 | 1345 | ||
| 1385 | var last_else_token = else_token; | 1346 | var last_else_token = else_token.?; |
| 1386 | 1347 | ||
| 1387 | if (maybe_error_token) |error_token| { | 1348 | if (maybe_error_token) |error_token| { |
| 1388 | try renderToken(r, else_token, .space); // else | 1349 | try renderToken(r, last_else_token, .space); // else |
| 1389 | try renderToken(r, error_token - 1, .none); // | | 1350 | try renderToken(r, error_token - 1, .none); // | |
| 1390 | try renderIdentifier(r, error_token, .none, .preserve_when_shadowing); // identifier | 1351 | try renderIdentifier(r, error_token, .none, .preserve_when_shadowing); // identifier |
| 1391 | last_else_token = error_token + 1; // | | 1352 | last_else_token = error_token + 1; // | |
| 1392 | } | 1353 | } |
| 1393 | 1354 | ||
| 1394 | const indent_else_expr = indent_then_expr and | 1355 | const indent_else_expr = indent_then_expr and |
| 1395 | !nodeIsBlock(node_tags[else_expr]) and | 1356 | !nodeIsBlock(tree.nodeTag(else_expr)) and |
| 1396 | !nodeIsIfForWhileSwitch(node_tags[else_expr]); | 1357 | !nodeIsIfForWhileSwitch(tree.nodeTag(else_expr)); |
| 1397 | if (indent_else_expr) { | 1358 | if (indent_else_expr) { |
| 1398 | try ais.pushIndent(.normal); | 1359 | try ais.pushIndent(.normal); |
| 1399 | try renderToken(r, last_else_token, .newline); | 1360 | try renderToken(r, last_else_token, .newline); |
| ... | @@ -1430,21 +1391,21 @@ fn renderFor(r: *Render, for_node: Ast.full.For, space: Space) Error!void { | ... | @@ -1430,21 +1391,21 @@ fn renderFor(r: *Render, for_node: Ast.full.For, space: Space) Error!void { |
| 1430 | 1391 | ||
| 1431 | var cur = for_node.payload_token; | 1392 | var cur = for_node.payload_token; |
| 1432 | const pipe = std.mem.indexOfScalarPos(std.zig.Token.Tag, token_tags, cur, .pipe).?; | 1393 | const pipe = std.mem.indexOfScalarPos(std.zig.Token.Tag, token_tags, cur, .pipe).?; |
| 1433 | if (token_tags[pipe - 1] == .comma) { | 1394 | if (tree.tokenTag(@intCast(pipe - 1)) == .comma) { |
| 1434 | try ais.pushIndent(.normal); | 1395 | try ais.pushIndent(.normal); |
| 1435 | try renderToken(r, cur - 1, .newline); // | | 1396 | try renderToken(r, cur - 1, .newline); // | |
| 1436 | while (true) { | 1397 | while (true) { |
| 1437 | if (token_tags[cur] == .asterisk) { | 1398 | if (tree.tokenTag(cur) == .asterisk) { |
| 1438 | try renderToken(r, cur, .none); // * | 1399 | try renderToken(r, cur, .none); // * |
| 1439 | cur += 1; | 1400 | cur += 1; |
| 1440 | } | 1401 | } |
| 1441 | try renderIdentifier(r, cur, .none, .preserve_when_shadowing); // identifier | 1402 | try renderIdentifier(r, cur, .none, .preserve_when_shadowing); // identifier |
| 1442 | cur += 1; | 1403 | cur += 1; |
| 1443 | if (token_tags[cur] == .comma) { | 1404 | if (tree.tokenTag(cur) == .comma) { |
| 1444 | try renderToken(r, cur, .newline); // , | 1405 | try renderToken(r, cur, .newline); // , |
| 1445 | cur += 1; | 1406 | cur += 1; |
| 1446 | } | 1407 | } |
| 1447 | if (token_tags[cur] == .pipe) { | 1408 | if (tree.tokenTag(cur) == .pipe) { |
| 1448 | break; | 1409 | break; |
| 1449 | } | 1410 | } |
| 1450 | } | 1411 | } |
| ... | @@ -1452,17 +1413,17 @@ fn renderFor(r: *Render, for_node: Ast.full.For, space: Space) Error!void { | ... | @@ -1452,17 +1413,17 @@ fn renderFor(r: *Render, for_node: Ast.full.For, space: Space) Error!void { |
| 1452 | } else { | 1413 | } else { |
| 1453 | try renderToken(r, cur - 1, .none); // | | 1414 | try renderToken(r, cur - 1, .none); // | |
| 1454 | while (true) { | 1415 | while (true) { |
| 1455 | if (token_tags[cur] == .asterisk) { | 1416 | if (tree.tokenTag(cur) == .asterisk) { |
| 1456 | try renderToken(r, cur, .none); // * | 1417 | try renderToken(r, cur, .none); // * |
| 1457 | cur += 1; | 1418 | cur += 1; |
| 1458 | } | 1419 | } |
| 1459 | try renderIdentifier(r, cur, .none, .preserve_when_shadowing); // identifier | 1420 | try renderIdentifier(r, cur, .none, .preserve_when_shadowing); // identifier |
| 1460 | cur += 1; | 1421 | cur += 1; |
| 1461 | if (token_tags[cur] == .comma) { | 1422 | if (tree.tokenTag(cur) == .comma) { |
| 1462 | try renderToken(r, cur, .space); // , | 1423 | try renderToken(r, cur, .space); // , |
| 1463 | cur += 1; | 1424 | cur += 1; |
| 1464 | } | 1425 | } |
| 1465 | if (token_tags[cur] == .pipe) { | 1426 | if (tree.tokenTag(cur) == .pipe) { |
| 1466 | break; | 1427 | break; |
| 1467 | } | 1428 | } |
| 1468 | } | 1429 | } |
| ... | @@ -1488,7 +1449,7 @@ fn renderContainerField( | ... | @@ -1488,7 +1449,7 @@ fn renderContainerField( |
| 1488 | const tree = r.tree; | 1449 | const tree = r.tree; |
| 1489 | const ais = r.ais; | 1450 | const ais = r.ais; |
| 1490 | var field = field_param; | 1451 | var field = field_param; |
| 1491 | if (container != .tuple) field.convertToNonTupleLike(tree.nodes); | 1452 | if (container != .tuple) field.convertToNonTupleLike(&tree); |
| 1492 | const quote: QuoteBehavior = switch (container) { | 1453 | const quote: QuoteBehavior = switch (container) { |
| 1493 | .@"enum" => .eagerly_unquote_except_underscore, | 1454 | .@"enum" => .eagerly_unquote_except_underscore, |
| 1494 | .tuple, .other => .eagerly_unquote, | 1455 | .tuple, .other => .eagerly_unquote, |
| ... | @@ -1497,67 +1458,74 @@ fn renderContainerField( | ... | @@ -1497,67 +1458,74 @@ fn renderContainerField( |
| 1497 | if (field.comptime_token) |t| { | 1458 | if (field.comptime_token) |t| { |
| 1498 | try renderToken(r, t, .space); // comptime | 1459 | try renderToken(r, t, .space); // comptime |
| 1499 | } | 1460 | } |
| 1500 | if (field.ast.type_expr == 0 and field.ast.value_expr == 0) { | 1461 | if (field.ast.type_expr == .none and field.ast.value_expr == .none) { |
| 1501 | if (field.ast.align_expr != 0) { | 1462 | if (field.ast.align_expr.unwrap()) |align_expr| { |
| 1502 | try renderIdentifier(r, field.ast.main_token, .space, quote); // name | 1463 | try renderIdentifier(r, field.ast.main_token, .space, quote); // name |
| 1503 | const lparen_token = tree.firstToken(field.ast.align_expr) - 1; | 1464 | const lparen_token = tree.firstToken(align_expr) - 1; |
| 1504 | const align_kw = lparen_token - 1; | 1465 | const align_kw = lparen_token - 1; |
| 1505 | const rparen_token = tree.lastToken(field.ast.align_expr) + 1; | 1466 | const rparen_token = tree.lastToken(align_expr) + 1; |
| 1506 | try renderToken(r, align_kw, .none); // align | 1467 | try renderToken(r, align_kw, .none); // align |
| 1507 | try renderToken(r, lparen_token, .none); // ( | 1468 | try renderToken(r, lparen_token, .none); // ( |
| 1508 | try renderExpression(r, field.ast.align_expr, .none); // alignment | 1469 | try renderExpression(r, align_expr, .none); // alignment |
| 1509 | return renderToken(r, rparen_token, .space); // ) | 1470 | return renderToken(r, rparen_token, .space); // ) |
| 1510 | } | 1471 | } |
| 1511 | return renderIdentifierComma(r, field.ast.main_token, space, quote); // name | 1472 | return renderIdentifierComma(r, field.ast.main_token, space, quote); // name |
| 1512 | } | 1473 | } |
| 1513 | if (field.ast.type_expr != 0 and field.ast.value_expr == 0) { | 1474 | if (field.ast.type_expr != .none and field.ast.value_expr == .none) { |
| 1475 | const type_expr = field.ast.type_expr.unwrap().?; | ||
| 1514 | if (!field.ast.tuple_like) { | 1476 | if (!field.ast.tuple_like) { |
| 1515 | try renderIdentifier(r, field.ast.main_token, .none, quote); // name | 1477 | try renderIdentifier(r, field.ast.main_token, .none, quote); // name |
| 1516 | try renderToken(r, field.ast.main_token + 1, .space); // : | 1478 | try renderToken(r, field.ast.main_token + 1, .space); // : |
| 1517 | } | 1479 | } |
| 1518 | 1480 | ||
| 1519 | if (field.ast.align_expr != 0) { | 1481 | if (field.ast.align_expr.unwrap()) |align_expr| { |
| 1520 | try renderExpression(r, field.ast.type_expr, .space); // type | 1482 | try renderExpression(r, type_expr, .space); // type |
| 1521 | const align_token = tree.firstToken(field.ast.align_expr) - 2; | 1483 | const align_token = tree.firstToken(align_expr) - 2; |
| 1522 | try renderToken(r, align_token, .none); // align | 1484 | try renderToken(r, align_token, .none); // align |
| 1523 | try renderToken(r, align_token + 1, .none); // ( | 1485 | try renderToken(r, align_token + 1, .none); // ( |
| 1524 | try renderExpression(r, field.ast.align_expr, .none); // alignment | 1486 | try renderExpression(r, align_expr, .none); // alignment |
| 1525 | const rparen = tree.lastToken(field.ast.align_expr) + 1; | 1487 | const rparen = tree.lastToken(align_expr) + 1; |
| 1526 | return renderTokenComma(r, rparen, space); // ) | 1488 | return renderTokenComma(r, rparen, space); // ) |
| 1527 | } else { | 1489 | } else { |
| 1528 | return renderExpressionComma(r, field.ast.type_expr, space); // type | 1490 | return renderExpressionComma(r, type_expr, space); // type |
| 1529 | } | 1491 | } |
| 1530 | } | 1492 | } |
| 1531 | if (field.ast.type_expr == 0 and field.ast.value_expr != 0) { | 1493 | if (field.ast.type_expr == .none and field.ast.value_expr != .none) { |
| 1494 | const value_expr = field.ast.value_expr.unwrap().?; | ||
| 1495 | |||
| 1532 | try renderIdentifier(r, field.ast.main_token, .space, quote); // name | 1496 | try renderIdentifier(r, field.ast.main_token, .space, quote); // name |
| 1533 | if (field.ast.align_expr != 0) { | 1497 | if (field.ast.align_expr.unwrap()) |align_expr| { |
| 1534 | const lparen_token = tree.firstToken(field.ast.align_expr) - 1; | 1498 | const lparen_token = tree.firstToken(align_expr) - 1; |
| 1535 | const align_kw = lparen_token - 1; | 1499 | const align_kw = lparen_token - 1; |
| 1536 | const rparen_token = tree.lastToken(field.ast.align_expr) + 1; | 1500 | const rparen_token = tree.lastToken(align_expr) + 1; |
| 1537 | try renderToken(r, align_kw, .none); // align | 1501 | try renderToken(r, align_kw, .none); // align |
| 1538 | try renderToken(r, lparen_token, .none); // ( | 1502 | try renderToken(r, lparen_token, .none); // ( |
| 1539 | try renderExpression(r, field.ast.align_expr, .none); // alignment | 1503 | try renderExpression(r, align_expr, .none); // alignment |
| 1540 | try renderToken(r, rparen_token, .space); // ) | 1504 | try renderToken(r, rparen_token, .space); // ) |
| 1541 | } | 1505 | } |
| 1542 | try renderToken(r, field.ast.main_token + 1, .space); // = | 1506 | try renderToken(r, field.ast.main_token + 1, .space); // = |
| 1543 | return renderExpressionComma(r, field.ast.value_expr, space); // value | 1507 | return renderExpressionComma(r, value_expr, space); // value |
| 1544 | } | 1508 | } |
| 1545 | if (!field.ast.tuple_like) { | 1509 | if (!field.ast.tuple_like) { |
| 1546 | try renderIdentifier(r, field.ast.main_token, .none, quote); // name | 1510 | try renderIdentifier(r, field.ast.main_token, .none, quote); // name |
| 1547 | try renderToken(r, field.ast.main_token + 1, .space); // : | 1511 | try renderToken(r, field.ast.main_token + 1, .space); // : |
| 1548 | } | 1512 | } |
| 1549 | try renderExpression(r, field.ast.type_expr, .space); // type | ||
| 1550 | 1513 | ||
| 1551 | if (field.ast.align_expr != 0) { | 1514 | const type_expr = field.ast.type_expr.unwrap().?; |
| 1552 | const lparen_token = tree.firstToken(field.ast.align_expr) - 1; | 1515 | const value_expr = field.ast.value_expr.unwrap().?; |
| 1516 | |||
| 1517 | try renderExpression(r, type_expr, .space); // type | ||
| 1518 | |||
| 1519 | if (field.ast.align_expr.unwrap()) |align_expr| { | ||
| 1520 | const lparen_token = tree.firstToken(align_expr) - 1; | ||
| 1553 | const align_kw = lparen_token - 1; | 1521 | const align_kw = lparen_token - 1; |
| 1554 | const rparen_token = tree.lastToken(field.ast.align_expr) + 1; | 1522 | const rparen_token = tree.lastToken(align_expr) + 1; |
| 1555 | try renderToken(r, align_kw, .none); // align | 1523 | try renderToken(r, align_kw, .none); // align |
| 1556 | try renderToken(r, lparen_token, .none); // ( | 1524 | try renderToken(r, lparen_token, .none); // ( |
| 1557 | try renderExpression(r, field.ast.align_expr, .none); // alignment | 1525 | try renderExpression(r, align_expr, .none); // alignment |
| 1558 | try renderToken(r, rparen_token, .space); // ) | 1526 | try renderToken(r, rparen_token, .space); // ) |
| 1559 | } | 1527 | } |
| 1560 | const eq_token = tree.firstToken(field.ast.value_expr) - 1; | 1528 | const eq_token = tree.firstToken(value_expr) - 1; |
| 1561 | const eq_space: Space = if (tree.tokensOnSameLine(eq_token, eq_token + 1)) .space else .newline; | 1529 | const eq_space: Space = if (tree.tokensOnSameLine(eq_token, eq_token + 1)) .space else .newline; |
| 1562 | 1530 | ||
| 1563 | try ais.pushIndent(.after_equals); | 1531 | try ais.pushIndent(.after_equals); |
| ... | @@ -1565,19 +1533,18 @@ fn renderContainerField( | ... | @@ -1565,19 +1533,18 @@ fn renderContainerField( |
| 1565 | 1533 | ||
| 1566 | if (eq_space == .space) { | 1534 | if (eq_space == .space) { |
| 1567 | ais.popIndent(); | 1535 | ais.popIndent(); |
| 1568 | try renderExpressionComma(r, field.ast.value_expr, space); // value | 1536 | try renderExpressionComma(r, value_expr, space); // value |
| 1569 | return; | 1537 | return; |
| 1570 | } | 1538 | } |
| 1571 | 1539 | ||
| 1572 | const token_tags = tree.tokens.items(.tag); | 1540 | const maybe_comma = tree.lastToken(value_expr) + 1; |
| 1573 | const maybe_comma = tree.lastToken(field.ast.value_expr) + 1; | ||
| 1574 | 1541 | ||
| 1575 | if (token_tags[maybe_comma] == .comma) { | 1542 | if (tree.tokenTag(maybe_comma) == .comma) { |
| 1576 | try renderExpression(r, field.ast.value_expr, .none); // value | 1543 | try renderExpression(r, value_expr, .none); // value |
| 1577 | ais.popIndent(); | 1544 | ais.popIndent(); |
| 1578 | try renderToken(r, maybe_comma, .newline); | 1545 | try renderToken(r, maybe_comma, .newline); |
| 1579 | } else { | 1546 | } else { |
| 1580 | try renderExpression(r, field.ast.value_expr, space); // value | 1547 | try renderExpression(r, value_expr, space); // value |
| 1581 | ais.popIndent(); | 1548 | ais.popIndent(); |
| 1582 | } | 1549 | } |
| 1583 | } | 1550 | } |
| ... | @@ -1590,8 +1557,6 @@ fn renderBuiltinCall( | ... | @@ -1590,8 +1557,6 @@ fn renderBuiltinCall( |
| 1590 | ) Error!void { | 1557 | ) Error!void { |
| 1591 | const tree = r.tree; | 1558 | const tree = r.tree; |
| 1592 | const ais = r.ais; | 1559 | const ais = r.ais; |
| 1593 | const token_tags = tree.tokens.items(.tag); | ||
| 1594 | const main_tokens = tree.nodes.items(.main_token); | ||
| 1595 | 1560 | ||
| 1596 | try renderToken(r, builtin_token, .none); // @name | 1561 | try renderToken(r, builtin_token, .none); // @name |
| 1597 | 1562 | ||
| ... | @@ -1604,8 +1569,8 @@ fn renderBuiltinCall( | ... | @@ -1604,8 +1569,8 @@ fn renderBuiltinCall( |
| 1604 | const slice = tree.tokenSlice(builtin_token); | 1569 | const slice = tree.tokenSlice(builtin_token); |
| 1605 | if (mem.eql(u8, slice, "@import")) f: { | 1570 | if (mem.eql(u8, slice, "@import")) f: { |
| 1606 | const param = params[0]; | 1571 | const param = params[0]; |
| 1607 | const str_lit_token = main_tokens[param]; | 1572 | const str_lit_token = tree.nodeMainToken(param); |
| 1608 | assert(token_tags[str_lit_token] == .string_literal); | 1573 | assert(tree.tokenTag(str_lit_token) == .string_literal); |
| 1609 | const token_bytes = tree.tokenSlice(str_lit_token); | 1574 | const token_bytes = tree.tokenSlice(str_lit_token); |
| 1610 | const imported_string = std.zig.string_literal.parseAlloc(r.gpa, token_bytes) catch |err| switch (err) { | 1575 | const imported_string = std.zig.string_literal.parseAlloc(r.gpa, token_bytes) catch |err| switch (err) { |
| 1611 | error.OutOfMemory => return error.OutOfMemory, | 1576 | error.OutOfMemory => return error.OutOfMemory, |
| ... | @@ -1624,13 +1589,13 @@ fn renderBuiltinCall( | ... | @@ -1624,13 +1589,13 @@ fn renderBuiltinCall( |
| 1624 | const last_param = params[params.len - 1]; | 1589 | const last_param = params[params.len - 1]; |
| 1625 | const after_last_param_token = tree.lastToken(last_param) + 1; | 1590 | const after_last_param_token = tree.lastToken(last_param) + 1; |
| 1626 | 1591 | ||
| 1627 | if (token_tags[after_last_param_token] != .comma) { | 1592 | if (tree.tokenTag(after_last_param_token) != .comma) { |
| 1628 | // Render all on one line, no trailing comma. | 1593 | // Render all on one line, no trailing comma. |
| 1629 | try renderToken(r, builtin_token + 1, .none); // ( | 1594 | try renderToken(r, builtin_token + 1, .none); // ( |
| 1630 | 1595 | ||
| 1631 | for (params, 0..) |param_node, i| { | 1596 | for (params, 0..) |param_node, i| { |
| 1632 | const first_param_token = tree.firstToken(param_node); | 1597 | const first_param_token = tree.firstToken(param_node); |
| 1633 | if (token_tags[first_param_token] == .multiline_string_literal_line or | 1598 | if (tree.tokenTag(first_param_token) == .multiline_string_literal_line or |
| 1634 | hasSameLineComment(tree, first_param_token - 1)) | 1599 | hasSameLineComment(tree, first_param_token - 1)) |
| 1635 | { | 1600 | { |
| 1636 | try ais.pushIndent(.normal); | 1601 | try ais.pushIndent(.normal); |
| ... | @@ -1665,11 +1630,9 @@ fn renderBuiltinCall( | ... | @@ -1665,11 +1630,9 @@ fn renderBuiltinCall( |
| 1665 | fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!void { | 1630 | fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!void { |
| 1666 | const tree = r.tree; | 1631 | const tree = r.tree; |
| 1667 | const ais = r.ais; | 1632 | const ais = r.ais; |
| 1668 | const token_tags = tree.tokens.items(.tag); | ||
| 1669 | const token_starts = tree.tokens.items(.start); | ||
| 1670 | 1633 | ||
| 1671 | const after_fn_token = fn_proto.ast.fn_token + 1; | 1634 | const after_fn_token = fn_proto.ast.fn_token + 1; |
| 1672 | const lparen = if (token_tags[after_fn_token] == .identifier) blk: { | 1635 | const lparen = if (tree.tokenTag(after_fn_token) == .identifier) blk: { |
| 1673 | try renderToken(r, fn_proto.ast.fn_token, .space); // fn | 1636 | try renderToken(r, fn_proto.ast.fn_token, .space); // fn |
| 1674 | try renderIdentifier(r, after_fn_token, .none, .preserve_when_shadowing); // name | 1637 | try renderIdentifier(r, after_fn_token, .none, .preserve_when_shadowing); // name |
| 1675 | break :blk after_fn_token + 1; | 1638 | break :blk after_fn_token + 1; |
| ... | @@ -1677,41 +1640,42 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi | ... | @@ -1677,41 +1640,42 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi |
| 1677 | try renderToken(r, fn_proto.ast.fn_token, .space); // fn | 1640 | try renderToken(r, fn_proto.ast.fn_token, .space); // fn |
| 1678 | break :blk fn_proto.ast.fn_token + 1; | 1641 | break :blk fn_proto.ast.fn_token + 1; |
| 1679 | }; | 1642 | }; |
| 1680 | assert(token_tags[lparen] == .l_paren); | 1643 | assert(tree.tokenTag(lparen) == .l_paren); |
| 1681 | 1644 | ||
| 1682 | const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1; | 1645 | const return_type = fn_proto.ast.return_type.unwrap().?; |
| 1646 | const maybe_bang = tree.firstToken(return_type) - 1; | ||
| 1683 | const rparen = blk: { | 1647 | const rparen = blk: { |
| 1684 | // These may appear in any order, so we have to check the token_starts array | 1648 | // These may appear in any order, so we have to check the token_starts array |
| 1685 | // to find out which is first. | 1649 | // to find out which is first. |
| 1686 | var rparen = if (token_tags[maybe_bang] == .bang) maybe_bang - 1 else maybe_bang; | 1650 | var rparen = if (tree.tokenTag(maybe_bang) == .bang) maybe_bang - 1 else maybe_bang; |
| 1687 | var smallest_start = token_starts[maybe_bang]; | 1651 | var smallest_start = tree.tokenStart(maybe_bang); |
| 1688 | if (fn_proto.ast.align_expr != 0) { | 1652 | if (fn_proto.ast.align_expr.unwrap()) |align_expr| { |
| 1689 | const tok = tree.firstToken(fn_proto.ast.align_expr) - 3; | 1653 | const tok = tree.firstToken(align_expr) - 3; |
| 1690 | const start = token_starts[tok]; | 1654 | const start = tree.tokenStart(tok); |
| 1691 | if (start < smallest_start) { | 1655 | if (start < smallest_start) { |
| 1692 | rparen = tok; | 1656 | rparen = tok; |
| 1693 | smallest_start = start; | 1657 | smallest_start = start; |
| 1694 | } | 1658 | } |
| 1695 | } | 1659 | } |
| 1696 | if (fn_proto.ast.addrspace_expr != 0) { | 1660 | if (fn_proto.ast.addrspace_expr.unwrap()) |addrspace_expr| { |
| 1697 | const tok = tree.firstToken(fn_proto.ast.addrspace_expr) - 3; | 1661 | const tok = tree.firstToken(addrspace_expr) - 3; |
| 1698 | const start = token_starts[tok]; | 1662 | const start = tree.tokenStart(tok); |
| 1699 | if (start < smallest_start) { | 1663 | if (start < smallest_start) { |
| 1700 | rparen = tok; | 1664 | rparen = tok; |
| 1701 | smallest_start = start; | 1665 | smallest_start = start; |
| 1702 | } | 1666 | } |
| 1703 | } | 1667 | } |
| 1704 | if (fn_proto.ast.section_expr != 0) { | 1668 | if (fn_proto.ast.section_expr.unwrap()) |section_expr| { |
| 1705 | const tok = tree.firstToken(fn_proto.ast.section_expr) - 3; | 1669 | const tok = tree.firstToken(section_expr) - 3; |
| 1706 | const start = token_starts[tok]; | 1670 | const start = tree.tokenStart(tok); |
| 1707 | if (start < smallest_start) { | 1671 | if (start < smallest_start) { |
| 1708 | rparen = tok; | 1672 | rparen = tok; |
| 1709 | smallest_start = start; | 1673 | smallest_start = start; |
| 1710 | } | 1674 | } |
| 1711 | } | 1675 | } |
| 1712 | if (fn_proto.ast.callconv_expr != 0) { | 1676 | if (fn_proto.ast.callconv_expr.unwrap()) |callconv_expr| { |
| 1713 | const tok = tree.firstToken(fn_proto.ast.callconv_expr) - 3; | 1677 | const tok = tree.firstToken(callconv_expr) - 3; |
| 1714 | const start = token_starts[tok]; | 1678 | const start = tree.tokenStart(tok); |
| 1715 | if (start < smallest_start) { | 1679 | if (start < smallest_start) { |
| 1716 | rparen = tok; | 1680 | rparen = tok; |
| 1717 | smallest_start = start; | 1681 | smallest_start = start; |
| ... | @@ -1719,11 +1683,11 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi | ... | @@ -1719,11 +1683,11 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi |
| 1719 | } | 1683 | } |
| 1720 | break :blk rparen; | 1684 | break :blk rparen; |
| 1721 | }; | 1685 | }; |
| 1722 | assert(token_tags[rparen] == .r_paren); | 1686 | assert(tree.tokenTag(rparen) == .r_paren); |
| 1723 | 1687 | ||
| 1724 | // The params list is a sparse set that does *not* include anytype or ... parameters. | 1688 | // The params list is a sparse set that does *not* include anytype or ... parameters. |
| 1725 | 1689 | ||
| 1726 | const trailing_comma = token_tags[rparen - 1] == .comma; | 1690 | const trailing_comma = tree.tokenTag(rparen - 1) == .comma; |
| 1727 | if (!trailing_comma and !hasComment(tree, lparen, rparen)) { | 1691 | if (!trailing_comma and !hasComment(tree, lparen, rparen)) { |
| 1728 | // Render all on one line, no trailing comma. | 1692 | // Render all on one line, no trailing comma. |
| 1729 | try renderToken(r, lparen, .none); // ( | 1693 | try renderToken(r, lparen, .none); // ( |
| ... | @@ -1732,7 +1696,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi | ... | @@ -1732,7 +1696,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi |
| 1732 | var last_param_token = lparen; | 1696 | var last_param_token = lparen; |
| 1733 | while (true) { | 1697 | while (true) { |
| 1734 | last_param_token += 1; | 1698 | last_param_token += 1; |
| 1735 | switch (token_tags[last_param_token]) { | 1699 | switch (tree.tokenTag(last_param_token)) { |
| 1736 | .doc_comment => { | 1700 | .doc_comment => { |
| 1737 | try renderToken(r, last_param_token, .newline); | 1701 | try renderToken(r, last_param_token, .newline); |
| 1738 | continue; | 1702 | continue; |
| ... | @@ -1757,15 +1721,15 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi | ... | @@ -1757,15 +1721,15 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi |
| 1757 | }, | 1721 | }, |
| 1758 | else => {}, // Parameter type without a name. | 1722 | else => {}, // Parameter type without a name. |
| 1759 | } | 1723 | } |
| 1760 | if (token_tags[last_param_token] == .identifier and | 1724 | if (tree.tokenTag(last_param_token) == .identifier and |
| 1761 | token_tags[last_param_token + 1] == .colon) | 1725 | tree.tokenTag(last_param_token + 1) == .colon) |
| 1762 | { | 1726 | { |
| 1763 | try renderIdentifier(r, last_param_token, .none, .preserve_when_shadowing); // name | 1727 | try renderIdentifier(r, last_param_token, .none, .preserve_when_shadowing); // name |
| 1764 | last_param_token += 1; | 1728 | last_param_token = last_param_token + 1; |
| 1765 | try renderToken(r, last_param_token, .space); // : | 1729 | try renderToken(r, last_param_token, .space); // : |
| 1766 | last_param_token += 1; | 1730 | last_param_token += 1; |
| 1767 | } | 1731 | } |
| 1768 | if (token_tags[last_param_token] == .keyword_anytype) { | 1732 | if (tree.tokenTag(last_param_token) == .keyword_anytype) { |
| 1769 | try renderToken(r, last_param_token, .none); // anytype | 1733 | try renderToken(r, last_param_token, .none); // anytype |
| 1770 | continue; | 1734 | continue; |
| 1771 | } | 1735 | } |
| ... | @@ -1783,7 +1747,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi | ... | @@ -1783,7 +1747,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi |
| 1783 | var last_param_token = lparen; | 1747 | var last_param_token = lparen; |
| 1784 | while (true) { | 1748 | while (true) { |
| 1785 | last_param_token += 1; | 1749 | last_param_token += 1; |
| 1786 | switch (token_tags[last_param_token]) { | 1750 | switch (tree.tokenTag(last_param_token)) { |
| 1787 | .doc_comment => { | 1751 | .doc_comment => { |
| 1788 | try renderToken(r, last_param_token, .newline); | 1752 | try renderToken(r, last_param_token, .newline); |
| 1789 | continue; | 1753 | continue; |
| ... | @@ -1799,24 +1763,24 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi | ... | @@ -1799,24 +1763,24 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi |
| 1799 | .identifier => {}, | 1763 | .identifier => {}, |
| 1800 | .keyword_anytype => { | 1764 | .keyword_anytype => { |
| 1801 | try renderToken(r, last_param_token, .comma); // anytype | 1765 | try renderToken(r, last_param_token, .comma); // anytype |
| 1802 | if (token_tags[last_param_token + 1] == .comma) | 1766 | if (tree.tokenTag(last_param_token + 1) == .comma) |
| 1803 | last_param_token += 1; | 1767 | last_param_token += 1; |
| 1804 | continue; | 1768 | continue; |
| 1805 | }, | 1769 | }, |
| 1806 | .r_paren => break, | 1770 | .r_paren => break, |
| 1807 | else => {}, // Parameter type without a name. | 1771 | else => {}, // Parameter type without a name. |
| 1808 | } | 1772 | } |
| 1809 | if (token_tags[last_param_token] == .identifier and | 1773 | if (tree.tokenTag(last_param_token) == .identifier and |
| 1810 | token_tags[last_param_token + 1] == .colon) | 1774 | tree.tokenTag(last_param_token + 1) == .colon) |
| 1811 | { | 1775 | { |
| 1812 | try renderIdentifier(r, last_param_token, .none, .preserve_when_shadowing); // name | 1776 | try renderIdentifier(r, last_param_token, .none, .preserve_when_shadowing); // name |
| 1813 | last_param_token += 1; | 1777 | last_param_token += 1; |
| 1814 | try renderToken(r, last_param_token, .space); // : | 1778 | try renderToken(r, last_param_token, .space); // : |
| 1815 | last_param_token += 1; | 1779 | last_param_token += 1; |
| 1816 | } | 1780 | } |
| 1817 | if (token_tags[last_param_token] == .keyword_anytype) { | 1781 | if (tree.tokenTag(last_param_token) == .keyword_anytype) { |
| 1818 | try renderToken(r, last_param_token, .comma); // anytype | 1782 | try renderToken(r, last_param_token, .comma); // anytype |
| 1819 | if (token_tags[last_param_token + 1] == .comma) | 1783 | if (tree.tokenTag(last_param_token + 1) == .comma) |
| 1820 | last_param_token += 1; | 1784 | last_param_token += 1; |
| 1821 | continue; | 1785 | continue; |
| 1822 | } | 1786 | } |
| ... | @@ -1826,60 +1790,62 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi | ... | @@ -1826,60 +1790,62 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi |
| 1826 | try renderExpression(r, param, .comma); | 1790 | try renderExpression(r, param, .comma); |
| 1827 | ais.popSpace(); | 1791 | ais.popSpace(); |
| 1828 | last_param_token = tree.lastToken(param); | 1792 | last_param_token = tree.lastToken(param); |
| 1829 | if (token_tags[last_param_token + 1] == .comma) last_param_token += 1; | 1793 | if (tree.tokenTag(last_param_token + 1) == .comma) last_param_token += 1; |
| 1830 | } | 1794 | } |
| 1831 | ais.popIndent(); | 1795 | ais.popIndent(); |
| 1832 | } | 1796 | } |
| 1833 | 1797 | ||
| 1834 | try renderToken(r, rparen, .space); // ) | 1798 | try renderToken(r, rparen, .space); // ) |
| 1835 | 1799 | ||
| 1836 | if (fn_proto.ast.align_expr != 0) { | 1800 | if (fn_proto.ast.align_expr.unwrap()) |align_expr| { |
| 1837 | const align_lparen = tree.firstToken(fn_proto.ast.align_expr) - 1; | 1801 | const align_lparen = tree.firstToken(align_expr) - 1; |
| 1838 | const align_rparen = tree.lastToken(fn_proto.ast.align_expr) + 1; | 1802 | const align_rparen = tree.lastToken(align_expr) + 1; |
| 1839 | 1803 | ||
| 1840 | try renderToken(r, align_lparen - 1, .none); // align | 1804 | try renderToken(r, align_lparen - 1, .none); // align |
| 1841 | try renderToken(r, align_lparen, .none); // ( | 1805 | try renderToken(r, align_lparen, .none); // ( |
| 1842 | try renderExpression(r, fn_proto.ast.align_expr, .none); | 1806 | try renderExpression(r, align_expr, .none); |
| 1843 | try renderToken(r, align_rparen, .space); // ) | 1807 | try renderToken(r, align_rparen, .space); // ) |
| 1844 | } | 1808 | } |
| 1845 | 1809 | ||
| 1846 | if (fn_proto.ast.addrspace_expr != 0) { | 1810 | if (fn_proto.ast.addrspace_expr.unwrap()) |addrspace_expr| { |
| 1847 | const align_lparen = tree.firstToken(fn_proto.ast.addrspace_expr) - 1; | 1811 | const align_lparen = tree.firstToken(addrspace_expr) - 1; |
| 1848 | const align_rparen = tree.lastToken(fn_proto.ast.addrspace_expr) + 1; | 1812 | const align_rparen = tree.lastToken(addrspace_expr) + 1; |
| 1849 | 1813 | ||
| 1850 | try renderToken(r, align_lparen - 1, .none); // addrspace | 1814 | try renderToken(r, align_lparen - 1, .none); // addrspace |
| 1851 | try renderToken(r, align_lparen, .none); // ( | 1815 | try renderToken(r, align_lparen, .none); // ( |
| 1852 | try renderExpression(r, fn_proto.ast.addrspace_expr, .none); | 1816 | try renderExpression(r, addrspace_expr, .none); |
| 1853 | try renderToken(r, align_rparen, .space); // ) | 1817 | try renderToken(r, align_rparen, .space); // ) |
| 1854 | } | 1818 | } |
| 1855 | 1819 | ||
| 1856 | if (fn_proto.ast.section_expr != 0) { | 1820 | if (fn_proto.ast.section_expr.unwrap()) |section_expr| { |
| 1857 | const section_lparen = tree.firstToken(fn_proto.ast.section_expr) - 1; | 1821 | const section_lparen = tree.firstToken(section_expr) - 1; |
| 1858 | const section_rparen = tree.lastToken(fn_proto.ast.section_expr) + 1; | 1822 | const section_rparen = tree.lastToken(section_expr) + 1; |
| 1859 | 1823 | ||
| 1860 | try renderToken(r, section_lparen - 1, .none); // section | 1824 | try renderToken(r, section_lparen - 1, .none); // section |
| 1861 | try renderToken(r, section_lparen, .none); // ( | 1825 | try renderToken(r, section_lparen, .none); // ( |
| 1862 | try renderExpression(r, fn_proto.ast.section_expr, .none); | 1826 | try renderExpression(r, section_expr, .none); |
| 1863 | try renderToken(r, section_rparen, .space); // ) | 1827 | try renderToken(r, section_rparen, .space); // ) |
| 1864 | } | 1828 | } |
| 1865 | 1829 | ||
| 1866 | // Keep in sync with logic in `renderMember`. Search this file for the marker PROMOTE_CALLCONV_INLINE | 1830 | if (fn_proto.ast.callconv_expr.unwrap()) |callconv_expr| { |
| 1867 | const is_callconv_inline = mem.eql(u8, "@\"inline\"", tree.tokenSlice(tree.nodes.items(.main_token)[fn_proto.ast.callconv_expr])); | 1831 | // Keep in sync with logic in `renderMember`. Search this file for the marker PROMOTE_CALLCONV_INLINE |
| 1868 | const is_declaration = fn_proto.name_token != null; | 1832 | const is_callconv_inline = mem.eql(u8, "@\"inline\"", tree.tokenSlice(tree.nodeMainToken(callconv_expr))); |
| 1869 | if (fn_proto.ast.callconv_expr != 0 and !(is_declaration and is_callconv_inline)) { | 1833 | const is_declaration = fn_proto.name_token != null; |
| 1870 | const callconv_lparen = tree.firstToken(fn_proto.ast.callconv_expr) - 1; | 1834 | if (!(is_declaration and is_callconv_inline)) { |
| 1871 | const callconv_rparen = tree.lastToken(fn_proto.ast.callconv_expr) + 1; | 1835 | const callconv_lparen = tree.firstToken(callconv_expr) - 1; |
| 1836 | const callconv_rparen = tree.lastToken(callconv_expr) + 1; | ||
| 1872 | 1837 | ||
| 1873 | try renderToken(r, callconv_lparen - 1, .none); // callconv | 1838 | try renderToken(r, callconv_lparen - 1, .none); // callconv |
| 1874 | try renderToken(r, callconv_lparen, .none); // ( | 1839 | try renderToken(r, callconv_lparen, .none); // ( |
| 1875 | try renderExpression(r, fn_proto.ast.callconv_expr, .none); | 1840 | try renderExpression(r, callconv_expr, .none); |
| 1876 | try renderToken(r, callconv_rparen, .space); // ) | 1841 | try renderToken(r, callconv_rparen, .space); // ) |
| 1842 | } | ||
| 1877 | } | 1843 | } |
| 1878 | 1844 | ||
| 1879 | if (token_tags[maybe_bang] == .bang) { | 1845 | if (tree.tokenTag(maybe_bang) == .bang) { |
| 1880 | try renderToken(r, maybe_bang, .none); // ! | 1846 | try renderToken(r, maybe_bang, .none); // ! |
| 1881 | } | 1847 | } |
| 1882 | return renderExpression(r, fn_proto.ast.return_type, space); | 1848 | return renderExpression(r, return_type, space); |
| 1883 | } | 1849 | } |
| 1884 | 1850 | ||
| 1885 | fn renderSwitchCase( | 1851 | fn renderSwitchCase( |
| ... | @@ -1889,9 +1855,7 @@ fn renderSwitchCase( | ... | @@ -1889,9 +1855,7 @@ fn renderSwitchCase( |
| 1889 | ) Error!void { | 1855 | ) Error!void { |
| 1890 | const ais = r.ais; | 1856 | const ais = r.ais; |
| 1891 | const tree = r.tree; | 1857 | const tree = r.tree; |
| 1892 | const node_tags = tree.nodes.items(.tag); | 1858 | const trailing_comma = tree.tokenTag(switch_case.ast.arrow_token - 1) == .comma; |
| 1893 | const token_tags = tree.tokens.items(.tag); | ||
| 1894 | const trailing_comma = token_tags[switch_case.ast.arrow_token - 1] == .comma; | ||
| 1895 | const has_comment_before_arrow = blk: { | 1859 | const has_comment_before_arrow = blk: { |
| 1896 | if (switch_case.ast.values.len == 0) break :blk false; | 1860 | if (switch_case.ast.values.len == 0) break :blk false; |
| 1897 | break :blk hasComment(tree, tree.firstToken(switch_case.ast.values[0]), switch_case.ast.arrow_token); | 1861 | break :blk hasComment(tree, tree.firstToken(switch_case.ast.values[0]), switch_case.ast.arrow_token); |
| ... | @@ -1918,7 +1882,7 @@ fn renderSwitchCase( | ... | @@ -1918,7 +1882,7 @@ fn renderSwitchCase( |
| 1918 | } | 1882 | } |
| 1919 | 1883 | ||
| 1920 | // Render the arrow and everything after it | 1884 | // Render the arrow and everything after it |
| 1921 | const pre_target_space = if (node_tags[switch_case.ast.target_expr] == .multiline_string_literal) | 1885 | const pre_target_space = if (tree.nodeTag(switch_case.ast.target_expr) == .multiline_string_literal) |
| 1922 | // Newline gets inserted when rendering the target expr. | 1886 | // Newline gets inserted when rendering the target expr. |
| 1923 | Space.none | 1887 | Space.none |
| 1924 | else | 1888 | else |
| ... | @@ -1928,12 +1892,12 @@ fn renderSwitchCase( | ... | @@ -1928,12 +1892,12 @@ fn renderSwitchCase( |
| 1928 | 1892 | ||
| 1929 | if (switch_case.payload_token) |payload_token| { | 1893 | if (switch_case.payload_token) |payload_token| { |
| 1930 | try renderToken(r, payload_token - 1, .none); // pipe | 1894 | try renderToken(r, payload_token - 1, .none); // pipe |
| 1931 | const ident = payload_token + @intFromBool(token_tags[payload_token] == .asterisk); | 1895 | const ident = payload_token + @intFromBool(tree.tokenTag(payload_token) == .asterisk); |
| 1932 | if (token_tags[payload_token] == .asterisk) { | 1896 | if (tree.tokenTag(payload_token) == .asterisk) { |
| 1933 | try renderToken(r, payload_token, .none); // asterisk | 1897 | try renderToken(r, payload_token, .none); // asterisk |
| 1934 | } | 1898 | } |
| 1935 | try renderIdentifier(r, ident, .none, .preserve_when_shadowing); // identifier | 1899 | try renderIdentifier(r, ident, .none, .preserve_when_shadowing); // identifier |
| 1936 | if (token_tags[ident + 1] == .comma) { | 1900 | if (tree.tokenTag(ident + 1) == .comma) { |
| 1937 | try renderToken(r, ident + 1, .space); // , | 1901 | try renderToken(r, ident + 1, .space); // , |
| 1938 | try renderIdentifier(r, ident + 2, .none, .preserve_when_shadowing); // identifier | 1902 | try renderIdentifier(r, ident + 2, .none, .preserve_when_shadowing); // identifier |
| 1939 | try renderToken(r, ident + 3, pre_target_space); // pipe | 1903 | try renderToken(r, ident + 3, pre_target_space); // pipe |
| ... | @@ -1953,12 +1917,9 @@ fn renderBlock( | ... | @@ -1953,12 +1917,9 @@ fn renderBlock( |
| 1953 | ) Error!void { | 1917 | ) Error!void { |
| 1954 | const tree = r.tree; | 1918 | const tree = r.tree; |
| 1955 | const ais = r.ais; | 1919 | const ais = r.ais; |
| 1956 | const token_tags = tree.tokens.items(.tag); | 1920 | const lbrace = tree.nodeMainToken(block_node); |
| 1957 | const lbrace = tree.nodes.items(.main_token)[block_node]; | ||
| 1958 | 1921 | ||
| 1959 | if (token_tags[lbrace - 1] == .colon and | 1922 | if (tree.isTokenPrecededByTags(lbrace, &.{ .identifier, .colon })) { |
| 1960 | token_tags[lbrace - 2] == .identifier) | ||
| 1961 | { | ||
| 1962 | try renderIdentifier(r, lbrace - 2, .none, .eagerly_unquote); // identifier | 1923 | try renderIdentifier(r, lbrace - 2, .none, .eagerly_unquote); // identifier |
| 1963 | try renderToken(r, lbrace - 1, .space); // : | 1924 | try renderToken(r, lbrace - 1, .space); // : |
| 1964 | } | 1925 | } |
| ... | @@ -1980,13 +1941,12 @@ fn finishRenderBlock( | ... | @@ -1980,13 +1941,12 @@ fn finishRenderBlock( |
| 1980 | space: Space, | 1941 | space: Space, |
| 1981 | ) Error!void { | 1942 | ) Error!void { |
| 1982 | const tree = r.tree; | 1943 | const tree = r.tree; |
| 1983 | const node_tags = tree.nodes.items(.tag); | ||
| 1984 | const ais = r.ais; | 1944 | const ais = r.ais; |
| 1985 | for (statements, 0..) |stmt, i| { | 1945 | for (statements, 0..) |stmt, i| { |
| 1986 | if (i != 0) try renderExtraNewline(r, stmt); | 1946 | if (i != 0) try renderExtraNewline(r, stmt); |
| 1987 | if (r.fixups.omit_nodes.contains(stmt)) continue; | 1947 | if (r.fixups.omit_nodes.contains(stmt)) continue; |
| 1988 | try ais.pushSpace(.semicolon); | 1948 | try ais.pushSpace(.semicolon); |
| 1989 | switch (node_tags[stmt]) { | 1949 | switch (tree.nodeTag(stmt)) { |
| 1990 | .global_var_decl, | 1950 | .global_var_decl, |
| 1991 | .local_var_decl, | 1951 | .local_var_decl, |
| 1992 | .simple_var_decl, | 1952 | .simple_var_decl, |
| ... | @@ -2010,12 +1970,13 @@ fn renderStructInit( | ... | @@ -2010,12 +1970,13 @@ fn renderStructInit( |
| 2010 | ) Error!void { | 1970 | ) Error!void { |
| 2011 | const tree = r.tree; | 1971 | const tree = r.tree; |
| 2012 | const ais = r.ais; | 1972 | const ais = r.ais; |
| 2013 | const token_tags = tree.tokens.items(.tag); | 1973 | |
| 2014 | if (struct_init.ast.type_expr == 0) { | 1974 | if (struct_init.ast.type_expr.unwrap()) |type_expr| { |
| 2015 | try renderToken(r, struct_init.ast.lbrace - 1, .none); // . | 1975 | try renderExpression(r, type_expr, .none); // T |
| 2016 | } else { | 1976 | } else { |
| 2017 | try renderExpression(r, struct_init.ast.type_expr, .none); // T | 1977 | try renderToken(r, struct_init.ast.lbrace - 1, .none); // . |
| 2018 | } | 1978 | } |
| 1979 | |||
| 2019 | if (struct_init.ast.fields.len == 0) { | 1980 | if (struct_init.ast.fields.len == 0) { |
| 2020 | try ais.pushIndent(.normal); | 1981 | try ais.pushIndent(.normal); |
| 2021 | try renderToken(r, struct_init.ast.lbrace, .none); // lbrace | 1982 | try renderToken(r, struct_init.ast.lbrace, .none); // lbrace |
| ... | @@ -2024,7 +1985,7 @@ fn renderStructInit( | ... | @@ -2024,7 +1985,7 @@ fn renderStructInit( |
| 2024 | } | 1985 | } |
| 2025 | 1986 | ||
| 2026 | const rbrace = tree.lastToken(struct_node); | 1987 | const rbrace = tree.lastToken(struct_node); |
| 2027 | const trailing_comma = token_tags[rbrace - 1] == .comma; | 1988 | const trailing_comma = tree.tokenTag(rbrace - 1) == .comma; |
| 2028 | if (trailing_comma or hasComment(tree, struct_init.ast.lbrace, rbrace)) { | 1989 | if (trailing_comma or hasComment(tree, struct_init.ast.lbrace, rbrace)) { |
| 2029 | // Render one field init per line. | 1990 | // Render one field init per line. |
| 2030 | try ais.pushIndent(.normal); | 1991 | try ais.pushIndent(.normal); |
| ... | @@ -2034,9 +1995,8 @@ fn renderStructInit( | ... | @@ -2034,9 +1995,8 @@ fn renderStructInit( |
| 2034 | try renderIdentifier(r, struct_init.ast.lbrace + 2, .space, .eagerly_unquote); // name | 1995 | try renderIdentifier(r, struct_init.ast.lbrace + 2, .space, .eagerly_unquote); // name |
| 2035 | // Don't output a space after the = if expression is a multiline string, | 1996 | // Don't output a space after the = if expression is a multiline string, |
| 2036 | // since then it will start on the next line. | 1997 | // since then it will start on the next line. |
| 2037 | const nodes = tree.nodes.items(.tag); | ||
| 2038 | const field_node = struct_init.ast.fields[0]; | 1998 | const field_node = struct_init.ast.fields[0]; |
| 2039 | const expr = nodes[field_node]; | 1999 | const expr = tree.nodeTag(field_node); |
| 2040 | var space_after_equal: Space = if (expr == .multiline_string_literal) .none else .space; | 2000 | var space_after_equal: Space = if (expr == .multiline_string_literal) .none else .space; |
| 2041 | try renderToken(r, struct_init.ast.lbrace + 3, space_after_equal); // = | 2001 | try renderToken(r, struct_init.ast.lbrace + 3, space_after_equal); // = |
| 2042 | 2002 | ||
| ... | @@ -2049,7 +2009,7 @@ fn renderStructInit( | ... | @@ -2049,7 +2009,7 @@ fn renderStructInit( |
| 2049 | try renderExtraNewlineToken(r, init_token - 3); | 2009 | try renderExtraNewlineToken(r, init_token - 3); |
| 2050 | try renderToken(r, init_token - 3, .none); // . | 2010 | try renderToken(r, init_token - 3, .none); // . |
| 2051 | try renderIdentifier(r, init_token - 2, .space, .eagerly_unquote); // name | 2011 | try renderIdentifier(r, init_token - 2, .space, .eagerly_unquote); // name |
| 2052 | space_after_equal = if (nodes[field_init] == .multiline_string_literal) .none else .space; | 2012 | space_after_equal = if (tree.nodeTag(field_init) == .multiline_string_literal) .none else .space; |
| 2053 | try renderToken(r, init_token - 1, space_after_equal); // = | 2013 | try renderToken(r, init_token - 1, space_after_equal); // = |
| 2054 | 2014 | ||
| 2055 | try ais.pushSpace(.comma); | 2015 | try ais.pushSpace(.comma); |
| ... | @@ -2082,12 +2042,11 @@ fn renderArrayInit( | ... | @@ -2082,12 +2042,11 @@ fn renderArrayInit( |
| 2082 | const tree = r.tree; | 2042 | const tree = r.tree; |
| 2083 | const ais = r.ais; | 2043 | const ais = r.ais; |
| 2084 | const gpa = r.gpa; | 2044 | const gpa = r.gpa; |
| 2085 | const token_tags = tree.tokens.items(.tag); | ||
| 2086 | 2045 | ||
| 2087 | if (array_init.ast.type_expr == 0) { | 2046 | if (array_init.ast.type_expr.unwrap()) |type_expr| { |
| 2088 | try renderToken(r, array_init.ast.lbrace - 1, .none); // . | 2047 | try renderExpression(r, type_expr, .none); // T |
| 2089 | } else { | 2048 | } else { |
| 2090 | try renderExpression(r, array_init.ast.type_expr, .none); // T | 2049 | try renderToken(r, array_init.ast.lbrace - 1, .none); // . |
| 2091 | } | 2050 | } |
| 2092 | 2051 | ||
| 2093 | if (array_init.ast.elements.len == 0) { | 2052 | if (array_init.ast.elements.len == 0) { |
| ... | @@ -2099,14 +2058,14 @@ fn renderArrayInit( | ... | @@ -2099,14 +2058,14 @@ fn renderArrayInit( |
| 2099 | 2058 | ||
| 2100 | const last_elem = array_init.ast.elements[array_init.ast.elements.len - 1]; | 2059 | const last_elem = array_init.ast.elements[array_init.ast.elements.len - 1]; |
| 2101 | const last_elem_token = tree.lastToken(last_elem); | 2060 | const last_elem_token = tree.lastToken(last_elem); |
| 2102 | const trailing_comma = token_tags[last_elem_token + 1] == .comma; | 2061 | const trailing_comma = tree.tokenTag(last_elem_token + 1) == .comma; |
| 2103 | const rbrace = if (trailing_comma) last_elem_token + 2 else last_elem_token + 1; | 2062 | const rbrace = if (trailing_comma) last_elem_token + 2 else last_elem_token + 1; |
| 2104 | assert(token_tags[rbrace] == .r_brace); | 2063 | assert(tree.tokenTag(rbrace) == .r_brace); |
| 2105 | 2064 | ||
| 2106 | if (array_init.ast.elements.len == 1) { | 2065 | if (array_init.ast.elements.len == 1) { |
| 2107 | const only_elem = array_init.ast.elements[0]; | 2066 | const only_elem = array_init.ast.elements[0]; |
| 2108 | const first_token = tree.firstToken(only_elem); | 2067 | const first_token = tree.firstToken(only_elem); |
| 2109 | if (token_tags[first_token] != .multiline_string_literal_line and | 2068 | if (tree.tokenTag(first_token) != .multiline_string_literal_line and |
| 2110 | !anythingBetween(tree, last_elem_token, rbrace)) | 2069 | !anythingBetween(tree, last_elem_token, rbrace)) |
| 2111 | { | 2070 | { |
| 2112 | try renderToken(r, array_init.ast.lbrace, .none); | 2071 | try renderToken(r, array_init.ast.lbrace, .none); |
| ... | @@ -2169,7 +2128,7 @@ fn renderArrayInit( | ... | @@ -2169,7 +2128,7 @@ fn renderArrayInit( |
| 2169 | } | 2128 | } |
| 2170 | 2129 | ||
| 2171 | const maybe_comma = expr_last_token + 1; | 2130 | const maybe_comma = expr_last_token + 1; |
| 2172 | if (token_tags[maybe_comma] == .comma) { | 2131 | if (tree.tokenTag(maybe_comma) == .comma) { |
| 2173 | if (hasSameLineComment(tree, maybe_comma)) | 2132 | if (hasSameLineComment(tree, maybe_comma)) |
| 2174 | break :sec_end i - this_line_size + 1; | 2133 | break :sec_end i - this_line_size + 1; |
| 2175 | } | 2134 | } |
| ... | @@ -2309,13 +2268,12 @@ fn renderContainerDecl( | ... | @@ -2309,13 +2268,12 @@ fn renderContainerDecl( |
| 2309 | ) Error!void { | 2268 | ) Error!void { |
| 2310 | const tree = r.tree; | 2269 | const tree = r.tree; |
| 2311 | const ais = r.ais; | 2270 | const ais = r.ais; |
| 2312 | const token_tags = tree.tokens.items(.tag); | ||
| 2313 | 2271 | ||
| 2314 | if (container_decl.layout_token) |layout_token| { | 2272 | if (container_decl.layout_token) |layout_token| { |
| 2315 | try renderToken(r, layout_token, .space); | 2273 | try renderToken(r, layout_token, .space); |
| 2316 | } | 2274 | } |
| 2317 | 2275 | ||
| 2318 | const container: Container = switch (token_tags[container_decl.ast.main_token]) { | 2276 | const container: Container = switch (tree.tokenTag(container_decl.ast.main_token)) { |
| 2319 | .keyword_enum => .@"enum", | 2277 | .keyword_enum => .@"enum", |
| 2320 | .keyword_struct => for (container_decl.ast.members) |member| { | 2278 | .keyword_struct => for (container_decl.ast.members) |member| { |
| 2321 | if (tree.fullContainerField(member)) |field| if (!field.ast.tuple_like) break .other; | 2279 | if (tree.fullContainerField(member)) |field| if (!field.ast.tuple_like) break .other; |
| ... | @@ -2328,10 +2286,10 @@ fn renderContainerDecl( | ... | @@ -2328,10 +2286,10 @@ fn renderContainerDecl( |
| 2328 | try renderToken(r, container_decl.ast.main_token, .none); // union | 2286 | try renderToken(r, container_decl.ast.main_token, .none); // union |
| 2329 | try renderToken(r, enum_token - 1, .none); // lparen | 2287 | try renderToken(r, enum_token - 1, .none); // lparen |
| 2330 | try renderToken(r, enum_token, .none); // enum | 2288 | try renderToken(r, enum_token, .none); // enum |
| 2331 | if (container_decl.ast.arg != 0) { | 2289 | if (container_decl.ast.arg.unwrap()) |arg| { |
| 2332 | try renderToken(r, enum_token + 1, .none); // lparen | 2290 | try renderToken(r, enum_token + 1, .none); // lparen |
| 2333 | try renderExpression(r, container_decl.ast.arg, .none); | 2291 | try renderExpression(r, arg, .none); |
| 2334 | const rparen = tree.lastToken(container_decl.ast.arg) + 1; | 2292 | const rparen = tree.lastToken(arg) + 1; |
| 2335 | try renderToken(r, rparen, .none); // rparen | 2293 | try renderToken(r, rparen, .none); // rparen |
| 2336 | try renderToken(r, rparen + 1, .space); // rparen | 2294 | try renderToken(r, rparen + 1, .space); // rparen |
| 2337 | lbrace = rparen + 2; | 2295 | lbrace = rparen + 2; |
| ... | @@ -2339,11 +2297,11 @@ fn renderContainerDecl( | ... | @@ -2339,11 +2297,11 @@ fn renderContainerDecl( |
| 2339 | try renderToken(r, enum_token + 1, .space); // rparen | 2297 | try renderToken(r, enum_token + 1, .space); // rparen |
| 2340 | lbrace = enum_token + 2; | 2298 | lbrace = enum_token + 2; |
| 2341 | } | 2299 | } |
| 2342 | } else if (container_decl.ast.arg != 0) { | 2300 | } else if (container_decl.ast.arg.unwrap()) |arg| { |
| 2343 | try renderToken(r, container_decl.ast.main_token, .none); // union | 2301 | try renderToken(r, container_decl.ast.main_token, .none); // union |
| 2344 | try renderToken(r, container_decl.ast.main_token + 1, .none); // lparen | 2302 | try renderToken(r, container_decl.ast.main_token + 1, .none); // lparen |
| 2345 | try renderExpression(r, container_decl.ast.arg, .none); | 2303 | try renderExpression(r, arg, .none); |
| 2346 | const rparen = tree.lastToken(container_decl.ast.arg) + 1; | 2304 | const rparen = tree.lastToken(arg) + 1; |
| 2347 | try renderToken(r, rparen, .space); // rparen | 2305 | try renderToken(r, rparen, .space); // rparen |
| 2348 | lbrace = rparen + 1; | 2306 | lbrace = rparen + 1; |
| 2349 | } else { | 2307 | } else { |
| ... | @@ -2352,9 +2310,10 @@ fn renderContainerDecl( | ... | @@ -2352,9 +2310,10 @@ fn renderContainerDecl( |
| 2352 | } | 2310 | } |
| 2353 | 2311 | ||
| 2354 | const rbrace = tree.lastToken(container_decl_node); | 2312 | const rbrace = tree.lastToken(container_decl_node); |
| 2313 | |||
| 2355 | if (container_decl.ast.members.len == 0) { | 2314 | if (container_decl.ast.members.len == 0) { |
| 2356 | try ais.pushIndent(.normal); | 2315 | try ais.pushIndent(.normal); |
| 2357 | if (token_tags[lbrace + 1] == .container_doc_comment) { | 2316 | if (tree.tokenTag(lbrace + 1) == .container_doc_comment) { |
| 2358 | try renderToken(r, lbrace, .newline); // lbrace | 2317 | try renderToken(r, lbrace, .newline); // lbrace |
| 2359 | try renderContainerDocComments(r, lbrace + 1); | 2318 | try renderContainerDocComments(r, lbrace + 1); |
| 2360 | } else { | 2319 | } else { |
| ... | @@ -2364,7 +2323,7 @@ fn renderContainerDecl( | ... | @@ -2364,7 +2323,7 @@ fn renderContainerDecl( |
| 2364 | return renderToken(r, rbrace, space); // rbrace | 2323 | return renderToken(r, rbrace, space); // rbrace |
| 2365 | } | 2324 | } |
| 2366 | 2325 | ||
| 2367 | const src_has_trailing_comma = token_tags[rbrace - 1] == .comma; | 2326 | const src_has_trailing_comma = tree.tokenTag(rbrace - 1) == .comma; |
| 2368 | if (!src_has_trailing_comma) one_line: { | 2327 | if (!src_has_trailing_comma) one_line: { |
| 2369 | // We print all the members in-line unless one of the following conditions are true: | 2328 | // We print all the members in-line unless one of the following conditions are true: |
| 2370 | 2329 | ||
| ... | @@ -2374,10 +2333,10 @@ fn renderContainerDecl( | ... | @@ -2374,10 +2333,10 @@ fn renderContainerDecl( |
| 2374 | } | 2333 | } |
| 2375 | 2334 | ||
| 2376 | // 2. The container has a container comment. | 2335 | // 2. The container has a container comment. |
| 2377 | if (token_tags[lbrace + 1] == .container_doc_comment) break :one_line; | 2336 | if (tree.tokenTag(lbrace + 1) == .container_doc_comment) break :one_line; |
| 2378 | 2337 | ||
| 2379 | // 3. A member of the container has a doc comment. | 2338 | // 3. A member of the container has a doc comment. |
| 2380 | for (token_tags[lbrace + 1 .. rbrace - 1]) |tag| { | 2339 | for (tree.tokens.items(.tag)[lbrace + 1 .. rbrace - 1]) |tag| { |
| 2381 | if (tag == .doc_comment) break :one_line; | 2340 | if (tag == .doc_comment) break :one_line; |
| 2382 | } | 2341 | } |
| 2383 | 2342 | ||
| ... | @@ -2397,12 +2356,12 @@ fn renderContainerDecl( | ... | @@ -2397,12 +2356,12 @@ fn renderContainerDecl( |
| 2397 | // One member per line. | 2356 | // One member per line. |
| 2398 | try ais.pushIndent(.normal); | 2357 | try ais.pushIndent(.normal); |
| 2399 | try renderToken(r, lbrace, .newline); // lbrace | 2358 | try renderToken(r, lbrace, .newline); // lbrace |
| 2400 | if (token_tags[lbrace + 1] == .container_doc_comment) { | 2359 | if (tree.tokenTag(lbrace + 1) == .container_doc_comment) { |
| 2401 | try renderContainerDocComments(r, lbrace + 1); | 2360 | try renderContainerDocComments(r, lbrace + 1); |
| 2402 | } | 2361 | } |
| 2403 | for (container_decl.ast.members, 0..) |member, i| { | 2362 | for (container_decl.ast.members, 0..) |member, i| { |
| 2404 | if (i != 0) try renderExtraNewline(r, member); | 2363 | if (i != 0) try renderExtraNewline(r, member); |
| 2405 | switch (tree.nodes.items(.tag)[member]) { | 2364 | switch (tree.nodeTag(member)) { |
| 2406 | // For container fields, ensure a trailing comma is added if necessary. | 2365 | // For container fields, ensure a trailing comma is added if necessary. |
| 2407 | .container_field_init, | 2366 | .container_field_init, |
| 2408 | .container_field_align, | 2367 | .container_field_align, |
| ... | @@ -2428,7 +2387,6 @@ fn renderAsm( | ... | @@ -2428,7 +2387,6 @@ fn renderAsm( |
| 2428 | ) Error!void { | 2387 | ) Error!void { |
| 2429 | const tree = r.tree; | 2388 | const tree = r.tree; |
| 2430 | const ais = r.ais; | 2389 | const ais = r.ais; |
| 2431 | const token_tags = tree.tokens.items(.tag); | ||
| 2432 | 2390 | ||
| 2433 | try renderToken(r, asm_node.ast.asm_token, .space); // asm | 2391 | try renderToken(r, asm_node.ast.asm_token, .space); // asm |
| 2434 | 2392 | ||
| ... | @@ -2454,13 +2412,13 @@ fn renderAsm( | ... | @@ -2454,13 +2412,13 @@ fn renderAsm( |
| 2454 | while (true) : (tok_i += 1) { | 2412 | while (true) : (tok_i += 1) { |
| 2455 | try renderToken(r, tok_i, .none); | 2413 | try renderToken(r, tok_i, .none); |
| 2456 | tok_i += 1; | 2414 | tok_i += 1; |
| 2457 | switch (token_tags[tok_i]) { | 2415 | switch (tree.tokenTag(tok_i)) { |
| 2458 | .r_paren => { | 2416 | .r_paren => { |
| 2459 | ais.popIndent(); | 2417 | ais.popIndent(); |
| 2460 | return renderToken(r, tok_i, space); | 2418 | return renderToken(r, tok_i, space); |
| 2461 | }, | 2419 | }, |
| 2462 | .comma => { | 2420 | .comma => { |
| 2463 | if (token_tags[tok_i + 1] == .r_paren) { | 2421 | if (tree.tokenTag(tok_i + 1) == .r_paren) { |
| 2464 | ais.popIndent(); | 2422 | ais.popIndent(); |
| 2465 | return renderToken(r, tok_i + 1, space); | 2423 | return renderToken(r, tok_i + 1, space); |
| 2466 | } else { | 2424 | } else { |
| ... | @@ -2512,7 +2470,7 @@ fn renderAsm( | ... | @@ -2512,7 +2470,7 @@ fn renderAsm( |
| 2512 | ais.popSpace(); | 2470 | ais.popSpace(); |
| 2513 | const comma_or_colon = tree.lastToken(asm_output) + 1; | 2471 | const comma_or_colon = tree.lastToken(asm_output) + 1; |
| 2514 | ais.popIndent(); | 2472 | ais.popIndent(); |
| 2515 | break :colon2 switch (token_tags[comma_or_colon]) { | 2473 | break :colon2 switch (tree.tokenTag(comma_or_colon)) { |
| 2516 | .comma => comma_or_colon + 1, | 2474 | .comma => comma_or_colon + 1, |
| 2517 | else => comma_or_colon, | 2475 | else => comma_or_colon, |
| 2518 | }; | 2476 | }; |
| ... | @@ -2548,7 +2506,7 @@ fn renderAsm( | ... | @@ -2548,7 +2506,7 @@ fn renderAsm( |
| 2548 | ais.popSpace(); | 2506 | ais.popSpace(); |
| 2549 | const comma_or_colon = tree.lastToken(asm_input) + 1; | 2507 | const comma_or_colon = tree.lastToken(asm_input) + 1; |
| 2550 | ais.popIndent(); | 2508 | ais.popIndent(); |
| 2551 | break :colon3 switch (token_tags[comma_or_colon]) { | 2509 | break :colon3 switch (tree.tokenTag(comma_or_colon)) { |
| 2552 | .comma => comma_or_colon + 1, | 2510 | .comma => comma_or_colon + 1, |
| 2553 | else => comma_or_colon, | 2511 | else => comma_or_colon, |
| 2554 | }; | 2512 | }; |
| ... | @@ -2561,7 +2519,7 @@ fn renderAsm( | ... | @@ -2561,7 +2519,7 @@ fn renderAsm( |
| 2561 | const first_clobber = asm_node.first_clobber.?; | 2519 | const first_clobber = asm_node.first_clobber.?; |
| 2562 | var tok_i = first_clobber; | 2520 | var tok_i = first_clobber; |
| 2563 | while (true) { | 2521 | while (true) { |
| 2564 | switch (token_tags[tok_i + 1]) { | 2522 | switch (tree.tokenTag(tok_i + 1)) { |
| 2565 | .r_paren => { | 2523 | .r_paren => { |
| 2566 | ais.setIndentDelta(indent_delta); | 2524 | ais.setIndentDelta(indent_delta); |
| 2567 | try renderToken(r, tok_i, .newline); | 2525 | try renderToken(r, tok_i, .newline); |
| ... | @@ -2569,7 +2527,7 @@ fn renderAsm( | ... | @@ -2569,7 +2527,7 @@ fn renderAsm( |
| 2569 | return renderToken(r, tok_i + 1, space); | 2527 | return renderToken(r, tok_i + 1, space); |
| 2570 | }, | 2528 | }, |
| 2571 | .comma => { | 2529 | .comma => { |
| 2572 | switch (token_tags[tok_i + 2]) { | 2530 | switch (tree.tokenTag(tok_i + 2)) { |
| 2573 | .r_paren => { | 2531 | .r_paren => { |
| 2574 | ais.setIndentDelta(indent_delta); | 2532 | ais.setIndentDelta(indent_delta); |
| 2575 | try renderToken(r, tok_i, .newline); | 2533 | try renderToken(r, tok_i, .newline); |
| ... | @@ -2608,7 +2566,6 @@ fn renderParamList( | ... | @@ -2608,7 +2566,6 @@ fn renderParamList( |
| 2608 | ) Error!void { | 2566 | ) Error!void { |
| 2609 | const tree = r.tree; | 2567 | const tree = r.tree; |
| 2610 | const ais = r.ais; | 2568 | const ais = r.ais; |
| 2611 | const token_tags = tree.tokens.items(.tag); | ||
| 2612 | 2569 | ||
| 2613 | if (params.len == 0) { | 2570 | if (params.len == 0) { |
| 2614 | try ais.pushIndent(.normal); | 2571 | try ais.pushIndent(.normal); |
| ... | @@ -2619,7 +2576,7 @@ fn renderParamList( | ... | @@ -2619,7 +2576,7 @@ fn renderParamList( |
| 2619 | 2576 | ||
| 2620 | const last_param = params[params.len - 1]; | 2577 | const last_param = params[params.len - 1]; |
| 2621 | const after_last_param_tok = tree.lastToken(last_param) + 1; | 2578 | const after_last_param_tok = tree.lastToken(last_param) + 1; |
| 2622 | if (token_tags[after_last_param_tok] == .comma) { | 2579 | if (tree.tokenTag(after_last_param_tok) == .comma) { |
| 2623 | try ais.pushIndent(.normal); | 2580 | try ais.pushIndent(.normal); |
| 2624 | try renderToken(r, lparen, .newline); // ( | 2581 | try renderToken(r, lparen, .newline); // ( |
| 2625 | for (params, 0..) |param_node, i| { | 2582 | for (params, 0..) |param_node, i| { |
| ... | @@ -2648,7 +2605,7 @@ fn renderParamList( | ... | @@ -2648,7 +2605,7 @@ fn renderParamList( |
| 2648 | if (i + 1 < params.len) { | 2605 | if (i + 1 < params.len) { |
| 2649 | const comma = tree.lastToken(param_node) + 1; | 2606 | const comma = tree.lastToken(param_node) + 1; |
| 2650 | const next_multiline_string = | 2607 | const next_multiline_string = |
| 2651 | token_tags[tree.firstToken(params[i + 1])] == .multiline_string_literal_line; | 2608 | tree.tokenTag(tree.firstToken(params[i + 1])) == .multiline_string_literal_line; |
| 2652 | const comma_space: Space = if (next_multiline_string) .none else .space; | 2609 | const comma_space: Space = if (next_multiline_string) .none else .space; |
| 2653 | try renderToken(r, comma, comma_space); | 2610 | try renderToken(r, comma, comma_space); |
| 2654 | } | 2611 | } |
| ... | @@ -2661,9 +2618,8 @@ fn renderParamList( | ... | @@ -2661,9 +2618,8 @@ fn renderParamList( |
| 2661 | /// If a comma is present, and `space` is `Space.comma`, render only a single comma. | 2618 | /// If a comma is present, and `space` is `Space.comma`, render only a single comma. |
| 2662 | fn renderExpressionComma(r: *Render, node: Ast.Node.Index, space: Space) Error!void { | 2619 | fn renderExpressionComma(r: *Render, node: Ast.Node.Index, space: Space) Error!void { |
| 2663 | const tree = r.tree; | 2620 | const tree = r.tree; |
| 2664 | const token_tags = tree.tokens.items(.tag); | ||
| 2665 | const maybe_comma = tree.lastToken(node) + 1; | 2621 | const maybe_comma = tree.lastToken(node) + 1; |
| 2666 | if (token_tags[maybe_comma] == .comma and space != .comma) { | 2622 | if (tree.tokenTag(maybe_comma) == .comma and space != .comma) { |
| 2667 | try renderExpression(r, node, .none); | 2623 | try renderExpression(r, node, .none); |
| 2668 | return renderToken(r, maybe_comma, space); | 2624 | return renderToken(r, maybe_comma, space); |
| 2669 | } else { | 2625 | } else { |
| ... | @@ -2675,9 +2631,8 @@ fn renderExpressionComma(r: *Render, node: Ast.Node.Index, space: Space) Error!v | ... | @@ -2675,9 +2631,8 @@ fn renderExpressionComma(r: *Render, node: Ast.Node.Index, space: Space) Error!v |
| 2675 | /// If a comma is present, and `space` is `Space.comma`, render only a single comma. | 2631 | /// If a comma is present, and `space` is `Space.comma`, render only a single comma. |
| 2676 | fn renderTokenComma(r: *Render, token: Ast.TokenIndex, space: Space) Error!void { | 2632 | fn renderTokenComma(r: *Render, token: Ast.TokenIndex, space: Space) Error!void { |
| 2677 | const tree = r.tree; | 2633 | const tree = r.tree; |
| 2678 | const token_tags = tree.tokens.items(.tag); | ||
| 2679 | const maybe_comma = token + 1; | 2634 | const maybe_comma = token + 1; |
| 2680 | if (token_tags[maybe_comma] == .comma and space != .comma) { | 2635 | if (tree.tokenTag(maybe_comma) == .comma and space != .comma) { |
| 2681 | try renderToken(r, token, .none); | 2636 | try renderToken(r, token, .none); |
| 2682 | return renderToken(r, maybe_comma, space); | 2637 | return renderToken(r, maybe_comma, space); |
| 2683 | } else { | 2638 | } else { |
| ... | @@ -2689,9 +2644,8 @@ fn renderTokenComma(r: *Render, token: Ast.TokenIndex, space: Space) Error!void | ... | @@ -2689,9 +2644,8 @@ fn renderTokenComma(r: *Render, token: Ast.TokenIndex, space: Space) Error!void |
| 2689 | /// If a comma is present, and `space` is `Space.comma`, render only a single comma. | 2644 | /// If a comma is present, and `space` is `Space.comma`, render only a single comma. |
| 2690 | fn renderIdentifierComma(r: *Render, token: Ast.TokenIndex, space: Space, quote: QuoteBehavior) Error!void { | 2645 | fn renderIdentifierComma(r: *Render, token: Ast.TokenIndex, space: Space, quote: QuoteBehavior) Error!void { |
| 2691 | const tree = r.tree; | 2646 | const tree = r.tree; |
| 2692 | const token_tags = tree.tokens.items(.tag); | ||
| 2693 | const maybe_comma = token + 1; | 2647 | const maybe_comma = token + 1; |
| 2694 | if (token_tags[maybe_comma] == .comma and space != .comma) { | 2648 | if (tree.tokenTag(maybe_comma) == .comma and space != .comma) { |
| 2695 | try renderIdentifier(r, token, .none, quote); | 2649 | try renderIdentifier(r, token, .none, quote); |
| 2696 | return renderToken(r, maybe_comma, space); | 2650 | return renderToken(r, maybe_comma, space); |
| 2697 | } else { | 2651 | } else { |
| ... | @@ -2741,37 +2695,39 @@ fn renderTokenOverrideSpaceMode(r: *Render, token_index: Ast.TokenIndex, space: | ... | @@ -2741,37 +2695,39 @@ fn renderTokenOverrideSpaceMode(r: *Render, token_index: Ast.TokenIndex, space: |
| 2741 | fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space: Space) Error!void { | 2695 | fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space: Space) Error!void { |
| 2742 | const tree = r.tree; | 2696 | const tree = r.tree; |
| 2743 | const ais = r.ais; | 2697 | const ais = r.ais; |
| 2744 | const token_tags = tree.tokens.items(.tag); | ||
| 2745 | const token_starts = tree.tokens.items(.start); | ||
| 2746 | 2698 | ||
| 2747 | const token_start = token_starts[token_index]; | 2699 | const next_token_tag = tree.tokenTag(token_index + 1); |
| 2748 | 2700 | ||
| 2749 | if (space == .skip) return; | 2701 | if (space == .skip) return; |
| 2750 | 2702 | ||
| 2751 | if (space == .comma and token_tags[token_index + 1] != .comma) { | 2703 | if (space == .comma and next_token_tag != .comma) { |
| 2752 | try ais.writer().writeByte(','); | 2704 | try ais.writer().writeByte(','); |
| 2753 | } | 2705 | } |
| 2754 | if (space == .semicolon or space == .comma) ais.enableSpaceMode(space); | 2706 | if (space == .semicolon or space == .comma) ais.enableSpaceMode(space); |
| 2755 | defer ais.disableSpaceMode(); | 2707 | defer ais.disableSpaceMode(); |
| 2756 | const comment = try renderComments(r, token_start + lexeme_len, token_starts[token_index + 1]); | 2708 | const comment = try renderComments( |
| 2709 | r, | ||
| 2710 | tree.tokenStart(token_index) + lexeme_len, | ||
| 2711 | tree.tokenStart(token_index + 1), | ||
| 2712 | ); | ||
| 2757 | switch (space) { | 2713 | switch (space) { |
| 2758 | .none => {}, | 2714 | .none => {}, |
| 2759 | .space => if (!comment) try ais.writer().writeByte(' '), | 2715 | .space => if (!comment) try ais.writer().writeByte(' '), |
| 2760 | .newline => if (!comment) try ais.insertNewline(), | 2716 | .newline => if (!comment) try ais.insertNewline(), |
| 2761 | 2717 | ||
| 2762 | .comma => if (token_tags[token_index + 1] == .comma) { | 2718 | .comma => if (next_token_tag == .comma) { |
| 2763 | try renderToken(r, token_index + 1, .newline); | 2719 | try renderToken(r, token_index + 1, .newline); |
| 2764 | } else if (!comment) { | 2720 | } else if (!comment) { |
| 2765 | try ais.insertNewline(); | 2721 | try ais.insertNewline(); |
| 2766 | }, | 2722 | }, |
| 2767 | 2723 | ||
| 2768 | .comma_space => if (token_tags[token_index + 1] == .comma) { | 2724 | .comma_space => if (next_token_tag == .comma) { |
| 2769 | try renderToken(r, token_index + 1, .space); | 2725 | try renderToken(r, token_index + 1, .space); |
| 2770 | } else if (!comment) { | 2726 | } else if (!comment) { |
| 2771 | try ais.writer().writeByte(' '); | 2727 | try ais.writer().writeByte(' '); |
| 2772 | }, | 2728 | }, |
| 2773 | 2729 | ||
| 2774 | .semicolon => if (token_tags[token_index + 1] == .semicolon) { | 2730 | .semicolon => if (next_token_tag == .semicolon) { |
| 2775 | try renderToken(r, token_index + 1, .newline); | 2731 | try renderToken(r, token_index + 1, .newline); |
| 2776 | } else if (!comment) { | 2732 | } else if (!comment) { |
| 2777 | try ais.insertNewline(); | 2733 | try ais.insertNewline(); |
| ... | @@ -2802,8 +2758,7 @@ const QuoteBehavior = enum { | ... | @@ -2802,8 +2758,7 @@ const QuoteBehavior = enum { |
| 2802 | 2758 | ||
| 2803 | fn renderIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space, quote: QuoteBehavior) Error!void { | 2759 | fn renderIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space, quote: QuoteBehavior) Error!void { |
| 2804 | const tree = r.tree; | 2760 | const tree = r.tree; |
| 2805 | const token_tags = tree.tokens.items(.tag); | 2761 | assert(tree.tokenTag(token_index) == .identifier); |
| 2806 | assert(token_tags[token_index] == .identifier); | ||
| 2807 | const lexeme = tokenSliceForRender(tree, token_index); | 2762 | const lexeme = tokenSliceForRender(tree, token_index); |
| 2808 | 2763 | ||
| 2809 | if (r.fixups.rename_identifiers.get(lexeme)) |mangled| { | 2764 | if (r.fixups.rename_identifiers.get(lexeme)) |mangled| { |
| ... | @@ -2912,8 +2867,7 @@ fn renderIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space, quote | ... | @@ -2912,8 +2867,7 @@ fn renderIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space, quote |
| 2912 | fn renderQuotedIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space, comptime unquote: bool) !void { | 2867 | fn renderQuotedIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space, comptime unquote: bool) !void { |
| 2913 | const tree = r.tree; | 2868 | const tree = r.tree; |
| 2914 | const ais = r.ais; | 2869 | const ais = r.ais; |
| 2915 | const token_tags = tree.tokens.items(.tag); | 2870 | assert(tree.tokenTag(token_index) == .identifier); |
| 2916 | assert(token_tags[token_index] == .identifier); | ||
| 2917 | const lexeme = tokenSliceForRender(tree, token_index); | 2871 | const lexeme = tokenSliceForRender(tree, token_index); |
| 2918 | assert(lexeme.len >= 3 and lexeme[0] == '@'); | 2872 | assert(lexeme.len >= 3 and lexeme[0] == '@'); |
| 2919 | 2873 | ||
| ... | @@ -2966,12 +2920,10 @@ fn renderIdentifierContents(writer: anytype, bytes: []const u8) !void { | ... | @@ -2966,12 +2920,10 @@ fn renderIdentifierContents(writer: anytype, bytes: []const u8) !void { |
| 2966 | /// fn_proto should be wrapped and have a trailing comma inserted even if | 2920 | /// fn_proto should be wrapped and have a trailing comma inserted even if |
| 2967 | /// there is none in the source. | 2921 | /// there is none in the source. |
| 2968 | fn hasComment(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool { | 2922 | fn hasComment(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool { |
| 2969 | const token_starts = tree.tokens.items(.start); | 2923 | for (start_token..end_token) |i| { |
| 2970 | 2924 | const token: Ast.TokenIndex = @intCast(i); | |
| 2971 | var i = start_token; | 2925 | const start = tree.tokenStart(token) + tree.tokenSlice(token).len; |
| 2972 | while (i < end_token) : (i += 1) { | 2926 | const end = tree.tokenStart(token + 1); |
| 2973 | const start = token_starts[i] + tree.tokenSlice(i).len; | ||
| 2974 | const end = token_starts[i + 1]; | ||
| 2975 | if (mem.indexOf(u8, tree.source[start..end], "//") != null) return true; | 2927 | if (mem.indexOf(u8, tree.source[start..end], "//") != null) return true; |
| 2976 | } | 2928 | } |
| 2977 | 2929 | ||
| ... | @@ -2981,16 +2933,11 @@ fn hasComment(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) | ... | @@ -2981,16 +2933,11 @@ fn hasComment(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) |
| 2981 | /// Returns true if there exists a multiline string literal between the start | 2933 | /// Returns true if there exists a multiline string literal between the start |
| 2982 | /// of token `start_token` and the start of token `end_token`. | 2934 | /// of token `start_token` and the start of token `end_token`. |
| 2983 | fn hasMultilineString(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool { | 2935 | fn hasMultilineString(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool { |
| 2984 | const token_tags = tree.tokens.items(.tag); | 2936 | return std.mem.indexOfScalar( |
| 2985 | 2937 | Token.Tag, | |
| 2986 | for (token_tags[start_token..end_token]) |tag| { | 2938 | tree.tokens.items(.tag)[start_token..end_token], |
| 2987 | switch (tag) { | 2939 | .multiline_string_literal_line, |
| 2988 | .multiline_string_literal_line => return true, | 2940 | ) != null; |
| 2989 | else => continue, | ||
| 2990 | } | ||
| 2991 | } | ||
| 2992 | |||
| 2993 | return false; | ||
| 2994 | } | 2941 | } |
| 2995 | 2942 | ||
| 2996 | /// Assumes that start is the first byte past the previous token and | 2943 | /// Assumes that start is the first byte past the previous token and |
| ... | @@ -3066,18 +3013,17 @@ fn renderExtraNewline(r: *Render, node: Ast.Node.Index) Error!void { | ... | @@ -3066,18 +3013,17 @@ fn renderExtraNewline(r: *Render, node: Ast.Node.Index) Error!void { |
| 3066 | fn renderExtraNewlineToken(r: *Render, token_index: Ast.TokenIndex) Error!void { | 3013 | fn renderExtraNewlineToken(r: *Render, token_index: Ast.TokenIndex) Error!void { |
| 3067 | const tree = r.tree; | 3014 | const tree = r.tree; |
| 3068 | const ais = r.ais; | 3015 | const ais = r.ais; |
| 3069 | const token_starts = tree.tokens.items(.start); | 3016 | const token_start = tree.tokenStart(token_index); |
| 3070 | const token_start = token_starts[token_index]; | ||
| 3071 | if (token_start == 0) return; | 3017 | if (token_start == 0) return; |
| 3072 | const prev_token_end = if (token_index == 0) | 3018 | const prev_token_end = if (token_index == 0) |
| 3073 | 0 | 3019 | 0 |
| 3074 | else | 3020 | else |
| 3075 | token_starts[token_index - 1] + tokenSliceForRender(tree, token_index - 1).len; | 3021 | tree.tokenStart(token_index - 1) + tokenSliceForRender(tree, token_index - 1).len; |
| 3076 | 3022 | ||
| 3077 | // If there is a immediately preceding comment or doc_comment, | 3023 | // If there is a immediately preceding comment or doc_comment, |
| 3078 | // skip it because required extra newline has already been rendered. | 3024 | // skip it because required extra newline has already been rendered. |
| 3079 | if (mem.indexOf(u8, tree.source[prev_token_end..token_start], "//") != null) return; | 3025 | if (mem.indexOf(u8, tree.source[prev_token_end..token_start], "//") != null) return; |
| 3080 | if (token_index > 0 and tree.tokens.items(.tag)[token_index - 1] == .doc_comment) return; | 3026 | if (tree.isTokenPrecededByTags(token_index, &.{.doc_comment})) return; |
| 3081 | 3027 | ||
| 3082 | // Iterate backwards to the end of the previous token, stopping if a | 3028 | // Iterate backwards to the end of the previous token, stopping if a |
| 3083 | // non-whitespace character is encountered or two newlines have been found. | 3029 | // non-whitespace character is encountered or two newlines have been found. |
| ... | @@ -3095,10 +3041,9 @@ fn renderExtraNewlineToken(r: *Render, token_index: Ast.TokenIndex) Error!void { | ... | @@ -3095,10 +3041,9 @@ fn renderExtraNewlineToken(r: *Render, token_index: Ast.TokenIndex) Error!void { |
| 3095 | fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void { | 3041 | fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void { |
| 3096 | const tree = r.tree; | 3042 | const tree = r.tree; |
| 3097 | // Search backwards for the first doc comment. | 3043 | // Search backwards for the first doc comment. |
| 3098 | const token_tags = tree.tokens.items(.tag); | ||
| 3099 | if (end_token == 0) return; | 3044 | if (end_token == 0) return; |
| 3100 | var tok = end_token - 1; | 3045 | var tok = end_token - 1; |
| 3101 | while (token_tags[tok] == .doc_comment) { | 3046 | while (tree.tokenTag(tok) == .doc_comment) { |
| 3102 | if (tok == 0) break; | 3047 | if (tok == 0) break; |
| 3103 | tok -= 1; | 3048 | tok -= 1; |
| 3104 | } else { | 3049 | } else { |
| ... | @@ -3108,7 +3053,7 @@ fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void { | ... | @@ -3108,7 +3053,7 @@ fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void { |
| 3108 | if (first_tok == end_token) return; | 3053 | if (first_tok == end_token) return; |
| 3109 | 3054 | ||
| 3110 | if (first_tok != 0) { | 3055 | if (first_tok != 0) { |
| 3111 | const prev_token_tag = token_tags[first_tok - 1]; | 3056 | const prev_token_tag = tree.tokenTag(first_tok - 1); |
| 3112 | 3057 | ||
| 3113 | // Prevent accidental use of `renderDocComments` for a function argument doc comment | 3058 | // Prevent accidental use of `renderDocComments` for a function argument doc comment |
| 3114 | assert(prev_token_tag != .l_paren); | 3059 | assert(prev_token_tag != .l_paren); |
| ... | @@ -3118,7 +3063,7 @@ fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void { | ... | @@ -3118,7 +3063,7 @@ fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void { |
| 3118 | } | 3063 | } |
| 3119 | } | 3064 | } |
| 3120 | 3065 | ||
| 3121 | while (token_tags[tok] == .doc_comment) : (tok += 1) { | 3066 | while (tree.tokenTag(tok) == .doc_comment) : (tok += 1) { |
| 3122 | try renderToken(r, tok, .newline); | 3067 | try renderToken(r, tok, .newline); |
| 3123 | } | 3068 | } |
| 3124 | } | 3069 | } |
| ... | @@ -3126,15 +3071,14 @@ fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void { | ... | @@ -3126,15 +3071,14 @@ fn renderDocComments(r: *Render, end_token: Ast.TokenIndex) Error!void { |
| 3126 | /// start_token is first container doc comment token. | 3071 | /// start_token is first container doc comment token. |
| 3127 | fn renderContainerDocComments(r: *Render, start_token: Ast.TokenIndex) Error!void { | 3072 | fn renderContainerDocComments(r: *Render, start_token: Ast.TokenIndex) Error!void { |
| 3128 | const tree = r.tree; | 3073 | const tree = r.tree; |
| 3129 | const token_tags = tree.tokens.items(.tag); | ||
| 3130 | var tok = start_token; | 3074 | var tok = start_token; |
| 3131 | while (token_tags[tok] == .container_doc_comment) : (tok += 1) { | 3075 | while (tree.tokenTag(tok) == .container_doc_comment) : (tok += 1) { |
| 3132 | try renderToken(r, tok, .newline); | 3076 | try renderToken(r, tok, .newline); |
| 3133 | } | 3077 | } |
| 3134 | // Render extra newline if there is one between final container doc comment and | 3078 | // Render extra newline if there is one between final container doc comment and |
| 3135 | // the next token. If the next token is a doc comment, that code path | 3079 | // the next token. If the next token is a doc comment, that code path |
| 3136 | // will have its own logic to insert a newline. | 3080 | // will have its own logic to insert a newline. |
| 3137 | if (token_tags[tok] != .doc_comment) { | 3081 | if (tree.tokenTag(tok) != .doc_comment) { |
| 3138 | try renderExtraNewlineToken(r, tok); | 3082 | try renderExtraNewlineToken(r, tok); |
| 3139 | } | 3083 | } |
| 3140 | } | 3084 | } |
| ... | @@ -3144,11 +3088,10 @@ fn discardAllParams(r: *Render, fn_proto_node: Ast.Node.Index) Error!void { | ... | @@ -3144,11 +3088,10 @@ fn discardAllParams(r: *Render, fn_proto_node: Ast.Node.Index) Error!void { |
| 3144 | const ais = r.ais; | 3088 | const ais = r.ais; |
| 3145 | var buf: [1]Ast.Node.Index = undefined; | 3089 | var buf: [1]Ast.Node.Index = undefined; |
| 3146 | const fn_proto = tree.fullFnProto(&buf, fn_proto_node).?; | 3090 | const fn_proto = tree.fullFnProto(&buf, fn_proto_node).?; |
| 3147 | const token_tags = tree.tokens.items(.tag); | ||
| 3148 | var it = fn_proto.iterate(tree); | 3091 | var it = fn_proto.iterate(tree); |
| 3149 | while (it.next()) |param| { | 3092 | while (it.next()) |param| { |
| 3150 | const name_ident = param.name_token.?; | 3093 | const name_ident = param.name_token.?; |
| 3151 | assert(token_tags[name_ident] == .identifier); | 3094 | assert(tree.tokenTag(name_ident) == .identifier); |
| 3152 | const w = ais.writer(); | 3095 | const w = ais.writer(); |
| 3153 | try w.writeAll("_ = "); | 3096 | try w.writeAll("_ = "); |
| 3154 | try w.writeAll(tokenSliceForRender(r.tree, name_ident)); | 3097 | try w.writeAll(tokenSliceForRender(r.tree, name_ident)); |
| ... | @@ -3158,7 +3101,7 @@ fn discardAllParams(r: *Render, fn_proto_node: Ast.Node.Index) Error!void { | ... | @@ -3158,7 +3101,7 @@ fn discardAllParams(r: *Render, fn_proto_node: Ast.Node.Index) Error!void { |
| 3158 | 3101 | ||
| 3159 | fn tokenSliceForRender(tree: Ast, token_index: Ast.TokenIndex) []const u8 { | 3102 | fn tokenSliceForRender(tree: Ast, token_index: Ast.TokenIndex) []const u8 { |
| 3160 | var ret = tree.tokenSlice(token_index); | 3103 | var ret = tree.tokenSlice(token_index); |
| 3161 | switch (tree.tokens.items(.tag)[token_index]) { | 3104 | switch (tree.tokenTag(token_index)) { |
| 3162 | .container_doc_comment, .doc_comment => { | 3105 | .container_doc_comment, .doc_comment => { |
| 3163 | ret = mem.trimRight(u8, ret, &std.ascii.whitespace); | 3106 | ret = mem.trimRight(u8, ret, &std.ascii.whitespace); |
| 3164 | }, | 3107 | }, |
| ... | @@ -3168,8 +3111,7 @@ fn tokenSliceForRender(tree: Ast, token_index: Ast.TokenIndex) []const u8 { | ... | @@ -3168,8 +3111,7 @@ fn tokenSliceForRender(tree: Ast, token_index: Ast.TokenIndex) []const u8 { |
| 3168 | } | 3111 | } |
| 3169 | 3112 | ||
| 3170 | fn hasSameLineComment(tree: Ast, token_index: Ast.TokenIndex) bool { | 3113 | fn hasSameLineComment(tree: Ast, token_index: Ast.TokenIndex) bool { |
| 3171 | const token_starts = tree.tokens.items(.start); | 3114 | const between_source = tree.source[tree.tokenStart(token_index)..tree.tokenStart(token_index + 1)]; |
| 3172 | const between_source = tree.source[token_starts[token_index]..token_starts[token_index + 1]]; | ||
| 3173 | for (between_source) |byte| switch (byte) { | 3115 | for (between_source) |byte| switch (byte) { |
| 3174 | '\n' => return false, | 3116 | '\n' => return false, |
| 3175 | '/' => return true, | 3117 | '/' => return true, |
| ... | @@ -3182,8 +3124,7 @@ fn hasSameLineComment(tree: Ast, token_index: Ast.TokenIndex) bool { | ... | @@ -3182,8 +3124,7 @@ fn hasSameLineComment(tree: Ast, token_index: Ast.TokenIndex) bool { |
| 3182 | /// start_token and end_token. | 3124 | /// start_token and end_token. |
| 3183 | fn anythingBetween(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool { | 3125 | fn anythingBetween(tree: Ast, start_token: Ast.TokenIndex, end_token: Ast.TokenIndex) bool { |
| 3184 | if (start_token + 1 != end_token) return true; | 3126 | if (start_token + 1 != end_token) return true; |
| 3185 | const token_starts = tree.tokens.items(.start); | 3127 | const between_source = tree.source[tree.tokenStart(start_token)..tree.tokenStart(start_token + 1)]; |
| 3186 | const between_source = tree.source[token_starts[start_token]..token_starts[start_token + 1]]; | ||
| 3187 | for (between_source) |byte| switch (byte) { | 3128 | for (between_source) |byte| switch (byte) { |
| 3188 | '/' => return true, | 3129 | '/' => return true, |
| 3189 | else => continue, | 3130 | else => continue, |
| ... | @@ -3277,12 +3218,10 @@ fn nodeCausesSliceOpSpace(tag: Ast.Node.Tag) bool { | ... | @@ -3277,12 +3218,10 @@ fn nodeCausesSliceOpSpace(tag: Ast.Node.Tag) bool { |
| 3277 | 3218 | ||
| 3278 | // Returns the number of nodes in `exprs` that are on the same line as `rtoken`. | 3219 | // Returns the number of nodes in `exprs` that are on the same line as `rtoken`. |
| 3279 | fn rowSize(tree: Ast, exprs: []const Ast.Node.Index, rtoken: Ast.TokenIndex) usize { | 3220 | fn rowSize(tree: Ast, exprs: []const Ast.Node.Index, rtoken: Ast.TokenIndex) usize { |
| 3280 | const token_tags = tree.tokens.items(.tag); | ||
| 3281 | |||
| 3282 | const first_token = tree.firstToken(exprs[0]); | 3221 | const first_token = tree.firstToken(exprs[0]); |
| 3283 | if (tree.tokensOnSameLine(first_token, rtoken)) { | 3222 | if (tree.tokensOnSameLine(first_token, rtoken)) { |
| 3284 | const maybe_comma = rtoken - 1; | 3223 | const maybe_comma = rtoken - 1; |
| 3285 | if (token_tags[maybe_comma] == .comma) | 3224 | if (tree.tokenTag(maybe_comma) == .comma) |
| 3286 | return 1; | 3225 | return 1; |
| 3287 | return exprs.len; // no newlines | 3226 | return exprs.len; // no newlines |
| 3288 | } | 3227 | } |
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]), |
| ... | @@ -2331,7 +2331,7 @@ const TestFetchBuilder = struct { | ... | @@ -2331,7 +2331,7 @@ const TestFetchBuilder = struct { |
| 2331 | .arena = std.heap.ArenaAllocator.init(allocator), | 2331 | .arena = std.heap.ArenaAllocator.init(allocator), |
| 2332 | .location = .{ .path_or_url = path_or_url }, | 2332 | .location = .{ .path_or_url = path_or_url }, |
| 2333 | .location_tok = 0, | 2333 | .location_tok = 0, |
| 2334 | .hash_tok = 0, | 2334 | .hash_tok = .none, |
| 2335 | .name_tok = 0, | 2335 | .name_tok = 0, |
| 2336 | .lazy_status = .eager, | 2336 | .lazy_status = .eager, |
| 2337 | .parent_package_root = Cache.Path{ .root_dir = Cache.Directory{ .handle = cache_dir, .path = null } }, | 2337 | .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); |
| ... | @@ -17873,7 +17892,7 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -17873,7 +17892,7 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 17873 | const ip = &zcu.intern_pool; | 17892 | const ip = &zcu.intern_pool; |
| 17874 | const captures = Type.fromInterned(zcu.namespacePtr(block.namespace).owner_type).getCaptures(zcu); | 17893 | const captures = Type.fromInterned(zcu.namespacePtr(block.namespace).owner_type).getCaptures(zcu); |
| 17875 | 17894 | ||
| 17876 | const src_node: i32 = @bitCast(extended.operand); | 17895 | const src_node: std.zig.Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand))); |
| 17877 | const src = block.nodeOffset(src_node); | 17896 | const src = block.nodeOffset(src_node); |
| 17878 | 17897 | ||
| 17879 | const capture_ty = switch (captures.get(ip)[extended.small].unwrap()) { | 17898 | const capture_ty = switch (captures.get(ip)[extended.small].unwrap()) { |
| ... | @@ -17897,8 +17916,8 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -17897,8 +17916,8 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 17897 | }); | 17916 | }); |
| 17898 | break :name null; | 17917 | break :name null; |
| 17899 | }; | 17918 | }; |
| 17900 | const node: std.zig.Ast.Node.Index = @bitCast(src_node + @as(i32, @bitCast(src_base_node))); | 17919 | const node = src_node.toAbsolute(src_base_node); |
| 17901 | const token = tree.nodes.items(.main_token)[node]; | 17920 | const token = tree.nodeMainToken(node); |
| 17902 | break :name tree.tokenSlice(token); | 17921 | break :name tree.tokenSlice(token); |
| 17903 | }; | 17922 | }; |
| 17904 | 17923 | ||
| ... | @@ -17925,8 +17944,8 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -17925,8 +17944,8 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 17925 | }); | 17944 | }); |
| 17926 | break :name null; | 17945 | break :name null; |
| 17927 | }; | 17946 | }; |
| 17928 | const node: std.zig.Ast.Node.Index = @bitCast(src_node + @as(i32, @bitCast(src_base_node))); | 17947 | const node = src_node.toAbsolute(src_base_node); |
| 17929 | const token = tree.nodes.items(.main_token)[node]; | 17948 | const token = tree.nodeMainToken(node); |
| 17930 | break :name tree.tokenSlice(token); | 17949 | break :name tree.tokenSlice(token); |
| 17931 | }; | 17950 | }; |
| 17932 | 17951 | ||
| ... | @@ -17936,7 +17955,7 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -17936,7 +17955,7 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 17936 | try sema.errMsg(src, "variable not accessible from inner function", .{}); | 17955 | try sema.errMsg(src, "variable not accessible from inner function", .{}); |
| 17937 | errdefer msg.destroy(sema.gpa); | 17956 | errdefer msg.destroy(sema.gpa); |
| 17938 | 17957 | ||
| 17939 | try sema.errNote(block.nodeOffset(0), msg, "crossed function definition here", .{}); | 17958 | try sema.errNote(block.nodeOffset(.zero), msg, "crossed function definition here", .{}); |
| 17940 | 17959 | ||
| 17941 | // TODO add "declared here" note | 17960 | // TODO add "declared here" note |
| 17942 | break :msg msg; | 17961 | break :msg msg; |
| ... | @@ -17968,7 +17987,8 @@ fn zirFrameAddress( | ... | @@ -17968,7 +17987,8 @@ fn zirFrameAddress( |
| 17968 | block: *Block, | 17987 | block: *Block, |
| 17969 | extended: Zir.Inst.Extended.InstData, | 17988 | extended: Zir.Inst.Extended.InstData, |
| 17970 | ) CompileError!Air.Inst.Ref { | 17989 | ) CompileError!Air.Inst.Ref { |
| 17971 | const src = block.nodeOffset(@bitCast(extended.operand)); | 17990 | const src_node: std.zig.Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand))); |
| 17991 | const src = block.nodeOffset(src_node); | ||
| 17972 | try sema.requireRuntimeBlock(block, src, null); | 17992 | try sema.requireRuntimeBlock(block, src, null); |
| 17973 | return try block.addNoOp(.frame_addr); | 17993 | return try block.addNoOp(.frame_addr); |
| 17974 | } | 17994 | } |
| ... | @@ -18065,7 +18085,7 @@ fn zirBuiltinSrc( | ... | @@ -18065,7 +18085,7 @@ fn zirBuiltinSrc( |
| 18065 | } }); | 18085 | } }); |
| 18066 | }; | 18086 | }; |
| 18067 | 18087 | ||
| 18068 | const src_loc_ty = try sema.getBuiltinType(block.nodeOffset(0), .SourceLocation); | 18088 | const src_loc_ty = try sema.getBuiltinType(block.nodeOffset(.zero), .SourceLocation); |
| 18069 | const fields = .{ | 18089 | const fields = .{ |
| 18070 | // module: [:0]const u8, | 18090 | // module: [:0]const u8, |
| 18071 | module_name_val, | 18091 | module_name_val, |
| ... | @@ -19534,7 +19554,7 @@ fn zirCondbr( | ... | @@ -19534,7 +19554,7 @@ fn zirCondbr( |
| 19534 | fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 19554 | fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 19535 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 19555 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 19536 | const src = parent_block.nodeOffset(inst_data.src_node); | 19556 | const src = parent_block.nodeOffset(inst_data.src_node); |
| 19537 | const operand_src = parent_block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 19557 | const operand_src = parent_block.src(.{ .node_offset_try_operand = inst_data.src_node }); |
| 19538 | const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index); | 19558 | const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index); |
| 19539 | const body = sema.code.bodySlice(extra.end, extra.data.body_len); | 19559 | const body = sema.code.bodySlice(extra.end, extra.data.body_len); |
| 19540 | const err_union = try sema.resolveInst(extra.data.operand); | 19560 | const err_union = try sema.resolveInst(extra.data.operand); |
| ... | @@ -19593,7 +19613,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -19593,7 +19613,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError! |
| 19593 | fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 19613 | fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 19594 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 19614 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 19595 | const src = parent_block.nodeOffset(inst_data.src_node); | 19615 | const src = parent_block.nodeOffset(inst_data.src_node); |
| 19596 | const operand_src = parent_block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 19616 | const operand_src = parent_block.src(.{ .node_offset_try_operand = inst_data.src_node }); |
| 19597 | const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index); | 19617 | const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index); |
| 19598 | const body = sema.code.bodySlice(extra.end, extra.data.body_len); | 19618 | const body = sema.code.bodySlice(extra.end, extra.data.body_len); |
| 19599 | const operand = try sema.resolveInst(extra.data.operand); | 19619 | const operand = try sema.resolveInst(extra.data.operand); |
| ... | @@ -19796,7 +19816,7 @@ fn zirRetImplicit( | ... | @@ -19796,7 +19816,7 @@ fn zirRetImplicit( |
| 19796 | } | 19816 | } |
| 19797 | 19817 | ||
| 19798 | const operand = try sema.resolveInst(inst_data.operand); | 19818 | const operand = try sema.resolveInst(inst_data.operand); |
| 19799 | const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = 0 }); | 19819 | const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = .zero }); |
| 19800 | const base_tag = sema.fn_ret_ty.baseZigTypeTag(zcu); | 19820 | const base_tag = sema.fn_ret_ty.baseZigTypeTag(zcu); |
| 19801 | if (base_tag == .noreturn) { | 19821 | if (base_tag == .noreturn) { |
| 19802 | const msg = msg: { | 19822 | const msg = msg: { |
| ... | @@ -21283,7 +21303,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { | ... | @@ -21283,7 +21303,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 21283 | const pt = sema.pt; | 21303 | const pt = sema.pt; |
| 21284 | const zcu = pt.zcu; | 21304 | const zcu = pt.zcu; |
| 21285 | const ip = &zcu.intern_pool; | 21305 | const ip = &zcu.intern_pool; |
| 21286 | const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(0), .StackTrace); | 21306 | const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(.zero), .StackTrace); |
| 21287 | try stack_trace_ty.resolveFields(pt); | 21307 | try stack_trace_ty.resolveFields(pt); |
| 21288 | const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty); | 21308 | const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty); |
| 21289 | const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern()); | 21309 | const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern()); |
| ... | @@ -21305,7 +21325,8 @@ fn zirFrame( | ... | @@ -21305,7 +21325,8 @@ fn zirFrame( |
| 21305 | block: *Block, | 21325 | block: *Block, |
| 21306 | extended: Zir.Inst.Extended.InstData, | 21326 | extended: Zir.Inst.Extended.InstData, |
| 21307 | ) CompileError!Air.Inst.Ref { | 21327 | ) CompileError!Air.Inst.Ref { |
| 21308 | const src = block.nodeOffset(@bitCast(extended.operand)); | 21328 | const src_node: std.zig.Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand))); |
| 21329 | const src = block.nodeOffset(src_node); | ||
| 21309 | return sema.failWithUseOfAsync(block, src); | 21330 | return sema.failWithUseOfAsync(block, src); |
| 21310 | } | 21331 | } |
| 21311 | 21332 | ||
| ... | @@ -21559,13 +21580,13 @@ fn zirReify( | ... | @@ -21559,13 +21580,13 @@ fn zirReify( |
| 21559 | const tracked_inst = try block.trackZir(inst); | 21580 | const tracked_inst = try block.trackZir(inst); |
| 21560 | const src: LazySrcLoc = .{ | 21581 | const src: LazySrcLoc = .{ |
| 21561 | .base_node_inst = tracked_inst, | 21582 | .base_node_inst = tracked_inst, |
| 21562 | .offset = LazySrcLoc.Offset.nodeOffset(0), | 21583 | .offset = LazySrcLoc.Offset.nodeOffset(.zero), |
| 21563 | }; | 21584 | }; |
| 21564 | const operand_src: LazySrcLoc = .{ | 21585 | const operand_src: LazySrcLoc = .{ |
| 21565 | .base_node_inst = tracked_inst, | 21586 | .base_node_inst = tracked_inst, |
| 21566 | .offset = .{ | 21587 | .offset = .{ |
| 21567 | .node_offset_builtin_call_arg = .{ | 21588 | .node_offset_builtin_call_arg = .{ |
| 21568 | .builtin_call_node = 0, // `tracked_inst` is precisely the `reify` instruction, so offset is 0 | 21589 | .builtin_call_node = .zero, // `tracked_inst` is precisely the `reify` instruction, so offset is 0 |
| 21569 | .arg_index = 0, | 21590 | .arg_index = 0, |
| 21570 | }, | 21591 | }, |
| 21571 | }, | 21592 | }, |
| ... | @@ -22873,7 +22894,8 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C | ... | @@ -22873,7 +22894,8 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 22873 | } | 22894 | } |
| 22874 | 22895 | ||
| 22875 | fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { | 22896 | fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 22876 | const src = block.nodeOffset(@bitCast(extended.operand)); | 22897 | const src_node: std.zig.Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand))); |
| 22898 | const src = block.nodeOffset(src_node); | ||
| 22877 | 22899 | ||
| 22878 | const va_list_ty = try sema.getBuiltinType(src, .VaList); | 22900 | const va_list_ty = try sema.getBuiltinType(src, .VaList); |
| 22879 | try sema.requireRuntimeBlock(block, src, null); | 22901 | try sema.requireRuntimeBlock(block, src, null); |
| ... | @@ -24278,12 +24300,12 @@ fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -24278,12 +24300,12 @@ fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 24278 | fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u64 { | 24300 | fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u64 { |
| 24279 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 24301 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 24280 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); | 24302 | const src = block.src(.{ .node_offset_bin_op = inst_data.src_node }); |
| 24281 | const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node }); | 24303 | const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 24282 | const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node }); | 24304 | const field_name_src = block.builtinCallArgSrc(inst_data.src_node, 1); |
| 24283 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 24305 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 24284 | 24306 | ||
| 24285 | const ty = try sema.resolveType(block, lhs_src, extra.lhs); | 24307 | const ty = try sema.resolveType(block, ty_src, extra.lhs); |
| 24286 | const field_name = try sema.resolveConstStringIntern(block, rhs_src, extra.rhs, .{ .simple = .field_name }); | 24308 | const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.rhs, .{ .simple = .field_name }); |
| 24287 | 24309 | ||
| 24288 | const pt = sema.pt; | 24310 | const pt = sema.pt; |
| 24289 | const zcu = pt.zcu; | 24311 | const zcu = pt.zcu; |
| ... | @@ -24291,15 +24313,15 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 | ... | @@ -24291,15 +24313,15 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6 |
| 24291 | try ty.resolveLayout(pt); | 24313 | try ty.resolveLayout(pt); |
| 24292 | switch (ty.zigTypeTag(zcu)) { | 24314 | switch (ty.zigTypeTag(zcu)) { |
| 24293 | .@"struct" => {}, | 24315 | .@"struct" => {}, |
| 24294 | else => return sema.fail(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(pt)}), | 24316 | else => return sema.fail(block, ty_src, "expected struct type, found '{}'", .{ty.fmt(pt)}), |
| 24295 | } | 24317 | } |
| 24296 | 24318 | ||
| 24297 | const field_index = if (ty.isTuple(zcu)) blk: { | 24319 | const field_index = if (ty.isTuple(zcu)) blk: { |
| 24298 | if (field_name.eqlSlice("len", ip)) { | 24320 | if (field_name.eqlSlice("len", ip)) { |
| 24299 | return sema.fail(block, src, "no offset available for 'len' field of tuple", .{}); | 24321 | return sema.fail(block, src, "no offset available for 'len' field of tuple", .{}); |
| 24300 | } | 24322 | } |
| 24301 | break :blk try sema.tupleFieldIndex(block, ty, field_name, rhs_src); | 24323 | break :blk try sema.tupleFieldIndex(block, ty, field_name, field_name_src); |
| 24302 | } else try sema.structFieldIndex(block, ty, field_name, rhs_src); | 24324 | } else try sema.structFieldIndex(block, ty, field_name, field_name_src); |
| 24303 | 24325 | ||
| 24304 | if (ty.structFieldIsComptime(field_index, zcu)) { | 24326 | if (ty.structFieldIsComptime(field_index, zcu)) { |
| 24305 | return sema.fail(block, src, "no offset available for comptime field", .{}); | 24327 | return sema.fail(block, src, "no offset available for comptime field", .{}); |
| ... | @@ -25083,7 +25105,7 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -25083,7 +25105,7 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 25083 | fn analyzeShuffle( | 25105 | fn analyzeShuffle( |
| 25084 | sema: *Sema, | 25106 | sema: *Sema, |
| 25085 | block: *Block, | 25107 | block: *Block, |
| 25086 | src_node: i32, | 25108 | src_node: std.zig.Ast.Node.Offset, |
| 25087 | elem_ty: Type, | 25109 | elem_ty: Type, |
| 25088 | a_arg: Air.Inst.Ref, | 25110 | a_arg: Air.Inst.Ref, |
| 25089 | b_arg: Air.Inst.Ref, | 25111 | b_arg: Air.Inst.Ref, |
| ... | @@ -27010,7 +27032,8 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD | ... | @@ -27010,7 +27032,8 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD |
| 27010 | const gpa = zcu.gpa; | 27032 | const gpa = zcu.gpa; |
| 27011 | const ip = &zcu.intern_pool; | 27033 | const ip = &zcu.intern_pool; |
| 27012 | 27034 | ||
| 27013 | const src = block.nodeOffset(@bitCast(extended.operand)); | 27035 | const src_node: std.zig.Ast.Node.Offset = @enumFromInt(@as(i32, @bitCast(extended.operand))); |
| 27036 | const src = block.nodeOffset(src_node); | ||
| 27014 | const value: Zir.Inst.BuiltinValue = @enumFromInt(extended.small); | 27037 | const value: Zir.Inst.BuiltinValue = @enumFromInt(extended.small); |
| 27015 | 27038 | ||
| 27016 | const ty = switch (value) { | 27039 | const ty = switch (value) { |
| ... | @@ -29485,7 +29508,7 @@ const CoerceOpts = struct { | ... | @@ -29485,7 +29508,7 @@ const CoerceOpts = struct { |
| 29485 | return .{ | 29508 | return .{ |
| 29486 | .base_node_inst = func_inst, | 29509 | .base_node_inst = func_inst, |
| 29487 | .offset = .{ .fn_proto_param_type = .{ | 29510 | .offset = .{ .fn_proto_param_type = .{ |
| 29488 | .fn_proto_node_offset = 0, | 29511 | .fn_proto_node_offset = .zero, |
| 29489 | .param_index = info.param_i, | 29512 | .param_index = info.param_i, |
| 29490 | } }, | 29513 | } }, |
| 29491 | }; | 29514 | }; |
| ... | @@ -30090,7 +30113,7 @@ fn coerceExtra( | ... | @@ -30090,7 +30113,7 @@ fn coerceExtra( |
| 30090 | 30113 | ||
| 30091 | const ret_ty_src: LazySrcLoc = .{ | 30114 | const ret_ty_src: LazySrcLoc = .{ |
| 30092 | .base_node_inst = ip.getNav(zcu.funcInfo(sema.func_index).owner_nav).srcInst(ip), | 30115 | .base_node_inst = ip.getNav(zcu.funcInfo(sema.func_index).owner_nav).srcInst(ip), |
| 30093 | .offset = .{ .node_offset_fn_type_ret_ty = 0 }, | 30116 | .offset = .{ .node_offset_fn_type_ret_ty = .zero }, |
| 30094 | }; | 30117 | }; |
| 30095 | try sema.errNote(ret_ty_src, msg, "'noreturn' declared here", .{}); | 30118 | try sema.errNote(ret_ty_src, msg, "'noreturn' declared here", .{}); |
| 30096 | break :msg msg; | 30119 | break :msg msg; |
| ... | @@ -30130,7 +30153,7 @@ fn coerceExtra( | ... | @@ -30130,7 +30153,7 @@ fn coerceExtra( |
| 30130 | { | 30153 | { |
| 30131 | const ret_ty_src: LazySrcLoc = .{ | 30154 | const ret_ty_src: LazySrcLoc = .{ |
| 30132 | .base_node_inst = ip.getNav(zcu.funcInfo(sema.func_index).owner_nav).srcInst(ip), | 30155 | .base_node_inst = ip.getNav(zcu.funcInfo(sema.func_index).owner_nav).srcInst(ip), |
| 30133 | .offset = .{ .node_offset_fn_type_ret_ty = 0 }, | 30156 | .offset = .{ .node_offset_fn_type_ret_ty = .zero }, |
| 30134 | }; | 30157 | }; |
| 30135 | if (inst_ty.isError(zcu) and !dest_ty.isError(zcu)) { | 30158 | if (inst_ty.isError(zcu) and !dest_ty.isError(zcu)) { |
| 30136 | try sema.errNote(ret_ty_src, msg, "function cannot return an error", .{}); | 30159 | try sema.errNote(ret_ty_src, msg, "function cannot return an error", .{}); |
| ... | @@ -32331,7 +32354,7 @@ pub fn ensureNavResolved(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav | ... | @@ -32331,7 +32354,7 @@ pub fn ensureNavResolved(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav |
| 32331 | if (zcu.analysis_in_progress.contains(anal_unit)) { | 32354 | if (zcu.analysis_in_progress.contains(anal_unit)) { |
| 32332 | return sema.failWithOwnedErrorMsg(null, try sema.errMsg(.{ | 32355 | return sema.failWithOwnedErrorMsg(null, try sema.errMsg(.{ |
| 32333 | .base_node_inst = nav.analysis.?.zir_index, | 32356 | .base_node_inst = nav.analysis.?.zir_index, |
| 32334 | .offset = LazySrcLoc.Offset.nodeOffset(0), | 32357 | .offset = LazySrcLoc.Offset.nodeOffset(.zero), |
| 32335 | }, "dependency loop detected", .{})); | 32358 | }, "dependency loop detected", .{})); |
| 32336 | } | 32359 | } |
| 32337 | 32360 | ||
| ... | @@ -33948,7 +33971,7 @@ const PeerTypeCandidateSrc = union(enum) { | ... | @@ -33948,7 +33971,7 @@ const PeerTypeCandidateSrc = union(enum) { |
| 33948 | /// index i in this slice | 33971 | /// index i in this slice |
| 33949 | override: []const ?LazySrcLoc, | 33972 | override: []const ?LazySrcLoc, |
| 33950 | /// resolvePeerTypes originates from a @TypeOf(...) call | 33973 | /// resolvePeerTypes originates from a @TypeOf(...) call |
| 33951 | typeof_builtin_call_node_offset: i32, | 33974 | typeof_builtin_call_node_offset: std.zig.Ast.Node.Offset, |
| 33952 | 33975 | ||
| 33953 | pub fn resolve( | 33976 | pub fn resolve( |
| 33954 | self: PeerTypeCandidateSrc, | 33977 | self: PeerTypeCandidateSrc, |
| ... | @@ -35551,7 +35574,7 @@ fn backingIntType( | ... | @@ -35551,7 +35574,7 @@ fn backingIntType( |
| 35551 | 35574 | ||
| 35552 | const backing_int_src: LazySrcLoc = .{ | 35575 | const backing_int_src: LazySrcLoc = .{ |
| 35553 | .base_node_inst = struct_type.zir_index, | 35576 | .base_node_inst = struct_type.zir_index, |
| 35554 | .offset = .{ .node_offset_container_tag = 0 }, | 35577 | .offset = .{ .node_offset_container_tag = .zero }, |
| 35555 | }; | 35578 | }; |
| 35556 | block.comptime_reason = .{ .reason = .{ | 35579 | block.comptime_reason = .{ .reason = .{ |
| 35557 | .src = backing_int_src, | 35580 | .src = backing_int_src, |
| ... | @@ -35572,7 +35595,7 @@ fn backingIntType( | ... | @@ -35572,7 +35595,7 @@ fn backingIntType( |
| 35572 | struct_type.setBackingIntType(ip, backing_int_ty.toIntern()); | 35595 | struct_type.setBackingIntType(ip, backing_int_ty.toIntern()); |
| 35573 | } else { | 35596 | } else { |
| 35574 | if (fields_bit_sum > std.math.maxInt(u16)) { | 35597 | if (fields_bit_sum > std.math.maxInt(u16)) { |
| 35575 | return sema.fail(&block, block.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum}); | 35598 | return sema.fail(&block, block.nodeOffset(.zero), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum}); |
| 35576 | } | 35599 | } |
| 35577 | const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum)); | 35600 | const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum)); |
| 35578 | struct_type.setBackingIntType(ip, backing_int_ty.toIntern()); | 35601 | struct_type.setBackingIntType(ip, backing_int_ty.toIntern()); |
| ... | @@ -36173,7 +36196,7 @@ fn structFields( | ... | @@ -36173,7 +36196,7 @@ fn structFields( |
| 36173 | .comptime_reason = .{ .reason = .{ | 36196 | .comptime_reason = .{ .reason = .{ |
| 36174 | .src = .{ | 36197 | .src = .{ |
| 36175 | .base_node_inst = struct_type.zir_index, | 36198 | .base_node_inst = struct_type.zir_index, |
| 36176 | .offset = .nodeOffset(0), | 36199 | .offset = .nodeOffset(.zero), |
| 36177 | }, | 36200 | }, |
| 36178 | .r = .{ .simple = .struct_fields }, | 36201 | .r = .{ .simple = .struct_fields }, |
| 36179 | } }, | 36202 | } }, |
| ... | @@ -36514,7 +36537,7 @@ fn unionFields( | ... | @@ -36514,7 +36537,7 @@ fn unionFields( |
| 36514 | 36537 | ||
| 36515 | const src: LazySrcLoc = .{ | 36538 | const src: LazySrcLoc = .{ |
| 36516 | .base_node_inst = union_type.zir_index, | 36539 | .base_node_inst = union_type.zir_index, |
| 36517 | .offset = .nodeOffset(0), | 36540 | .offset = .nodeOffset(.zero), |
| 36518 | }; | 36541 | }; |
| 36519 | 36542 | ||
| 36520 | var block_scope: Block = .{ | 36543 | var block_scope: Block = .{ |
| ... | @@ -36543,7 +36566,7 @@ fn unionFields( | ... | @@ -36543,7 +36566,7 @@ fn unionFields( |
| 36543 | if (tag_type_ref != .none) { | 36566 | if (tag_type_ref != .none) { |
| 36544 | const tag_ty_src: LazySrcLoc = .{ | 36567 | const tag_ty_src: LazySrcLoc = .{ |
| 36545 | .base_node_inst = union_type.zir_index, | 36568 | .base_node_inst = union_type.zir_index, |
| 36546 | .offset = .{ .node_offset_container_tag = 0 }, | 36569 | .offset = .{ .node_offset_container_tag = .zero }, |
| 36547 | }; | 36570 | }; |
| 36548 | const provided_ty = try sema.resolveType(&block_scope, tag_ty_src, tag_type_ref); | 36571 | const provided_ty = try sema.resolveType(&block_scope, tag_ty_src, tag_type_ref); |
| 36549 | if (small.auto_enum_tag) { | 36572 | if (small.auto_enum_tag) { |
| ... | @@ -38523,7 +38546,7 @@ pub fn resolveDeclaredEnum( | ... | @@ -38523,7 +38546,7 @@ pub fn resolveDeclaredEnum( |
| 38523 | const zcu = pt.zcu; | 38546 | const zcu = pt.zcu; |
| 38524 | const gpa = zcu.gpa; | 38547 | const gpa = zcu.gpa; |
| 38525 | 38548 | ||
| 38526 | const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(0) }; | 38549 | const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(.zero) }; |
| 38527 | 38550 | ||
| 38528 | var arena: std.heap.ArenaAllocator = .init(gpa); | 38551 | var arena: std.heap.ArenaAllocator = .init(gpa); |
| 38529 | defer arena.deinit(); | 38552 | defer arena.deinit(); |
| ... | @@ -38610,7 +38633,7 @@ fn resolveDeclaredEnumInner( | ... | @@ -38610,7 +38633,7 @@ fn resolveDeclaredEnumInner( |
| 38610 | 38633 | ||
| 38611 | const bit_bags_count = std.math.divCeil(usize, fields_len, 32) catch unreachable; | 38634 | const bit_bags_count = std.math.divCeil(usize, fields_len, 32) catch unreachable; |
| 38612 | 38635 | ||
| 38613 | const tag_ty_src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = .{ .node_offset_container_tag = 0 } }; | 38636 | const tag_ty_src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = .{ .node_offset_container_tag = .zero } }; |
| 38614 | 38637 | ||
| 38615 | const int_tag_ty = ty: { | 38638 | const int_tag_ty = ty: { |
| 38616 | if (body.len != 0) { | 38639 | if (body.len != 0) { |
| ... | @@ -38763,9 +38786,9 @@ pub fn resolveNavPtrModifiers( | ... | @@ -38763,9 +38786,9 @@ pub fn resolveNavPtrModifiers( |
| 38763 | const gpa = zcu.gpa; | 38786 | const gpa = zcu.gpa; |
| 38764 | const ip = &zcu.intern_pool; | 38787 | const ip = &zcu.intern_pool; |
| 38765 | 38788 | ||
| 38766 | const align_src = block.src(.{ .node_offset_var_decl_align = 0 }); | 38789 | const align_src = block.src(.{ .node_offset_var_decl_align = .zero }); |
| 38767 | const section_src = block.src(.{ .node_offset_var_decl_section = 0 }); | 38790 | const section_src = block.src(.{ .node_offset_var_decl_section = .zero }); |
| 38768 | const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = 0 }); | 38791 | const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = .zero }); |
| 38769 | 38792 | ||
| 38770 | const alignment: InternPool.Alignment = a: { | 38793 | const alignment: InternPool.Alignment = a: { |
| 38771 | const align_body = zir_decl.align_body orelse break :a .none; | 38794 | const align_body = zir_decl.align_body orelse break :a .none; |
| ... | @@ -38838,7 +38861,7 @@ pub fn analyzeMemoizedState(sema: *Sema, block: *Block, simple_src: LazySrcLoc, | ... | @@ -38838,7 +38861,7 @@ pub fn analyzeMemoizedState(sema: *Sema, block: *Block, simple_src: LazySrcLoc, |
| 38838 | 38861 | ||
| 38839 | const src: LazySrcLoc = .{ | 38862 | const src: LazySrcLoc = .{ |
| 38840 | .base_node_inst = ip.getNav(nav).srcInst(ip), | 38863 | .base_node_inst = ip.getNav(nav).srcInst(ip), |
| 38841 | .offset = .nodeOffset(0), | 38864 | .offset = .nodeOffset(.zero), |
| 38842 | }; | 38865 | }; |
| 38843 | 38866 | ||
| 38844 | const result = try sema.analyzeNavVal(block, src, nav); | 38867 | 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+284-314| ... | @@ -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, |
| ... | @@ -1034,10 +1034,6 @@ pub const SrcLoc = struct { | ... | @@ -1034,10 +1034,6 @@ pub const SrcLoc = struct { |
| 1034 | return tree.firstToken(src_loc.base_node); | 1034 | return tree.firstToken(src_loc.base_node); |
| 1035 | } | 1035 | } |
| 1036 | 1036 | ||
| 1037 | pub fn relativeToNodeIndex(src_loc: SrcLoc, offset: i32) Ast.Node.Index { | ||
| 1038 | return @bitCast(offset + @as(i32, @bitCast(src_loc.base_node))); | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | pub const Span = Ast.Span; | 1037 | pub const Span = Ast.Span; |
| 1042 | 1038 | ||
| 1043 | pub fn span(src_loc: SrcLoc, gpa: Allocator) !Span { | 1039 | pub fn span(src_loc: SrcLoc, gpa: Allocator) !Span { |
| ... | @@ -1049,7 +1045,7 @@ pub const SrcLoc = struct { | ... | @@ -1049,7 +1045,7 @@ pub const SrcLoc = struct { |
| 1049 | 1045 | ||
| 1050 | .token_abs => |tok_index| { | 1046 | .token_abs => |tok_index| { |
| 1051 | const tree = try src_loc.file_scope.getTree(gpa); | 1047 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1052 | const start = tree.tokens.items(.start)[tok_index]; | 1048 | const start = tree.tokenStart(tok_index); |
| 1053 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1049 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1054 | return Span{ .start = start, .end = end, .main = start }; | 1050 | return Span{ .start = start, .end = end, .main = start }; |
| 1055 | }, | 1051 | }, |
| ... | @@ -1060,142 +1056,137 @@ pub const SrcLoc = struct { | ... | @@ -1060,142 +1056,137 @@ pub const SrcLoc = struct { |
| 1060 | .byte_offset => |byte_off| { | 1056 | .byte_offset => |byte_off| { |
| 1061 | const tree = try src_loc.file_scope.getTree(gpa); | 1057 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1062 | const tok_index = src_loc.baseSrcToken(); | 1058 | const tok_index = src_loc.baseSrcToken(); |
| 1063 | const start = tree.tokens.items(.start)[tok_index] + byte_off; | 1059 | const start = tree.tokenStart(tok_index) + byte_off; |
| 1064 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1060 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1065 | return Span{ .start = start, .end = end, .main = start }; | 1061 | return Span{ .start = start, .end = end, .main = start }; |
| 1066 | }, | 1062 | }, |
| 1067 | .token_offset => |tok_off| { | 1063 | .token_offset => |tok_off| { |
| 1068 | const tree = try src_loc.file_scope.getTree(gpa); | 1064 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1069 | const tok_index = src_loc.baseSrcToken() + tok_off; | 1065 | const tok_index = tok_off.toAbsolute(src_loc.baseSrcToken()); |
| 1070 | const start = tree.tokens.items(.start)[tok_index]; | 1066 | const start = tree.tokenStart(tok_index); |
| 1071 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1067 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1072 | return Span{ .start = start, .end = end, .main = start }; | 1068 | return Span{ .start = start, .end = end, .main = start }; |
| 1073 | }, | 1069 | }, |
| 1074 | .node_offset => |traced_off| { | 1070 | .node_offset => |traced_off| { |
| 1075 | const node_off = traced_off.x; | 1071 | const node_off = traced_off.x; |
| 1076 | const tree = try src_loc.file_scope.getTree(gpa); | 1072 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1077 | const node = src_loc.relativeToNodeIndex(node_off); | 1073 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1078 | return tree.nodeToSpan(node); | 1074 | return tree.nodeToSpan(node); |
| 1079 | }, | 1075 | }, |
| 1080 | .node_offset_main_token => |node_off| { | 1076 | .node_offset_main_token => |node_off| { |
| 1081 | const tree = try src_loc.file_scope.getTree(gpa); | 1077 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1082 | const node = src_loc.relativeToNodeIndex(node_off); | 1078 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1083 | const main_token = tree.nodes.items(.main_token)[node]; | 1079 | const main_token = tree.nodeMainToken(node); |
| 1084 | return tree.tokensToSpan(main_token, main_token, main_token); | 1080 | return tree.tokensToSpan(main_token, main_token, main_token); |
| 1085 | }, | 1081 | }, |
| 1086 | .node_offset_bin_op => |node_off| { | 1082 | .node_offset_bin_op => |node_off| { |
| 1087 | const tree = try src_loc.file_scope.getTree(gpa); | 1083 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1088 | const node = src_loc.relativeToNodeIndex(node_off); | 1084 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1089 | return tree.nodeToSpan(node); | 1085 | return tree.nodeToSpan(node); |
| 1090 | }, | 1086 | }, |
| 1091 | .node_offset_initializer => |node_off| { | 1087 | .node_offset_initializer => |node_off| { |
| 1092 | const tree = try src_loc.file_scope.getTree(gpa); | 1088 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1093 | const node = src_loc.relativeToNodeIndex(node_off); | 1089 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1094 | return tree.tokensToSpan( | 1090 | return tree.tokensToSpan( |
| 1095 | tree.firstToken(node) - 3, | 1091 | tree.firstToken(node) - 3, |
| 1096 | tree.lastToken(node), | 1092 | tree.lastToken(node), |
| 1097 | tree.nodes.items(.main_token)[node] - 2, | 1093 | tree.nodeMainToken(node) - 2, |
| 1098 | ); | 1094 | ); |
| 1099 | }, | 1095 | }, |
| 1100 | .node_offset_var_decl_ty => |node_off| { | 1096 | .node_offset_var_decl_ty => |node_off| { |
| 1101 | const tree = try src_loc.file_scope.getTree(gpa); | 1097 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1102 | const node = src_loc.relativeToNodeIndex(node_off); | 1098 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1103 | const node_tags = tree.nodes.items(.tag); | 1099 | const full = switch (tree.nodeTag(node)) { |
| 1104 | const full = switch (node_tags[node]) { | ||
| 1105 | .global_var_decl, | 1100 | .global_var_decl, |
| 1106 | .local_var_decl, | 1101 | .local_var_decl, |
| 1107 | .simple_var_decl, | 1102 | .simple_var_decl, |
| 1108 | .aligned_var_decl, | 1103 | .aligned_var_decl, |
| 1109 | => tree.fullVarDecl(node).?, | 1104 | => tree.fullVarDecl(node).?, |
| 1110 | .@"usingnamespace" => { | 1105 | .@"usingnamespace" => { |
| 1111 | const node_data = tree.nodes.items(.data); | 1106 | return tree.nodeToSpan(tree.nodeData(node).node); |
| 1112 | return tree.nodeToSpan(node_data[node].lhs); | ||
| 1113 | }, | 1107 | }, |
| 1114 | else => unreachable, | 1108 | else => unreachable, |
| 1115 | }; | 1109 | }; |
| 1116 | if (full.ast.type_node != 0) { | 1110 | if (full.ast.type_node.unwrap()) |type_node| { |
| 1117 | return tree.nodeToSpan(full.ast.type_node); | 1111 | return tree.nodeToSpan(type_node); |
| 1118 | } | 1112 | } |
| 1119 | const tok_index = full.ast.mut_token + 1; // the name token | 1113 | const tok_index = full.ast.mut_token + 1; // the name token |
| 1120 | const start = tree.tokens.items(.start)[tok_index]; | 1114 | const start = tree.tokenStart(tok_index); |
| 1121 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1115 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1122 | return Span{ .start = start, .end = end, .main = start }; | 1116 | return Span{ .start = start, .end = end, .main = start }; |
| 1123 | }, | 1117 | }, |
| 1124 | .node_offset_var_decl_align => |node_off| { | 1118 | .node_offset_var_decl_align => |node_off| { |
| 1125 | const tree = try src_loc.file_scope.getTree(gpa); | 1119 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1126 | const node = src_loc.relativeToNodeIndex(node_off); | 1120 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1127 | var buf: [1]Ast.Node.Index = undefined; | 1121 | var buf: [1]Ast.Node.Index = undefined; |
| 1128 | const align_node = if (tree.fullVarDecl(node)) |v| | 1122 | const align_node = if (tree.fullVarDecl(node)) |v| |
| 1129 | v.ast.align_node | 1123 | v.ast.align_node.unwrap().? |
| 1130 | else if (tree.fullFnProto(&buf, node)) |f| | 1124 | else if (tree.fullFnProto(&buf, node)) |f| |
| 1131 | f.ast.align_expr | 1125 | f.ast.align_expr.unwrap().? |
| 1132 | else | 1126 | else |
| 1133 | unreachable; | 1127 | unreachable; |
| 1134 | return tree.nodeToSpan(align_node); | 1128 | return tree.nodeToSpan(align_node); |
| 1135 | }, | 1129 | }, |
| 1136 | .node_offset_var_decl_section => |node_off| { | 1130 | .node_offset_var_decl_section => |node_off| { |
| 1137 | const tree = try src_loc.file_scope.getTree(gpa); | 1131 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1138 | const node = src_loc.relativeToNodeIndex(node_off); | 1132 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1139 | var buf: [1]Ast.Node.Index = undefined; | 1133 | var buf: [1]Ast.Node.Index = undefined; |
| 1140 | const section_node = if (tree.fullVarDecl(node)) |v| | 1134 | const section_node = if (tree.fullVarDecl(node)) |v| |
| 1141 | v.ast.section_node | 1135 | v.ast.section_node.unwrap().? |
| 1142 | else if (tree.fullFnProto(&buf, node)) |f| | 1136 | else if (tree.fullFnProto(&buf, node)) |f| |
| 1143 | f.ast.section_expr | 1137 | f.ast.section_expr.unwrap().? |
| 1144 | else | 1138 | else |
| 1145 | unreachable; | 1139 | unreachable; |
| 1146 | return tree.nodeToSpan(section_node); | 1140 | return tree.nodeToSpan(section_node); |
| 1147 | }, | 1141 | }, |
| 1148 | .node_offset_var_decl_addrspace => |node_off| { | 1142 | .node_offset_var_decl_addrspace => |node_off| { |
| 1149 | const tree = try src_loc.file_scope.getTree(gpa); | 1143 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1150 | const node = src_loc.relativeToNodeIndex(node_off); | 1144 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1151 | var buf: [1]Ast.Node.Index = undefined; | 1145 | var buf: [1]Ast.Node.Index = undefined; |
| 1152 | const addrspace_node = if (tree.fullVarDecl(node)) |v| | 1146 | const addrspace_node = if (tree.fullVarDecl(node)) |v| |
| 1153 | v.ast.addrspace_node | 1147 | v.ast.addrspace_node.unwrap().? |
| 1154 | else if (tree.fullFnProto(&buf, node)) |f| | 1148 | else if (tree.fullFnProto(&buf, node)) |f| |
| 1155 | f.ast.addrspace_expr | 1149 | f.ast.addrspace_expr.unwrap().? |
| 1156 | else | 1150 | else |
| 1157 | unreachable; | 1151 | unreachable; |
| 1158 | return tree.nodeToSpan(addrspace_node); | 1152 | return tree.nodeToSpan(addrspace_node); |
| 1159 | }, | 1153 | }, |
| 1160 | .node_offset_var_decl_init => |node_off| { | 1154 | .node_offset_var_decl_init => |node_off| { |
| 1161 | const tree = try src_loc.file_scope.getTree(gpa); | 1155 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1162 | const node = src_loc.relativeToNodeIndex(node_off); | 1156 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1163 | const full = tree.fullVarDecl(node).?; | 1157 | const init_node = switch (tree.nodeTag(node)) { |
| 1164 | return tree.nodeToSpan(full.ast.init_node); | 1158 | .global_var_decl, |
| 1159 | .local_var_decl, | ||
| 1160 | .aligned_var_decl, | ||
| 1161 | .simple_var_decl, | ||
| 1162 | => tree.fullVarDecl(node).?.ast.init_node.unwrap().?, | ||
| 1163 | .assign_destructure => tree.assignDestructure(node).ast.value_expr, | ||
| 1164 | else => unreachable, | ||
| 1165 | }; | ||
| 1166 | return tree.nodeToSpan(init_node); | ||
| 1165 | }, | 1167 | }, |
| 1166 | .node_offset_builtin_call_arg => |builtin_arg| { | 1168 | .node_offset_builtin_call_arg => |builtin_arg| { |
| 1167 | const tree = try src_loc.file_scope.getTree(gpa); | 1169 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1168 | const node_datas = tree.nodes.items(.data); | 1170 | const node = builtin_arg.builtin_call_node.toAbsolute(src_loc.base_node); |
| 1169 | const node_tags = tree.nodes.items(.tag); | 1171 | var buf: [2]Ast.Node.Index = undefined; |
| 1170 | const node = src_loc.relativeToNodeIndex(builtin_arg.builtin_call_node); | 1172 | const params = tree.builtinCallParams(&buf, node).?; |
| 1171 | const param = switch (node_tags[node]) { | 1173 | return tree.nodeToSpan(params[builtin_arg.arg_index]); |
| 1172 | .builtin_call_two, .builtin_call_two_comma => switch (builtin_arg.arg_index) { | ||
| 1173 | 0 => node_datas[node].lhs, | ||
| 1174 | 1 => node_datas[node].rhs, | ||
| 1175 | else => unreachable, | ||
| 1176 | }, | ||
| 1177 | .builtin_call, .builtin_call_comma => tree.extra_data[node_datas[node].lhs + builtin_arg.arg_index], | ||
| 1178 | else => unreachable, | ||
| 1179 | }; | ||
| 1180 | return tree.nodeToSpan(param); | ||
| 1181 | }, | 1174 | }, |
| 1182 | .node_offset_ptrcast_operand => |node_off| { | 1175 | .node_offset_ptrcast_operand => |node_off| { |
| 1183 | const tree = try src_loc.file_scope.getTree(gpa); | 1176 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1184 | const main_tokens = tree.nodes.items(.main_token); | ||
| 1185 | const node_datas = tree.nodes.items(.data); | ||
| 1186 | const node_tags = tree.nodes.items(.tag); | ||
| 1187 | 1177 | ||
| 1188 | var node = src_loc.relativeToNodeIndex(node_off); | 1178 | var node = node_off.toAbsolute(src_loc.base_node); |
| 1189 | while (true) { | 1179 | while (true) { |
| 1190 | switch (node_tags[node]) { | 1180 | switch (tree.nodeTag(node)) { |
| 1191 | .builtin_call_two, .builtin_call_two_comma => {}, | 1181 | .builtin_call_two, .builtin_call_two_comma => {}, |
| 1192 | else => break, | 1182 | else => break, |
| 1193 | } | 1183 | } |
| 1194 | 1184 | ||
| 1195 | if (node_datas[node].lhs == 0) break; // 0 args | 1185 | const first_arg, const second_arg = tree.nodeData(node).opt_node_and_opt_node; |
| 1196 | if (node_datas[node].rhs != 0) break; // 2 args | 1186 | if (first_arg == .none) break; // 0 args |
| 1187 | if (second_arg != .none) break; // 2 args | ||
| 1197 | 1188 | ||
| 1198 | const builtin_token = main_tokens[node]; | 1189 | const builtin_token = tree.nodeMainToken(node); |
| 1199 | const builtin_name = tree.tokenSlice(builtin_token); | 1190 | const builtin_name = tree.tokenSlice(builtin_token); |
| 1200 | const info = BuiltinFn.list.get(builtin_name) orelse break; | 1191 | const info = BuiltinFn.list.get(builtin_name) orelse break; |
| 1201 | 1192 | ||
| ... | @@ -1209,16 +1200,15 @@ pub const SrcLoc = struct { | ... | @@ -1209,16 +1200,15 @@ pub const SrcLoc = struct { |
| 1209 | => {}, | 1200 | => {}, |
| 1210 | } | 1201 | } |
| 1211 | 1202 | ||
| 1212 | node = node_datas[node].lhs; | 1203 | node = first_arg.unwrap().?; |
| 1213 | } | 1204 | } |
| 1214 | 1205 | ||
| 1215 | return tree.nodeToSpan(node); | 1206 | return tree.nodeToSpan(node); |
| 1216 | }, | 1207 | }, |
| 1217 | .node_offset_array_access_index => |node_off| { | 1208 | .node_offset_array_access_index => |node_off| { |
| 1218 | const tree = try src_loc.file_scope.getTree(gpa); | 1209 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1219 | const node_datas = tree.nodes.items(.data); | 1210 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1220 | const node = src_loc.relativeToNodeIndex(node_off); | 1211 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[1]); |
| 1221 | return tree.nodeToSpan(node_datas[node].rhs); | ||
| 1222 | }, | 1212 | }, |
| 1223 | .node_offset_slice_ptr, | 1213 | .node_offset_slice_ptr, |
| 1224 | .node_offset_slice_start, | 1214 | .node_offset_slice_start, |
| ... | @@ -1226,32 +1216,30 @@ pub const SrcLoc = struct { | ... | @@ -1226,32 +1216,30 @@ pub const SrcLoc = struct { |
| 1226 | .node_offset_slice_sentinel, | 1216 | .node_offset_slice_sentinel, |
| 1227 | => |node_off| { | 1217 | => |node_off| { |
| 1228 | const tree = try src_loc.file_scope.getTree(gpa); | 1218 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1229 | const node = src_loc.relativeToNodeIndex(node_off); | 1219 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1230 | const full = tree.fullSlice(node).?; | 1220 | const full = tree.fullSlice(node).?; |
| 1231 | const part_node = switch (src_loc.lazy) { | 1221 | const part_node = switch (src_loc.lazy) { |
| 1232 | .node_offset_slice_ptr => full.ast.sliced, | 1222 | .node_offset_slice_ptr => full.ast.sliced, |
| 1233 | .node_offset_slice_start => full.ast.start, | 1223 | .node_offset_slice_start => full.ast.start, |
| 1234 | .node_offset_slice_end => full.ast.end, | 1224 | .node_offset_slice_end => full.ast.end.unwrap().?, |
| 1235 | .node_offset_slice_sentinel => full.ast.sentinel, | 1225 | .node_offset_slice_sentinel => full.ast.sentinel.unwrap().?, |
| 1236 | else => unreachable, | 1226 | else => unreachable, |
| 1237 | }; | 1227 | }; |
| 1238 | return tree.nodeToSpan(part_node); | 1228 | return tree.nodeToSpan(part_node); |
| 1239 | }, | 1229 | }, |
| 1240 | .node_offset_call_func => |node_off| { | 1230 | .node_offset_call_func => |node_off| { |
| 1241 | const tree = try src_loc.file_scope.getTree(gpa); | 1231 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1242 | const node = src_loc.relativeToNodeIndex(node_off); | 1232 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1243 | var buf: [1]Ast.Node.Index = undefined; | 1233 | var buf: [1]Ast.Node.Index = undefined; |
| 1244 | const full = tree.fullCall(&buf, node).?; | 1234 | const full = tree.fullCall(&buf, node).?; |
| 1245 | return tree.nodeToSpan(full.ast.fn_expr); | 1235 | return tree.nodeToSpan(full.ast.fn_expr); |
| 1246 | }, | 1236 | }, |
| 1247 | .node_offset_field_name => |node_off| { | 1237 | .node_offset_field_name => |node_off| { |
| 1248 | const tree = try src_loc.file_scope.getTree(gpa); | 1238 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1249 | const node_datas = tree.nodes.items(.data); | 1239 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1250 | const node_tags = tree.nodes.items(.tag); | ||
| 1251 | const node = src_loc.relativeToNodeIndex(node_off); | ||
| 1252 | var buf: [1]Ast.Node.Index = undefined; | 1240 | var buf: [1]Ast.Node.Index = undefined; |
| 1253 | const tok_index = switch (node_tags[node]) { | 1241 | const tok_index = switch (tree.nodeTag(node)) { |
| 1254 | .field_access => node_datas[node].rhs, | 1242 | .field_access => tree.nodeData(node).node_and_token[1], |
| 1255 | .call_one, | 1243 | .call_one, |
| 1256 | .call_one_comma, | 1244 | .call_one_comma, |
| 1257 | .async_call_one, | 1245 | .async_call_one, |
| ... | @@ -1266,43 +1254,41 @@ pub const SrcLoc = struct { | ... | @@ -1266,43 +1254,41 @@ pub const SrcLoc = struct { |
| 1266 | }, | 1254 | }, |
| 1267 | else => tree.firstToken(node) - 2, | 1255 | else => tree.firstToken(node) - 2, |
| 1268 | }; | 1256 | }; |
| 1269 | const start = tree.tokens.items(.start)[tok_index]; | 1257 | const start = tree.tokenStart(tok_index); |
| 1270 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1258 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1271 | return Span{ .start = start, .end = end, .main = start }; | 1259 | return Span{ .start = start, .end = end, .main = start }; |
| 1272 | }, | 1260 | }, |
| 1273 | .node_offset_field_name_init => |node_off| { | 1261 | .node_offset_field_name_init => |node_off| { |
| 1274 | const tree = try src_loc.file_scope.getTree(gpa); | 1262 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1275 | const node = src_loc.relativeToNodeIndex(node_off); | 1263 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1276 | const tok_index = tree.firstToken(node) - 2; | 1264 | const tok_index = tree.firstToken(node) - 2; |
| 1277 | const start = tree.tokens.items(.start)[tok_index]; | 1265 | const start = tree.tokenStart(tok_index); |
| 1278 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1266 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1279 | return Span{ .start = start, .end = end, .main = start }; | 1267 | return Span{ .start = start, .end = end, .main = start }; |
| 1280 | }, | 1268 | }, |
| 1281 | .node_offset_deref_ptr => |node_off| { | 1269 | .node_offset_deref_ptr => |node_off| { |
| 1282 | const tree = try src_loc.file_scope.getTree(gpa); | 1270 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1283 | const node = src_loc.relativeToNodeIndex(node_off); | 1271 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1284 | return tree.nodeToSpan(node); | 1272 | return tree.nodeToSpan(node); |
| 1285 | }, | 1273 | }, |
| 1286 | .node_offset_asm_source => |node_off| { | 1274 | .node_offset_asm_source => |node_off| { |
| 1287 | const tree = try src_loc.file_scope.getTree(gpa); | 1275 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1288 | const node = src_loc.relativeToNodeIndex(node_off); | 1276 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1289 | const full = tree.fullAsm(node).?; | 1277 | const full = tree.fullAsm(node).?; |
| 1290 | return tree.nodeToSpan(full.ast.template); | 1278 | return tree.nodeToSpan(full.ast.template); |
| 1291 | }, | 1279 | }, |
| 1292 | .node_offset_asm_ret_ty => |node_off| { | 1280 | .node_offset_asm_ret_ty => |node_off| { |
| 1293 | const tree = try src_loc.file_scope.getTree(gpa); | 1281 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1294 | const node = src_loc.relativeToNodeIndex(node_off); | 1282 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1295 | const full = tree.fullAsm(node).?; | 1283 | const full = tree.fullAsm(node).?; |
| 1296 | const asm_output = full.outputs[0]; | 1284 | const asm_output = full.outputs[0]; |
| 1297 | const node_datas = tree.nodes.items(.data); | 1285 | return tree.nodeToSpan(tree.nodeData(asm_output).opt_node_and_token[0].unwrap().?); |
| 1298 | return tree.nodeToSpan(node_datas[asm_output].lhs); | ||
| 1299 | }, | 1286 | }, |
| 1300 | 1287 | ||
| 1301 | .node_offset_if_cond => |node_off| { | 1288 | .node_offset_if_cond => |node_off| { |
| 1302 | const tree = try src_loc.file_scope.getTree(gpa); | 1289 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1303 | const node = src_loc.relativeToNodeIndex(node_off); | 1290 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1304 | const node_tags = tree.nodes.items(.tag); | 1291 | const src_node = switch (tree.nodeTag(node)) { |
| 1305 | const src_node = switch (node_tags[node]) { | ||
| 1306 | .if_simple, | 1292 | .if_simple, |
| 1307 | .@"if", | 1293 | .@"if", |
| 1308 | => tree.fullIf(node).?.ast.cond_expr, | 1294 | => tree.fullIf(node).?.ast.cond_expr, |
| ... | @@ -1329,20 +1315,19 @@ pub const SrcLoc = struct { | ... | @@ -1329,20 +1315,19 @@ pub const SrcLoc = struct { |
| 1329 | }, | 1315 | }, |
| 1330 | .for_input => |for_input| { | 1316 | .for_input => |for_input| { |
| 1331 | const tree = try src_loc.file_scope.getTree(gpa); | 1317 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1332 | const node = src_loc.relativeToNodeIndex(for_input.for_node_offset); | 1318 | const node = for_input.for_node_offset.toAbsolute(src_loc.base_node); |
| 1333 | const for_full = tree.fullFor(node).?; | 1319 | const for_full = tree.fullFor(node).?; |
| 1334 | const src_node = for_full.ast.inputs[for_input.input_index]; | 1320 | const src_node = for_full.ast.inputs[for_input.input_index]; |
| 1335 | return tree.nodeToSpan(src_node); | 1321 | return tree.nodeToSpan(src_node); |
| 1336 | }, | 1322 | }, |
| 1337 | .for_capture_from_input => |node_off| { | 1323 | .for_capture_from_input => |node_off| { |
| 1338 | const tree = try src_loc.file_scope.getTree(gpa); | 1324 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1339 | const token_tags = tree.tokens.items(.tag); | 1325 | const input_node = node_off.toAbsolute(src_loc.base_node); |
| 1340 | const input_node = src_loc.relativeToNodeIndex(node_off); | ||
| 1341 | // We have to actually linear scan the whole AST to find the for loop | 1326 | // We have to actually linear scan the whole AST to find the for loop |
| 1342 | // that contains this input. | 1327 | // that contains this input. |
| 1343 | const node_tags = tree.nodes.items(.tag); | 1328 | const node_tags = tree.nodes.items(.tag); |
| 1344 | for (node_tags, 0..) |node_tag, node_usize| { | 1329 | for (node_tags, 0..) |node_tag, node_usize| { |
| 1345 | const node = @as(Ast.Node.Index, @intCast(node_usize)); | 1330 | const node: Ast.Node.Index = @enumFromInt(node_usize); |
| 1346 | switch (node_tag) { | 1331 | switch (node_tag) { |
| 1347 | .for_simple, .@"for" => { | 1332 | .for_simple, .@"for" => { |
| 1348 | const for_full = tree.fullFor(node).?; | 1333 | const for_full = tree.fullFor(node).?; |
| ... | @@ -1351,7 +1336,7 @@ pub const SrcLoc = struct { | ... | @@ -1351,7 +1336,7 @@ pub const SrcLoc = struct { |
| 1351 | var count = input_index; | 1336 | var count = input_index; |
| 1352 | var tok = for_full.payload_token; | 1337 | var tok = for_full.payload_token; |
| 1353 | while (true) { | 1338 | while (true) { |
| 1354 | switch (token_tags[tok]) { | 1339 | switch (tree.tokenTag(tok)) { |
| 1355 | .comma => { | 1340 | .comma => { |
| 1356 | count -= 1; | 1341 | count -= 1; |
| 1357 | tok += 1; | 1342 | tok += 1; |
| ... | @@ -1378,13 +1363,12 @@ pub const SrcLoc = struct { | ... | @@ -1378,13 +1363,12 @@ pub const SrcLoc = struct { |
| 1378 | }, | 1363 | }, |
| 1379 | .call_arg => |call_arg| { | 1364 | .call_arg => |call_arg| { |
| 1380 | const tree = try src_loc.file_scope.getTree(gpa); | 1365 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1381 | const node = src_loc.relativeToNodeIndex(call_arg.call_node_offset); | 1366 | const node = call_arg.call_node_offset.toAbsolute(src_loc.base_node); |
| 1382 | var buf: [2]Ast.Node.Index = undefined; | 1367 | var buf: [2]Ast.Node.Index = undefined; |
| 1383 | const call_full = tree.fullCall(buf[0..1], node) orelse { | 1368 | const call_full = tree.fullCall(buf[0..1], node) orelse { |
| 1384 | const node_tags = tree.nodes.items(.tag); | 1369 | assert(tree.nodeTag(node) == .builtin_call); |
| 1385 | assert(node_tags[node] == .builtin_call); | 1370 | const call_args_node: Ast.Node.Index = @enumFromInt(tree.extra_data[@intFromEnum(tree.nodeData(node).extra_range.end) - 1]); |
| 1386 | const call_args_node = tree.extra_data[tree.nodes.items(.data)[node].rhs - 1]; | 1371 | switch (tree.nodeTag(call_args_node)) { |
| 1387 | switch (node_tags[call_args_node]) { | ||
| 1388 | .array_init_one, | 1372 | .array_init_one, |
| 1389 | .array_init_one_comma, | 1373 | .array_init_one_comma, |
| 1390 | .array_init_dot_two, | 1374 | .array_init_dot_two, |
| ... | @@ -1416,7 +1400,7 @@ pub const SrcLoc = struct { | ... | @@ -1416,7 +1400,7 @@ pub const SrcLoc = struct { |
| 1416 | }, | 1400 | }, |
| 1417 | .fn_proto_param, .fn_proto_param_type => |fn_proto_param| { | 1401 | .fn_proto_param, .fn_proto_param_type => |fn_proto_param| { |
| 1418 | const tree = try src_loc.file_scope.getTree(gpa); | 1402 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1419 | const node = src_loc.relativeToNodeIndex(fn_proto_param.fn_proto_node_offset); | 1403 | const node = fn_proto_param.fn_proto_node_offset.toAbsolute(src_loc.base_node); |
| 1420 | var buf: [1]Ast.Node.Index = undefined; | 1404 | var buf: [1]Ast.Node.Index = undefined; |
| 1421 | const full = tree.fullFnProto(&buf, node).?; | 1405 | const full = tree.fullFnProto(&buf, node).?; |
| 1422 | var it = full.iterate(tree); | 1406 | var it = full.iterate(tree); |
| ... | @@ -1428,14 +1412,14 @@ pub const SrcLoc = struct { | ... | @@ -1428,14 +1412,14 @@ pub const SrcLoc = struct { |
| 1428 | .fn_proto_param_type => if (param.anytype_ellipsis3) |tok| { | 1412 | .fn_proto_param_type => if (param.anytype_ellipsis3) |tok| { |
| 1429 | return tree.tokenToSpan(tok); | 1413 | return tree.tokenToSpan(tok); |
| 1430 | } else { | 1414 | } else { |
| 1431 | return tree.nodeToSpan(param.type_expr); | 1415 | return tree.nodeToSpan(param.type_expr.?); |
| 1432 | }, | 1416 | }, |
| 1433 | .fn_proto_param => if (param.anytype_ellipsis3) |tok| { | 1417 | .fn_proto_param => if (param.anytype_ellipsis3) |tok| { |
| 1434 | const first = param.comptime_noalias orelse param.name_token orelse tok; | 1418 | const first = param.comptime_noalias orelse param.name_token orelse tok; |
| 1435 | return tree.tokensToSpan(first, tok, first); | 1419 | return tree.tokensToSpan(first, tok, first); |
| 1436 | } else { | 1420 | } else { |
| 1437 | const first = param.comptime_noalias orelse param.name_token orelse tree.firstToken(param.type_expr); | 1421 | const first = param.comptime_noalias orelse param.name_token orelse tree.firstToken(param.type_expr.?); |
| 1438 | return tree.tokensToSpan(first, tree.lastToken(param.type_expr), first); | 1422 | return tree.tokensToSpan(first, tree.lastToken(param.type_expr.?), first); |
| 1439 | }, | 1423 | }, |
| 1440 | else => unreachable, | 1424 | else => unreachable, |
| 1441 | } | 1425 | } |
| ... | @@ -1444,28 +1428,24 @@ pub const SrcLoc = struct { | ... | @@ -1444,28 +1428,24 @@ pub const SrcLoc = struct { |
| 1444 | }, | 1428 | }, |
| 1445 | .node_offset_bin_lhs => |node_off| { | 1429 | .node_offset_bin_lhs => |node_off| { |
| 1446 | const tree = try src_loc.file_scope.getTree(gpa); | 1430 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1447 | const node = src_loc.relativeToNodeIndex(node_off); | 1431 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1448 | const node_datas = tree.nodes.items(.data); | 1432 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[0]); |
| 1449 | return tree.nodeToSpan(node_datas[node].lhs); | ||
| 1450 | }, | 1433 | }, |
| 1451 | .node_offset_bin_rhs => |node_off| { | 1434 | .node_offset_bin_rhs => |node_off| { |
| 1452 | const tree = try src_loc.file_scope.getTree(gpa); | 1435 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1453 | const node = src_loc.relativeToNodeIndex(node_off); | 1436 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1454 | const node_datas = tree.nodes.items(.data); | 1437 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[1]); |
| 1455 | return tree.nodeToSpan(node_datas[node].rhs); | ||
| 1456 | }, | 1438 | }, |
| 1457 | .array_cat_lhs, .array_cat_rhs => |cat| { | 1439 | .array_cat_lhs, .array_cat_rhs => |cat| { |
| 1458 | const tree = try src_loc.file_scope.getTree(gpa); | 1440 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1459 | const node = src_loc.relativeToNodeIndex(cat.array_cat_offset); | 1441 | const node = cat.array_cat_offset.toAbsolute(src_loc.base_node); |
| 1460 | const node_datas = tree.nodes.items(.data); | ||
| 1461 | const arr_node = if (src_loc.lazy == .array_cat_lhs) | 1442 | const arr_node = if (src_loc.lazy == .array_cat_lhs) |
| 1462 | node_datas[node].lhs | 1443 | tree.nodeData(node).node_and_node[0] |
| 1463 | else | 1444 | else |
| 1464 | node_datas[node].rhs; | 1445 | tree.nodeData(node).node_and_node[1]; |
| 1465 | 1446 | ||
| 1466 | const node_tags = tree.nodes.items(.tag); | ||
| 1467 | var buf: [2]Ast.Node.Index = undefined; | 1447 | var buf: [2]Ast.Node.Index = undefined; |
| 1468 | switch (node_tags[arr_node]) { | 1448 | switch (tree.nodeTag(arr_node)) { |
| 1469 | .array_init_one, | 1449 | .array_init_one, |
| 1470 | .array_init_one_comma, | 1450 | .array_init_one_comma, |
| 1471 | .array_init_dot_two, | 1451 | .array_init_dot_two, |
| ... | @@ -1482,27 +1462,30 @@ pub const SrcLoc = struct { | ... | @@ -1482,27 +1462,30 @@ pub const SrcLoc = struct { |
| 1482 | } | 1462 | } |
| 1483 | }, | 1463 | }, |
| 1484 | 1464 | ||
| 1465 | .node_offset_try_operand => |node_off| { | ||
| 1466 | const tree = try src_loc.file_scope.getTree(gpa); | ||
| 1467 | const node = node_off.toAbsolute(src_loc.base_node); | ||
| 1468 | return tree.nodeToSpan(tree.nodeData(node).node); | ||
| 1469 | }, | ||
| 1470 | |||
| 1485 | .node_offset_switch_operand => |node_off| { | 1471 | .node_offset_switch_operand => |node_off| { |
| 1486 | const tree = try src_loc.file_scope.getTree(gpa); | 1472 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1487 | const node = src_loc.relativeToNodeIndex(node_off); | 1473 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1488 | const node_datas = tree.nodes.items(.data); | 1474 | const condition, _ = tree.nodeData(node).node_and_extra; |
| 1489 | return tree.nodeToSpan(node_datas[node].lhs); | 1475 | return tree.nodeToSpan(condition); |
| 1490 | }, | 1476 | }, |
| 1491 | 1477 | ||
| 1492 | .node_offset_switch_special_prong => |node_off| { | 1478 | .node_offset_switch_special_prong => |node_off| { |
| 1493 | const tree = try src_loc.file_scope.getTree(gpa); | 1479 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1494 | const switch_node = src_loc.relativeToNodeIndex(node_off); | 1480 | const switch_node = node_off.toAbsolute(src_loc.base_node); |
| 1495 | const node_datas = tree.nodes.items(.data); | 1481 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; |
| 1496 | const node_tags = tree.nodes.items(.tag); | 1482 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); |
| 1497 | const main_tokens = tree.nodes.items(.main_token); | ||
| 1498 | const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange); | ||
| 1499 | const case_nodes = tree.extra_data[extra.start..extra.end]; | ||
| 1500 | for (case_nodes) |case_node| { | 1483 | for (case_nodes) |case_node| { |
| 1501 | const case = tree.fullSwitchCase(case_node).?; | 1484 | const case = tree.fullSwitchCase(case_node).?; |
| 1502 | const is_special = (case.ast.values.len == 0) or | 1485 | const is_special = (case.ast.values.len == 0) or |
| 1503 | (case.ast.values.len == 1 and | 1486 | (case.ast.values.len == 1 and |
| 1504 | node_tags[case.ast.values[0]] == .identifier and | 1487 | tree.nodeTag(case.ast.values[0]) == .identifier and |
| 1505 | mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_")); | 1488 | mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(case.ast.values[0])), "_")); |
| 1506 | if (!is_special) continue; | 1489 | if (!is_special) continue; |
| 1507 | 1490 | ||
| 1508 | return tree.nodeToSpan(case_node); | 1491 | return tree.nodeToSpan(case_node); |
| ... | @@ -1511,22 +1494,19 @@ pub const SrcLoc = struct { | ... | @@ -1511,22 +1494,19 @@ pub const SrcLoc = struct { |
| 1511 | 1494 | ||
| 1512 | .node_offset_switch_range => |node_off| { | 1495 | .node_offset_switch_range => |node_off| { |
| 1513 | const tree = try src_loc.file_scope.getTree(gpa); | 1496 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1514 | const switch_node = src_loc.relativeToNodeIndex(node_off); | 1497 | const switch_node = node_off.toAbsolute(src_loc.base_node); |
| 1515 | const node_datas = tree.nodes.items(.data); | 1498 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; |
| 1516 | const node_tags = tree.nodes.items(.tag); | 1499 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); |
| 1517 | const main_tokens = tree.nodes.items(.main_token); | ||
| 1518 | const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange); | ||
| 1519 | const case_nodes = tree.extra_data[extra.start..extra.end]; | ||
| 1520 | for (case_nodes) |case_node| { | 1500 | for (case_nodes) |case_node| { |
| 1521 | const case = tree.fullSwitchCase(case_node).?; | 1501 | const case = tree.fullSwitchCase(case_node).?; |
| 1522 | const is_special = (case.ast.values.len == 0) or | 1502 | const is_special = (case.ast.values.len == 0) or |
| 1523 | (case.ast.values.len == 1 and | 1503 | (case.ast.values.len == 1 and |
| 1524 | node_tags[case.ast.values[0]] == .identifier and | 1504 | tree.nodeTag(case.ast.values[0]) == .identifier and |
| 1525 | mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_")); | 1505 | mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(case.ast.values[0])), "_")); |
| 1526 | if (is_special) continue; | 1506 | if (is_special) continue; |
| 1527 | 1507 | ||
| 1528 | for (case.ast.values) |item_node| { | 1508 | for (case.ast.values) |item_node| { |
| 1529 | if (node_tags[item_node] == .switch_range) { | 1509 | if (tree.nodeTag(item_node) == .switch_range) { |
| 1530 | return tree.nodeToSpan(item_node); | 1510 | return tree.nodeToSpan(item_node); |
| 1531 | } | 1511 | } |
| 1532 | } | 1512 | } |
| ... | @@ -1534,47 +1514,46 @@ pub const SrcLoc = struct { | ... | @@ -1534,47 +1514,46 @@ pub const SrcLoc = struct { |
| 1534 | }, | 1514 | }, |
| 1535 | .node_offset_fn_type_align => |node_off| { | 1515 | .node_offset_fn_type_align => |node_off| { |
| 1536 | const tree = try src_loc.file_scope.getTree(gpa); | 1516 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1537 | const node = src_loc.relativeToNodeIndex(node_off); | 1517 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1538 | var buf: [1]Ast.Node.Index = undefined; | 1518 | var buf: [1]Ast.Node.Index = undefined; |
| 1539 | const full = tree.fullFnProto(&buf, node).?; | 1519 | const full = tree.fullFnProto(&buf, node).?; |
| 1540 | return tree.nodeToSpan(full.ast.align_expr); | 1520 | return tree.nodeToSpan(full.ast.align_expr.unwrap().?); |
| 1541 | }, | 1521 | }, |
| 1542 | .node_offset_fn_type_addrspace => |node_off| { | 1522 | .node_offset_fn_type_addrspace => |node_off| { |
| 1543 | const tree = try src_loc.file_scope.getTree(gpa); | 1523 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1544 | const node = src_loc.relativeToNodeIndex(node_off); | 1524 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1545 | var buf: [1]Ast.Node.Index = undefined; | 1525 | var buf: [1]Ast.Node.Index = undefined; |
| 1546 | const full = tree.fullFnProto(&buf, node).?; | 1526 | const full = tree.fullFnProto(&buf, node).?; |
| 1547 | return tree.nodeToSpan(full.ast.addrspace_expr); | 1527 | return tree.nodeToSpan(full.ast.addrspace_expr.unwrap().?); |
| 1548 | }, | 1528 | }, |
| 1549 | .node_offset_fn_type_section => |node_off| { | 1529 | .node_offset_fn_type_section => |node_off| { |
| 1550 | const tree = try src_loc.file_scope.getTree(gpa); | 1530 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1551 | const node = src_loc.relativeToNodeIndex(node_off); | 1531 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1552 | var buf: [1]Ast.Node.Index = undefined; | 1532 | var buf: [1]Ast.Node.Index = undefined; |
| 1553 | const full = tree.fullFnProto(&buf, node).?; | 1533 | const full = tree.fullFnProto(&buf, node).?; |
| 1554 | return tree.nodeToSpan(full.ast.section_expr); | 1534 | return tree.nodeToSpan(full.ast.section_expr.unwrap().?); |
| 1555 | }, | 1535 | }, |
| 1556 | .node_offset_fn_type_cc => |node_off| { | 1536 | .node_offset_fn_type_cc => |node_off| { |
| 1557 | const tree = try src_loc.file_scope.getTree(gpa); | 1537 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1558 | const node = src_loc.relativeToNodeIndex(node_off); | 1538 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1559 | var buf: [1]Ast.Node.Index = undefined; | 1539 | var buf: [1]Ast.Node.Index = undefined; |
| 1560 | const full = tree.fullFnProto(&buf, node).?; | 1540 | const full = tree.fullFnProto(&buf, node).?; |
| 1561 | return tree.nodeToSpan(full.ast.callconv_expr); | 1541 | return tree.nodeToSpan(full.ast.callconv_expr.unwrap().?); |
| 1562 | }, | 1542 | }, |
| 1563 | 1543 | ||
| 1564 | .node_offset_fn_type_ret_ty => |node_off| { | 1544 | .node_offset_fn_type_ret_ty => |node_off| { |
| 1565 | const tree = try src_loc.file_scope.getTree(gpa); | 1545 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1566 | const node = src_loc.relativeToNodeIndex(node_off); | 1546 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1567 | var buf: [1]Ast.Node.Index = undefined; | 1547 | var buf: [1]Ast.Node.Index = undefined; |
| 1568 | const full = tree.fullFnProto(&buf, node).?; | 1548 | const full = tree.fullFnProto(&buf, node).?; |
| 1569 | return tree.nodeToSpan(full.ast.return_type); | 1549 | return tree.nodeToSpan(full.ast.return_type.unwrap().?); |
| 1570 | }, | 1550 | }, |
| 1571 | .node_offset_param => |node_off| { | 1551 | .node_offset_param => |node_off| { |
| 1572 | const tree = try src_loc.file_scope.getTree(gpa); | 1552 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1573 | const token_tags = tree.tokens.items(.tag); | 1553 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1574 | const node = src_loc.relativeToNodeIndex(node_off); | ||
| 1575 | 1554 | ||
| 1576 | var first_tok = tree.firstToken(node); | 1555 | var first_tok = tree.firstToken(node); |
| 1577 | while (true) switch (token_tags[first_tok - 1]) { | 1556 | while (true) switch (tree.tokenTag(first_tok - 1)) { |
| 1578 | .colon, .identifier, .keyword_comptime, .keyword_noalias => first_tok -= 1, | 1557 | .colon, .identifier, .keyword_comptime, .keyword_noalias => first_tok -= 1, |
| 1579 | else => break, | 1558 | else => break, |
| 1580 | }; | 1559 | }; |
| ... | @@ -1586,12 +1565,11 @@ pub const SrcLoc = struct { | ... | @@ -1586,12 +1565,11 @@ pub const SrcLoc = struct { |
| 1586 | }, | 1565 | }, |
| 1587 | .token_offset_param => |token_off| { | 1566 | .token_offset_param => |token_off| { |
| 1588 | const tree = try src_loc.file_scope.getTree(gpa); | 1567 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1589 | const token_tags = tree.tokens.items(.tag); | 1568 | const main_token = tree.nodeMainToken(src_loc.base_node); |
| 1590 | const main_token = tree.nodes.items(.main_token)[src_loc.base_node]; | 1569 | const tok_index = token_off.toAbsolute(main_token); |
| 1591 | const tok_index = @as(Ast.TokenIndex, @bitCast(token_off + @as(i32, @bitCast(main_token)))); | ||
| 1592 | 1570 | ||
| 1593 | var first_tok = tok_index; | 1571 | var first_tok = tok_index; |
| 1594 | while (true) switch (token_tags[first_tok - 1]) { | 1572 | while (true) switch (tree.tokenTag(first_tok - 1)) { |
| 1595 | .colon, .identifier, .keyword_comptime, .keyword_noalias => first_tok -= 1, | 1573 | .colon, .identifier, .keyword_comptime, .keyword_noalias => first_tok -= 1, |
| 1596 | else => break, | 1574 | else => break, |
| 1597 | }; | 1575 | }; |
| ... | @@ -1604,109 +1582,108 @@ pub const SrcLoc = struct { | ... | @@ -1604,109 +1582,108 @@ pub const SrcLoc = struct { |
| 1604 | 1582 | ||
| 1605 | .node_offset_anyframe_type => |node_off| { | 1583 | .node_offset_anyframe_type => |node_off| { |
| 1606 | const tree = try src_loc.file_scope.getTree(gpa); | 1584 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1607 | const node_datas = tree.nodes.items(.data); | 1585 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1608 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1586 | _, const child_type = tree.nodeData(parent_node).token_and_node; |
| 1609 | return tree.nodeToSpan(node_datas[parent_node].rhs); | 1587 | return tree.nodeToSpan(child_type); |
| 1610 | }, | 1588 | }, |
| 1611 | 1589 | ||
| 1612 | .node_offset_lib_name => |node_off| { | 1590 | .node_offset_lib_name => |node_off| { |
| 1613 | const tree = try src_loc.file_scope.getTree(gpa); | 1591 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1614 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1592 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1615 | var buf: [1]Ast.Node.Index = undefined; | 1593 | var buf: [1]Ast.Node.Index = undefined; |
| 1616 | const full = tree.fullFnProto(&buf, parent_node).?; | 1594 | const full = tree.fullFnProto(&buf, parent_node).?; |
| 1617 | const tok_index = full.lib_name.?; | 1595 | const tok_index = full.lib_name.?; |
| 1618 | const start = tree.tokens.items(.start)[tok_index]; | 1596 | const start = tree.tokenStart(tok_index); |
| 1619 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1597 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1620 | return Span{ .start = start, .end = end, .main = start }; | 1598 | return Span{ .start = start, .end = end, .main = start }; |
| 1621 | }, | 1599 | }, |
| 1622 | 1600 | ||
| 1623 | .node_offset_array_type_len => |node_off| { | 1601 | .node_offset_array_type_len => |node_off| { |
| 1624 | const tree = try src_loc.file_scope.getTree(gpa); | 1602 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1625 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1603 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1626 | 1604 | ||
| 1627 | const full = tree.fullArrayType(parent_node).?; | 1605 | const full = tree.fullArrayType(parent_node).?; |
| 1628 | return tree.nodeToSpan(full.ast.elem_count); | 1606 | return tree.nodeToSpan(full.ast.elem_count); |
| 1629 | }, | 1607 | }, |
| 1630 | .node_offset_array_type_sentinel => |node_off| { | 1608 | .node_offset_array_type_sentinel => |node_off| { |
| 1631 | const tree = try src_loc.file_scope.getTree(gpa); | 1609 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1632 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1610 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1633 | 1611 | ||
| 1634 | const full = tree.fullArrayType(parent_node).?; | 1612 | const full = tree.fullArrayType(parent_node).?; |
| 1635 | return tree.nodeToSpan(full.ast.sentinel); | 1613 | return tree.nodeToSpan(full.ast.sentinel.unwrap().?); |
| 1636 | }, | 1614 | }, |
| 1637 | .node_offset_array_type_elem => |node_off| { | 1615 | .node_offset_array_type_elem => |node_off| { |
| 1638 | const tree = try src_loc.file_scope.getTree(gpa); | 1616 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1639 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1617 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1640 | 1618 | ||
| 1641 | const full = tree.fullArrayType(parent_node).?; | 1619 | const full = tree.fullArrayType(parent_node).?; |
| 1642 | return tree.nodeToSpan(full.ast.elem_type); | 1620 | return tree.nodeToSpan(full.ast.elem_type); |
| 1643 | }, | 1621 | }, |
| 1644 | .node_offset_un_op => |node_off| { | 1622 | .node_offset_un_op => |node_off| { |
| 1645 | const tree = try src_loc.file_scope.getTree(gpa); | 1623 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1646 | const node_datas = tree.nodes.items(.data); | 1624 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1647 | const node = src_loc.relativeToNodeIndex(node_off); | 1625 | return tree.nodeToSpan(tree.nodeData(node).node); |
| 1648 | |||
| 1649 | return tree.nodeToSpan(node_datas[node].lhs); | ||
| 1650 | }, | 1626 | }, |
| 1651 | .node_offset_ptr_elem => |node_off| { | 1627 | .node_offset_ptr_elem => |node_off| { |
| 1652 | const tree = try src_loc.file_scope.getTree(gpa); | 1628 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1653 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1629 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1654 | 1630 | ||
| 1655 | const full = tree.fullPtrType(parent_node).?; | 1631 | const full = tree.fullPtrType(parent_node).?; |
| 1656 | return tree.nodeToSpan(full.ast.child_type); | 1632 | return tree.nodeToSpan(full.ast.child_type); |
| 1657 | }, | 1633 | }, |
| 1658 | .node_offset_ptr_sentinel => |node_off| { | 1634 | .node_offset_ptr_sentinel => |node_off| { |
| 1659 | const tree = try src_loc.file_scope.getTree(gpa); | 1635 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1660 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1636 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1661 | 1637 | ||
| 1662 | const full = tree.fullPtrType(parent_node).?; | 1638 | const full = tree.fullPtrType(parent_node).?; |
| 1663 | return tree.nodeToSpan(full.ast.sentinel); | 1639 | return tree.nodeToSpan(full.ast.sentinel.unwrap().?); |
| 1664 | }, | 1640 | }, |
| 1665 | .node_offset_ptr_align => |node_off| { | 1641 | .node_offset_ptr_align => |node_off| { |
| 1666 | const tree = try src_loc.file_scope.getTree(gpa); | 1642 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1667 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1643 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1668 | 1644 | ||
| 1669 | const full = tree.fullPtrType(parent_node).?; | 1645 | const full = tree.fullPtrType(parent_node).?; |
| 1670 | return tree.nodeToSpan(full.ast.align_node); | 1646 | return tree.nodeToSpan(full.ast.align_node.unwrap().?); |
| 1671 | }, | 1647 | }, |
| 1672 | .node_offset_ptr_addrspace => |node_off| { | 1648 | .node_offset_ptr_addrspace => |node_off| { |
| 1673 | const tree = try src_loc.file_scope.getTree(gpa); | 1649 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1674 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1650 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1675 | 1651 | ||
| 1676 | const full = tree.fullPtrType(parent_node).?; | 1652 | const full = tree.fullPtrType(parent_node).?; |
| 1677 | return tree.nodeToSpan(full.ast.addrspace_node); | 1653 | return tree.nodeToSpan(full.ast.addrspace_node.unwrap().?); |
| 1678 | }, | 1654 | }, |
| 1679 | .node_offset_ptr_bitoffset => |node_off| { | 1655 | .node_offset_ptr_bitoffset => |node_off| { |
| 1680 | const tree = try src_loc.file_scope.getTree(gpa); | 1656 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1681 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1657 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1682 | 1658 | ||
| 1683 | const full = tree.fullPtrType(parent_node).?; | 1659 | const full = tree.fullPtrType(parent_node).?; |
| 1684 | return tree.nodeToSpan(full.ast.bit_range_start); | 1660 | return tree.nodeToSpan(full.ast.bit_range_start.unwrap().?); |
| 1685 | }, | 1661 | }, |
| 1686 | .node_offset_ptr_hostsize => |node_off| { | 1662 | .node_offset_ptr_hostsize => |node_off| { |
| 1687 | const tree = try src_loc.file_scope.getTree(gpa); | 1663 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1688 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1664 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1689 | 1665 | ||
| 1690 | const full = tree.fullPtrType(parent_node).?; | 1666 | const full = tree.fullPtrType(parent_node).?; |
| 1691 | return tree.nodeToSpan(full.ast.bit_range_end); | 1667 | return tree.nodeToSpan(full.ast.bit_range_end.unwrap().?); |
| 1692 | }, | 1668 | }, |
| 1693 | .node_offset_container_tag => |node_off| { | 1669 | .node_offset_container_tag => |node_off| { |
| 1694 | const tree = try src_loc.file_scope.getTree(gpa); | 1670 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1695 | const node_tags = tree.nodes.items(.tag); | 1671 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1696 | const parent_node = src_loc.relativeToNodeIndex(node_off); | ||
| 1697 | 1672 | ||
| 1698 | switch (node_tags[parent_node]) { | 1673 | switch (tree.nodeTag(parent_node)) { |
| 1699 | .container_decl_arg, .container_decl_arg_trailing => { | 1674 | .container_decl_arg, .container_decl_arg_trailing => { |
| 1700 | const full = tree.containerDeclArg(parent_node); | 1675 | const full = tree.containerDeclArg(parent_node); |
| 1701 | return tree.nodeToSpan(full.ast.arg); | 1676 | const arg_node = full.ast.arg.unwrap().?; |
| 1677 | return tree.nodeToSpan(arg_node); | ||
| 1702 | }, | 1678 | }, |
| 1703 | .tagged_union_enum_tag, .tagged_union_enum_tag_trailing => { | 1679 | .tagged_union_enum_tag, .tagged_union_enum_tag_trailing => { |
| 1704 | const full = tree.taggedUnionEnumTag(parent_node); | 1680 | const full = tree.taggedUnionEnumTag(parent_node); |
| 1681 | const arg_node = full.ast.arg.unwrap().?; | ||
| 1705 | 1682 | ||
| 1706 | return tree.tokensToSpan( | 1683 | return tree.tokensToSpan( |
| 1707 | tree.firstToken(full.ast.arg) - 2, | 1684 | tree.firstToken(arg_node) - 2, |
| 1708 | tree.lastToken(full.ast.arg) + 1, | 1685 | tree.lastToken(arg_node) + 1, |
| 1709 | tree.nodes.items(.main_token)[full.ast.arg], | 1686 | tree.nodeMainToken(arg_node), |
| 1710 | ); | 1687 | ); |
| 1711 | }, | 1688 | }, |
| 1712 | else => unreachable, | 1689 | else => unreachable, |
| ... | @@ -1714,60 +1691,55 @@ pub const SrcLoc = struct { | ... | @@ -1714,60 +1691,55 @@ pub const SrcLoc = struct { |
| 1714 | }, | 1691 | }, |
| 1715 | .node_offset_field_default => |node_off| { | 1692 | .node_offset_field_default => |node_off| { |
| 1716 | const tree = try src_loc.file_scope.getTree(gpa); | 1693 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1717 | const node_tags = tree.nodes.items(.tag); | 1694 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1718 | const parent_node = src_loc.relativeToNodeIndex(node_off); | ||
| 1719 | 1695 | ||
| 1720 | const full: Ast.full.ContainerField = switch (node_tags[parent_node]) { | 1696 | const full: Ast.full.ContainerField = switch (tree.nodeTag(parent_node)) { |
| 1721 | .container_field => tree.containerField(parent_node), | 1697 | .container_field => tree.containerField(parent_node), |
| 1722 | .container_field_init => tree.containerFieldInit(parent_node), | 1698 | .container_field_init => tree.containerFieldInit(parent_node), |
| 1723 | else => unreachable, | 1699 | else => unreachable, |
| 1724 | }; | 1700 | }; |
| 1725 | return tree.nodeToSpan(full.ast.value_expr); | 1701 | return tree.nodeToSpan(full.ast.value_expr.unwrap().?); |
| 1726 | }, | 1702 | }, |
| 1727 | .node_offset_init_ty => |node_off| { | 1703 | .node_offset_init_ty => |node_off| { |
| 1728 | const tree = try src_loc.file_scope.getTree(gpa); | 1704 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1729 | const parent_node = src_loc.relativeToNodeIndex(node_off); | 1705 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1730 | 1706 | ||
| 1731 | var buf: [2]Ast.Node.Index = undefined; | 1707 | var buf: [2]Ast.Node.Index = undefined; |
| 1732 | const type_expr = if (tree.fullArrayInit(&buf, parent_node)) |array_init| | 1708 | const type_expr = if (tree.fullArrayInit(&buf, parent_node)) |array_init| |
| 1733 | array_init.ast.type_expr | 1709 | array_init.ast.type_expr.unwrap().? |
| 1734 | else | 1710 | else |
| 1735 | tree.fullStructInit(&buf, parent_node).?.ast.type_expr; | 1711 | tree.fullStructInit(&buf, parent_node).?.ast.type_expr.unwrap().?; |
| 1736 | return tree.nodeToSpan(type_expr); | 1712 | return tree.nodeToSpan(type_expr); |
| 1737 | }, | 1713 | }, |
| 1738 | .node_offset_store_ptr => |node_off| { | 1714 | .node_offset_store_ptr => |node_off| { |
| 1739 | const tree = try src_loc.file_scope.getTree(gpa); | 1715 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1740 | const node_tags = tree.nodes.items(.tag); | 1716 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1741 | const node_datas = tree.nodes.items(.data); | ||
| 1742 | const node = src_loc.relativeToNodeIndex(node_off); | ||
| 1743 | 1717 | ||
| 1744 | switch (node_tags[node]) { | 1718 | switch (tree.nodeTag(node)) { |
| 1745 | .assign => { | 1719 | .assign => { |
| 1746 | return tree.nodeToSpan(node_datas[node].lhs); | 1720 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[0]); |
| 1747 | }, | 1721 | }, |
| 1748 | else => return tree.nodeToSpan(node), | 1722 | else => return tree.nodeToSpan(node), |
| 1749 | } | 1723 | } |
| 1750 | }, | 1724 | }, |
| 1751 | .node_offset_store_operand => |node_off| { | 1725 | .node_offset_store_operand => |node_off| { |
| 1752 | const tree = try src_loc.file_scope.getTree(gpa); | 1726 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1753 | const node_tags = tree.nodes.items(.tag); | 1727 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1754 | const node_datas = tree.nodes.items(.data); | ||
| 1755 | const node = src_loc.relativeToNodeIndex(node_off); | ||
| 1756 | 1728 | ||
| 1757 | switch (node_tags[node]) { | 1729 | switch (tree.nodeTag(node)) { |
| 1758 | .assign => { | 1730 | .assign => { |
| 1759 | return tree.nodeToSpan(node_datas[node].rhs); | 1731 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[1]); |
| 1760 | }, | 1732 | }, |
| 1761 | else => return tree.nodeToSpan(node), | 1733 | else => return tree.nodeToSpan(node), |
| 1762 | } | 1734 | } |
| 1763 | }, | 1735 | }, |
| 1764 | .node_offset_return_operand => |node_off| { | 1736 | .node_offset_return_operand => |node_off| { |
| 1765 | const tree = try src_loc.file_scope.getTree(gpa); | 1737 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1766 | const node = src_loc.relativeToNodeIndex(node_off); | 1738 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1767 | const node_tags = tree.nodes.items(.tag); | 1739 | if (tree.nodeTag(node) == .@"return") { |
| 1768 | const node_datas = tree.nodes.items(.data); | 1740 | if (tree.nodeData(node).opt_node.unwrap()) |lhs| { |
| 1769 | if (node_tags[node] == .@"return" and node_datas[node].lhs != 0) { | 1741 | return tree.nodeToSpan(lhs); |
| 1770 | return tree.nodeToSpan(node_datas[node].lhs); | 1742 | } |
| 1771 | } | 1743 | } |
| 1772 | return tree.nodeToSpan(node); | 1744 | return tree.nodeToSpan(node); |
| 1773 | }, | 1745 | }, |
| ... | @@ -1777,7 +1749,7 @@ pub const SrcLoc = struct { | ... | @@ -1777,7 +1749,7 @@ pub const SrcLoc = struct { |
| 1777 | .container_field_align, | 1749 | .container_field_align, |
| 1778 | => |field_idx| { | 1750 | => |field_idx| { |
| 1779 | const tree = try src_loc.file_scope.getTree(gpa); | 1751 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1780 | const node = src_loc.relativeToNodeIndex(0); | 1752 | const node = src_loc.base_node; |
| 1781 | var buf: [2]Ast.Node.Index = undefined; | 1753 | var buf: [2]Ast.Node.Index = undefined; |
| 1782 | const container_decl = tree.fullContainerDecl(&buf, node) orelse | 1754 | const container_decl = tree.fullContainerDecl(&buf, node) orelse |
| 1783 | return tree.nodeToSpan(node); | 1755 | return tree.nodeToSpan(node); |
| ... | @@ -1790,36 +1762,36 @@ pub const SrcLoc = struct { | ... | @@ -1790,36 +1762,36 @@ pub const SrcLoc = struct { |
| 1790 | continue; | 1762 | continue; |
| 1791 | } | 1763 | } |
| 1792 | const field_component_node = switch (src_loc.lazy) { | 1764 | const field_component_node = switch (src_loc.lazy) { |
| 1793 | .container_field_name => 0, | 1765 | .container_field_name => .none, |
| 1794 | .container_field_value => field.ast.value_expr, | 1766 | .container_field_value => field.ast.value_expr, |
| 1795 | .container_field_type => field.ast.type_expr, | 1767 | .container_field_type => field.ast.type_expr, |
| 1796 | .container_field_align => field.ast.align_expr, | 1768 | .container_field_align => field.ast.align_expr, |
| 1797 | else => unreachable, | 1769 | else => unreachable, |
| 1798 | }; | 1770 | }; |
| 1799 | if (field_component_node == 0) { | 1771 | if (field_component_node.unwrap()) |component_node| { |
| 1800 | return tree.tokenToSpan(field.ast.main_token); | 1772 | return tree.nodeToSpan(component_node); |
| 1801 | } else { | 1773 | } else { |
| 1802 | return tree.nodeToSpan(field_component_node); | 1774 | return tree.tokenToSpan(field.ast.main_token); |
| 1803 | } | 1775 | } |
| 1804 | } else unreachable; | 1776 | } else unreachable; |
| 1805 | }, | 1777 | }, |
| 1806 | .tuple_field_type, .tuple_field_init => |field_info| { | 1778 | .tuple_field_type, .tuple_field_init => |field_info| { |
| 1807 | const tree = try src_loc.file_scope.getTree(gpa); | 1779 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1808 | const node = src_loc.relativeToNodeIndex(0); | 1780 | const node = src_loc.base_node; |
| 1809 | var buf: [2]Ast.Node.Index = undefined; | 1781 | var buf: [2]Ast.Node.Index = undefined; |
| 1810 | const container_decl = tree.fullContainerDecl(&buf, node) orelse | 1782 | const container_decl = tree.fullContainerDecl(&buf, node) orelse |
| 1811 | return tree.nodeToSpan(node); | 1783 | return tree.nodeToSpan(node); |
| 1812 | 1784 | ||
| 1813 | const field = tree.fullContainerField(container_decl.ast.members[field_info.elem_index]).?; | 1785 | const field = tree.fullContainerField(container_decl.ast.members[field_info.elem_index]).?; |
| 1814 | return tree.nodeToSpan(switch (src_loc.lazy) { | 1786 | return tree.nodeToSpan(switch (src_loc.lazy) { |
| 1815 | .tuple_field_type => field.ast.type_expr, | 1787 | .tuple_field_type => field.ast.type_expr.unwrap().?, |
| 1816 | .tuple_field_init => field.ast.value_expr, | 1788 | .tuple_field_init => field.ast.value_expr.unwrap().?, |
| 1817 | else => unreachable, | 1789 | else => unreachable, |
| 1818 | }); | 1790 | }); |
| 1819 | }, | 1791 | }, |
| 1820 | .init_elem => |init_elem| { | 1792 | .init_elem => |init_elem| { |
| 1821 | const tree = try src_loc.file_scope.getTree(gpa); | 1793 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1822 | const init_node = src_loc.relativeToNodeIndex(init_elem.init_node_offset); | 1794 | const init_node = init_elem.init_node_offset.toAbsolute(src_loc.base_node); |
| 1823 | var buf: [2]Ast.Node.Index = undefined; | 1795 | var buf: [2]Ast.Node.Index = undefined; |
| 1824 | if (tree.fullArrayInit(&buf, init_node)) |full| { | 1796 | if (tree.fullArrayInit(&buf, init_node)) |full| { |
| 1825 | const elem_node = full.ast.elements[init_elem.elem_index]; | 1797 | const elem_node = full.ast.elements[init_elem.elem_index]; |
| ... | @@ -1829,7 +1801,7 @@ pub const SrcLoc = struct { | ... | @@ -1829,7 +1801,7 @@ pub const SrcLoc = struct { |
| 1829 | return tree.tokensToSpan( | 1801 | return tree.tokensToSpan( |
| 1830 | tree.firstToken(field_node) - 3, | 1802 | tree.firstToken(field_node) - 3, |
| 1831 | tree.lastToken(field_node), | 1803 | tree.lastToken(field_node), |
| 1832 | tree.nodes.items(.main_token)[field_node] - 2, | 1804 | tree.nodeMainToken(field_node) - 2, |
| 1833 | ); | 1805 | ); |
| 1834 | } else unreachable; | 1806 | } else unreachable; |
| 1835 | }, | 1807 | }, |
| ... | @@ -1858,14 +1830,10 @@ pub const SrcLoc = struct { | ... | @@ -1858,14 +1830,10 @@ pub const SrcLoc = struct { |
| 1858 | else => unreachable, | 1830 | else => unreachable, |
| 1859 | }; | 1831 | }; |
| 1860 | const tree = try src_loc.file_scope.getTree(gpa); | 1832 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1861 | const node_datas = tree.nodes.items(.data); | 1833 | const node = builtin_call_node.toAbsolute(src_loc.base_node); |
| 1862 | const node_tags = tree.nodes.items(.tag); | 1834 | var builtin_buf: [2]Ast.Node.Index = undefined; |
| 1863 | const node = src_loc.relativeToNodeIndex(builtin_call_node); | 1835 | const args = tree.builtinCallParams(&builtin_buf, node).?; |
| 1864 | const arg_node = switch (node_tags[node]) { | 1836 | const arg_node = args[1]; |
| 1865 | .builtin_call_two, .builtin_call_two_comma => node_datas[node].rhs, | ||
| 1866 | .builtin_call, .builtin_call_comma => tree.extra_data[node_datas[node].lhs + 1], | ||
| 1867 | else => unreachable, | ||
| 1868 | }; | ||
| 1869 | var buf: [2]Ast.Node.Index = undefined; | 1837 | var buf: [2]Ast.Node.Index = undefined; |
| 1870 | const full = tree.fullStructInit(&buf, arg_node) orelse | 1838 | const full = tree.fullStructInit(&buf, arg_node) orelse |
| 1871 | return tree.nodeToSpan(arg_node); | 1839 | return tree.nodeToSpan(arg_node); |
| ... | @@ -1877,7 +1845,7 @@ pub const SrcLoc = struct { | ... | @@ -1877,7 +1845,7 @@ pub const SrcLoc = struct { |
| 1877 | return tree.tokensToSpan( | 1845 | return tree.tokensToSpan( |
| 1878 | name_token - 1, | 1846 | name_token - 1, |
| 1879 | tree.lastToken(field_node), | 1847 | tree.lastToken(field_node), |
| 1880 | tree.nodes.items(.main_token)[field_node] - 2, | 1848 | tree.nodeMainToken(field_node) - 2, |
| 1881 | ); | 1849 | ); |
| 1882 | } | 1850 | } |
| 1883 | } | 1851 | } |
| ... | @@ -1901,12 +1869,9 @@ pub const SrcLoc = struct { | ... | @@ -1901,12 +1869,9 @@ pub const SrcLoc = struct { |
| 1901 | }; | 1869 | }; |
| 1902 | 1870 | ||
| 1903 | const tree = try src_loc.file_scope.getTree(gpa); | 1871 | const tree = try src_loc.file_scope.getTree(gpa); |
| 1904 | const node_datas = tree.nodes.items(.data); | 1872 | const switch_node = switch_node_offset.toAbsolute(src_loc.base_node); |
| 1905 | const node_tags = tree.nodes.items(.tag); | 1873 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; |
| 1906 | const main_tokens = tree.nodes.items(.main_token); | 1874 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); |
| 1907 | const switch_node = src_loc.relativeToNodeIndex(switch_node_offset); | ||
| 1908 | const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange); | ||
| 1909 | const case_nodes = tree.extra_data[extra.start..extra.end]; | ||
| 1910 | 1875 | ||
| 1911 | var multi_i: u32 = 0; | 1876 | var multi_i: u32 = 0; |
| 1912 | var scalar_i: u32 = 0; | 1877 | var scalar_i: u32 = 0; |
| ... | @@ -1914,8 +1879,8 @@ pub const SrcLoc = struct { | ... | @@ -1914,8 +1879,8 @@ pub const SrcLoc = struct { |
| 1914 | const case = tree.fullSwitchCase(case_node).?; | 1879 | const case = tree.fullSwitchCase(case_node).?; |
| 1915 | const is_special = special: { | 1880 | const is_special = special: { |
| 1916 | if (case.ast.values.len == 0) break :special true; | 1881 | if (case.ast.values.len == 0) break :special true; |
| 1917 | if (case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .identifier) { | 1882 | if (case.ast.values.len == 1 and tree.nodeTag(case.ast.values[0]) == .identifier) { |
| 1918 | break :special mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_"); | 1883 | break :special mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(case.ast.values[0])), "_"); |
| 1919 | } | 1884 | } |
| 1920 | break :special false; | 1885 | break :special false; |
| 1921 | }; | 1886 | }; |
| ... | @@ -1927,7 +1892,7 @@ pub const SrcLoc = struct { | ... | @@ -1927,7 +1892,7 @@ pub const SrcLoc = struct { |
| 1927 | } | 1892 | } |
| 1928 | 1893 | ||
| 1929 | const is_multi = case.ast.values.len != 1 or | 1894 | const is_multi = case.ast.values.len != 1 or |
| 1930 | node_tags[case.ast.values[0]] == .switch_range; | 1895 | tree.nodeTag(case.ast.values[0]) == .switch_range; |
| 1931 | 1896 | ||
| 1932 | switch (want_case_idx.kind) { | 1897 | switch (want_case_idx.kind) { |
| 1933 | .scalar => if (!is_multi and want_case_idx.index == scalar_i) break case, | 1898 | .scalar => if (!is_multi and want_case_idx.index == scalar_i) break case, |
| ... | @@ -1947,18 +1912,17 @@ pub const SrcLoc = struct { | ... | @@ -1947,18 +1912,17 @@ pub const SrcLoc = struct { |
| 1947 | .switch_case_item_range_last, | 1912 | .switch_case_item_range_last, |
| 1948 | => |x| x.item_idx, | 1913 | => |x| x.item_idx, |
| 1949 | .switch_capture, .switch_tag_capture => { | 1914 | .switch_capture, .switch_tag_capture => { |
| 1950 | const token_tags = tree.tokens.items(.tag); | ||
| 1951 | const start = switch (src_loc.lazy) { | 1915 | const start = switch (src_loc.lazy) { |
| 1952 | .switch_capture => case.payload_token.?, | 1916 | .switch_capture => case.payload_token.?, |
| 1953 | .switch_tag_capture => tok: { | 1917 | .switch_tag_capture => tok: { |
| 1954 | var tok = case.payload_token.?; | 1918 | var tok = case.payload_token.?; |
| 1955 | if (token_tags[tok] == .asterisk) tok += 1; | 1919 | if (tree.tokenTag(tok) == .asterisk) tok += 1; |
| 1956 | tok += 2; // skip over comma | 1920 | tok = tok + 2; // skip over comma |
| 1957 | break :tok tok; | 1921 | break :tok tok; |
| 1958 | }, | 1922 | }, |
| 1959 | else => unreachable, | 1923 | else => unreachable, |
| 1960 | }; | 1924 | }; |
| 1961 | const end = switch (token_tags[start]) { | 1925 | const end = switch (tree.tokenTag(start)) { |
| 1962 | .asterisk => start + 1, | 1926 | .asterisk => start + 1, |
| 1963 | else => start, | 1927 | else => start, |
| 1964 | }; | 1928 | }; |
| ... | @@ -1971,7 +1935,7 @@ pub const SrcLoc = struct { | ... | @@ -1971,7 +1935,7 @@ pub const SrcLoc = struct { |
| 1971 | .single => { | 1935 | .single => { |
| 1972 | var item_i: u32 = 0; | 1936 | var item_i: u32 = 0; |
| 1973 | for (case.ast.values) |item_node| { | 1937 | for (case.ast.values) |item_node| { |
| 1974 | if (node_tags[item_node] == .switch_range) continue; | 1938 | if (tree.nodeTag(item_node) == .switch_range) continue; |
| 1975 | if (item_i != want_item.index) { | 1939 | if (item_i != want_item.index) { |
| 1976 | item_i += 1; | 1940 | item_i += 1; |
| 1977 | continue; | 1941 | continue; |
| ... | @@ -1982,15 +1946,16 @@ pub const SrcLoc = struct { | ... | @@ -1982,15 +1946,16 @@ pub const SrcLoc = struct { |
| 1982 | .range => { | 1946 | .range => { |
| 1983 | var range_i: u32 = 0; | 1947 | var range_i: u32 = 0; |
| 1984 | for (case.ast.values) |item_node| { | 1948 | for (case.ast.values) |item_node| { |
| 1985 | if (node_tags[item_node] != .switch_range) continue; | 1949 | if (tree.nodeTag(item_node) != .switch_range) continue; |
| 1986 | if (range_i != want_item.index) { | 1950 | if (range_i != want_item.index) { |
| 1987 | range_i += 1; | 1951 | range_i += 1; |
| 1988 | continue; | 1952 | continue; |
| 1989 | } | 1953 | } |
| 1954 | const first, const last = tree.nodeData(item_node).node_and_node; | ||
| 1990 | return switch (src_loc.lazy) { | 1955 | return switch (src_loc.lazy) { |
| 1991 | .switch_case_item => tree.nodeToSpan(item_node), | 1956 | .switch_case_item => tree.nodeToSpan(item_node), |
| 1992 | .switch_case_item_range_first => tree.nodeToSpan(node_datas[item_node].lhs), | 1957 | .switch_case_item_range_first => tree.nodeToSpan(first), |
| 1993 | .switch_case_item_range_last => tree.nodeToSpan(node_datas[item_node].rhs), | 1958 | .switch_case_item_range_last => tree.nodeToSpan(last), |
| 1994 | else => unreachable, | 1959 | else => unreachable, |
| 1995 | }; | 1960 | }; |
| 1996 | } else unreachable; | 1961 | } else unreachable; |
| ... | @@ -2013,7 +1978,7 @@ pub const SrcLoc = struct { | ... | @@ -2013,7 +1978,7 @@ pub const SrcLoc = struct { |
| 2013 | var param_it = full.iterate(tree); | 1978 | var param_it = full.iterate(tree); |
| 2014 | for (0..param_idx) |_| assert(param_it.next() != null); | 1979 | for (0..param_idx) |_| assert(param_it.next() != null); |
| 2015 | const param = param_it.next().?; | 1980 | const param = param_it.next().?; |
| 2016 | return tree.nodeToSpan(param.type_expr); | 1981 | return tree.nodeToSpan(param.type_expr.?); |
| 2017 | }, | 1982 | }, |
| 2018 | } | 1983 | } |
| 2019 | } | 1984 | } |
| ... | @@ -2044,212 +2009,217 @@ pub const LazySrcLoc = struct { | ... | @@ -2044,212 +2009,217 @@ pub const LazySrcLoc = struct { |
| 2044 | byte_abs: u32, | 2009 | byte_abs: u32, |
| 2045 | /// The source location points to a token within a source file, | 2010 | /// The source location points to a token within a source file, |
| 2046 | /// offset from 0. The source file is determined contextually. | 2011 | /// offset from 0. The source file is determined contextually. |
| 2047 | token_abs: u32, | 2012 | token_abs: Ast.TokenIndex, |
| 2048 | /// The source location points to an AST node within a source file, | 2013 | /// The source location points to an AST node within a source file, |
| 2049 | /// offset from 0. The source file is determined contextually. | 2014 | /// offset from 0. The source file is determined contextually. |
| 2050 | node_abs: u32, | 2015 | node_abs: Ast.Node.Index, |
| 2051 | /// The source location points to a byte offset within a source file, | 2016 | /// The source location points to a byte offset within a source file, |
| 2052 | /// offset from the byte offset of the base node within the file. | 2017 | /// offset from the byte offset of the base node within the file. |
| 2053 | byte_offset: u32, | 2018 | byte_offset: u32, |
| 2054 | /// This data is the offset into the token list from the base node's first token. | 2019 | /// This data is the offset into the token list from the base node's first token. |
| 2055 | token_offset: u32, | 2020 | token_offset: Ast.TokenOffset, |
| 2056 | /// The source location points to an AST node, which is this value offset | 2021 | /// The source location points to an AST node, which is this value offset |
| 2057 | /// from its containing base node AST index. | 2022 | /// from its containing base node AST index. |
| 2058 | node_offset: TracedOffset, | 2023 | node_offset: TracedOffset, |
| 2059 | /// The source location points to the main token of an AST node, found | 2024 | /// The source location points to the main token of an AST node, found |
| 2060 | /// by taking this AST node index offset from the containing base node. | 2025 | /// by taking this AST node index offset from the containing base node. |
| 2061 | node_offset_main_token: i32, | 2026 | node_offset_main_token: Ast.Node.Offset, |
| 2062 | /// The source location points to the beginning of a struct initializer. | 2027 | /// The source location points to the beginning of a struct initializer. |
| 2063 | node_offset_initializer: i32, | 2028 | node_offset_initializer: Ast.Node.Offset, |
| 2064 | /// The source location points to a variable declaration type expression, | 2029 | /// The source location points to a variable declaration type expression, |
| 2065 | /// found by taking this AST node index offset from the containing | 2030 | /// found by taking this AST node index offset from the containing |
| 2066 | /// base node, which points to a variable declaration AST node. Next, navigate | 2031 | /// base node, which points to a variable declaration AST node. Next, navigate |
| 2067 | /// to the type expression. | 2032 | /// to the type expression. |
| 2068 | node_offset_var_decl_ty: i32, | 2033 | node_offset_var_decl_ty: Ast.Node.Offset, |
| 2069 | /// The source location points to the alignment expression of a var decl. | 2034 | /// The source location points to the alignment expression of a var decl. |
| 2070 | node_offset_var_decl_align: i32, | 2035 | node_offset_var_decl_align: Ast.Node.Offset, |
| 2071 | /// The source location points to the linksection expression of a var decl. | 2036 | /// The source location points to the linksection expression of a var decl. |
| 2072 | node_offset_var_decl_section: i32, | 2037 | node_offset_var_decl_section: Ast.Node.Offset, |
| 2073 | /// The source location points to the addrspace expression of a var decl. | 2038 | /// The source location points to the addrspace expression of a var decl. |
| 2074 | node_offset_var_decl_addrspace: i32, | 2039 | node_offset_var_decl_addrspace: Ast.Node.Offset, |
| 2075 | /// The source location points to the initializer of a var decl. | 2040 | /// The source location points to the initializer of a var decl. |
| 2076 | node_offset_var_decl_init: i32, | 2041 | node_offset_var_decl_init: Ast.Node.Offset, |
| 2077 | /// The source location points to the given argument of a builtin function call. | 2042 | /// The source location points to the given argument of a builtin function call. |
| 2078 | /// `builtin_call_node` points to the builtin call. | 2043 | /// `builtin_call_node` points to the builtin call. |
| 2079 | /// `arg_index` is the index of the argument which hte source location refers to. | 2044 | /// `arg_index` is the index of the argument which hte source location refers to. |
| 2080 | node_offset_builtin_call_arg: struct { | 2045 | node_offset_builtin_call_arg: struct { |
| 2081 | builtin_call_node: i32, | 2046 | builtin_call_node: Ast.Node.Offset, |
| 2082 | arg_index: u32, | 2047 | arg_index: u32, |
| 2083 | }, | 2048 | }, |
| 2084 | /// Like `node_offset_builtin_call_arg` but recurses through arbitrarily many calls | 2049 | /// Like `node_offset_builtin_call_arg` but recurses through arbitrarily many calls |
| 2085 | /// to pointer cast builtins (taking the first argument of the most nested). | 2050 | /// to pointer cast builtins (taking the first argument of the most nested). |
| 2086 | node_offset_ptrcast_operand: i32, | 2051 | node_offset_ptrcast_operand: Ast.Node.Offset, |
| 2087 | /// The source location points to the index expression of an array access | 2052 | /// The source location points to the index expression of an array access |
| 2088 | /// expression, found by taking this AST node index offset from the containing | 2053 | /// expression, found by taking this AST node index offset from the containing |
| 2089 | /// base node, which points to an array access AST node. Next, navigate | 2054 | /// base node, which points to an array access AST node. Next, navigate |
| 2090 | /// to the index expression. | 2055 | /// to the index expression. |
| 2091 | node_offset_array_access_index: i32, | 2056 | node_offset_array_access_index: Ast.Node.Offset, |
| 2092 | /// The source location points to the LHS of a slice expression | 2057 | /// The source location points to the LHS of a slice expression |
| 2093 | /// expression, found by taking this AST node index offset from the containing | 2058 | /// expression, found by taking this AST node index offset from the containing |
| 2094 | /// base node, which points to a slice AST node. Next, navigate | 2059 | /// base node, which points to a slice AST node. Next, navigate |
| 2095 | /// to the sentinel expression. | 2060 | /// to the sentinel expression. |
| 2096 | node_offset_slice_ptr: i32, | 2061 | node_offset_slice_ptr: Ast.Node.Offset, |
| 2097 | /// The source location points to start expression of a slice expression | 2062 | /// The source location points to start expression of a slice expression |
| 2098 | /// expression, found by taking this AST node index offset from the containing | 2063 | /// expression, found by taking this AST node index offset from the containing |
| 2099 | /// base node, which points to a slice AST node. Next, navigate | 2064 | /// base node, which points to a slice AST node. Next, navigate |
| 2100 | /// to the sentinel expression. | 2065 | /// to the sentinel expression. |
| 2101 | node_offset_slice_start: i32, | 2066 | node_offset_slice_start: Ast.Node.Offset, |
| 2102 | /// The source location points to the end expression of a slice | 2067 | /// The source location points to the end expression of a slice |
| 2103 | /// expression, found by taking this AST node index offset from the containing | 2068 | /// expression, found by taking this AST node index offset from the containing |
| 2104 | /// base node, which points to a slice AST node. Next, navigate | 2069 | /// base node, which points to a slice AST node. Next, navigate |
| 2105 | /// to the sentinel expression. | 2070 | /// to the sentinel expression. |
| 2106 | node_offset_slice_end: i32, | 2071 | node_offset_slice_end: Ast.Node.Offset, |
| 2107 | /// The source location points to the sentinel expression of a slice | 2072 | /// The source location points to the sentinel expression of a slice |
| 2108 | /// expression, found by taking this AST node index offset from the containing | 2073 | /// expression, found by taking this AST node index offset from the containing |
| 2109 | /// base node, which points to a slice AST node. Next, navigate | 2074 | /// base node, which points to a slice AST node. Next, navigate |
| 2110 | /// to the sentinel expression. | 2075 | /// to the sentinel expression. |
| 2111 | node_offset_slice_sentinel: i32, | 2076 | node_offset_slice_sentinel: Ast.Node.Offset, |
| 2112 | /// The source location points to the callee expression of a function | 2077 | /// The source location points to the callee expression of a function |
| 2113 | /// call expression, found by taking this AST node index offset from the containing | 2078 | /// call expression, found by taking this AST node index offset from the containing |
| 2114 | /// base node, which points to a function call AST node. Next, navigate | 2079 | /// base node, which points to a function call AST node. Next, navigate |
| 2115 | /// to the callee expression. | 2080 | /// to the callee expression. |
| 2116 | node_offset_call_func: i32, | 2081 | node_offset_call_func: Ast.Node.Offset, |
| 2117 | /// The payload is offset from the containing base node. | 2082 | /// The payload is offset from the containing base node. |
| 2118 | /// The source location points to the field name of: | 2083 | /// The source location points to the field name of: |
| 2119 | /// * a field access expression (`a.b`), or | 2084 | /// * a field access expression (`a.b`), or |
| 2120 | /// * the callee of a method call (`a.b()`) | 2085 | /// * the callee of a method call (`a.b()`) |
| 2121 | node_offset_field_name: i32, | 2086 | node_offset_field_name: Ast.Node.Offset, |
| 2122 | /// The payload is offset from the containing base node. | 2087 | /// The payload is offset from the containing base node. |
| 2123 | /// The source location points to the field name of the operand ("b" node) | 2088 | /// The source location points to the field name of the operand ("b" node) |
| 2124 | /// of a field initialization expression (`.a = b`) | 2089 | /// of a field initialization expression (`.a = b`) |
| 2125 | node_offset_field_name_init: i32, | 2090 | node_offset_field_name_init: Ast.Node.Offset, |
| 2126 | /// The source location points to the pointer of a pointer deref expression, | 2091 | /// The source location points to the pointer of a pointer deref expression, |
| 2127 | /// found by taking this AST node index offset from the containing | 2092 | /// found by taking this AST node index offset from the containing |
| 2128 | /// base node, which points to a pointer deref AST node. Next, navigate | 2093 | /// base node, which points to a pointer deref AST node. Next, navigate |
| 2129 | /// to the pointer expression. | 2094 | /// to the pointer expression. |
| 2130 | node_offset_deref_ptr: i32, | 2095 | node_offset_deref_ptr: Ast.Node.Offset, |
| 2131 | /// The source location points to the assembly source code of an inline assembly | 2096 | /// The source location points to the assembly source code of an inline assembly |
| 2132 | /// expression, found by taking this AST node index offset from the containing | 2097 | /// expression, found by taking this AST node index offset from the containing |
| 2133 | /// base node, which points to inline assembly AST node. Next, navigate | 2098 | /// base node, which points to inline assembly AST node. Next, navigate |
| 2134 | /// to the asm template source code. | 2099 | /// to the asm template source code. |
| 2135 | node_offset_asm_source: i32, | 2100 | node_offset_asm_source: Ast.Node.Offset, |
| 2136 | /// The source location points to the return type of an inline assembly | 2101 | /// The source location points to the return type of an inline assembly |
| 2137 | /// expression, found by taking this AST node index offset from the containing | 2102 | /// expression, found by taking this AST node index offset from the containing |
| 2138 | /// base node, which points to inline assembly AST node. Next, navigate | 2103 | /// base node, which points to inline assembly AST node. Next, navigate |
| 2139 | /// to the return type expression. | 2104 | /// to the return type expression. |
| 2140 | node_offset_asm_ret_ty: i32, | 2105 | node_offset_asm_ret_ty: Ast.Node.Offset, |
| 2141 | /// The source location points to the condition expression of an if | 2106 | /// The source location points to the condition expression of an if |
| 2142 | /// expression, found by taking this AST node index offset from the containing | 2107 | /// expression, found by taking this AST node index offset from the containing |
| 2143 | /// base node, which points to an if expression AST node. Next, navigate | 2108 | /// base node, which points to an if expression AST node. Next, navigate |
| 2144 | /// to the condition expression. | 2109 | /// to the condition expression. |
| 2145 | node_offset_if_cond: i32, | 2110 | node_offset_if_cond: Ast.Node.Offset, |
| 2146 | /// The source location points to a binary expression, such as `a + b`, found | 2111 | /// The source location points to a binary expression, such as `a + b`, found |
| 2147 | /// 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. |
| 2148 | node_offset_bin_op: i32, | 2113 | node_offset_bin_op: Ast.Node.Offset, |
| 2149 | /// The source location points to the LHS of a binary expression, found | 2114 | /// The source location points to the LHS of a binary expression, found |
| 2150 | /// by taking this AST node index offset from the containing base node, | 2115 | /// by taking this AST node index offset from the containing base node, |
| 2151 | /// which points to a binary expression AST node. Next, navigate to the LHS. | 2116 | /// which points to a binary expression AST node. Next, navigate to the LHS. |
| 2152 | node_offset_bin_lhs: i32, | 2117 | node_offset_bin_lhs: Ast.Node.Offset, |
| 2153 | /// The source location points to the RHS of a binary expression, found | 2118 | /// The source location points to the RHS of a binary expression, found |
| 2154 | /// by taking this AST node index offset from the containing base node, | 2119 | /// by taking this AST node index offset from the containing base node, |
| 2155 | /// which points to a binary expression AST node. Next, navigate to the RHS. | 2120 | /// which points to a binary expression AST node. Next, navigate to the RHS. |
| 2156 | node_offset_bin_rhs: i32, | 2121 | node_offset_bin_rhs: Ast.Node.Offset, |
| 2122 | /// The source location points to the operand of a try expression, found | ||
| 2123 | /// by taking this AST node index offset from the containing base node, | ||
| 2124 | /// which points to a try expression AST node. Next, navigate to the | ||
| 2125 | /// operand expression. | ||
| 2126 | node_offset_try_operand: Ast.Node.Offset, | ||
| 2157 | /// The source location points to the operand of a switch expression, found | 2127 | /// The source location points to the operand of a switch expression, found |
| 2158 | /// by taking this AST node index offset from the containing base node, | 2128 | /// by taking this AST node index offset from the containing base node, |
| 2159 | /// which points to a switch expression AST node. Next, navigate to the operand. | 2129 | /// which points to a switch expression AST node. Next, navigate to the operand. |
| 2160 | node_offset_switch_operand: i32, | 2130 | node_offset_switch_operand: Ast.Node.Offset, |
| 2161 | /// The source location points to the else/`_` prong of a switch expression, found | 2131 | /// The source location points to the else/`_` prong of a switch expression, found |
| 2162 | /// by taking this AST node index offset from the containing base node, | 2132 | /// by taking this AST node index offset from the containing base node, |
| 2163 | /// which points to a switch expression AST node. Next, navigate to the else/`_` prong. | 2133 | /// which points to a switch expression AST node. Next, navigate to the else/`_` prong. |
| 2164 | node_offset_switch_special_prong: i32, | 2134 | node_offset_switch_special_prong: Ast.Node.Offset, |
| 2165 | /// The source location points to all the ranges of a switch expression, found | 2135 | /// The source location points to all the ranges of a switch expression, found |
| 2166 | /// by taking this AST node index offset from the containing base node, | 2136 | /// by taking this AST node index offset from the containing base node, |
| 2167 | /// which points to a switch expression AST node. Next, navigate to any of the | 2137 | /// which points to a switch expression AST node. Next, navigate to any of the |
| 2168 | /// range nodes. The error applies to all of them. | 2138 | /// range nodes. The error applies to all of them. |
| 2169 | node_offset_switch_range: i32, | 2139 | node_offset_switch_range: Ast.Node.Offset, |
| 2170 | /// The source location points to the align expr of a function type | 2140 | /// The source location points to the align expr of a function type |
| 2171 | /// expression, found by taking this AST node index offset from the containing | 2141 | /// expression, found by taking this AST node index offset from the containing |
| 2172 | /// base node, which points to a function type AST node. Next, navigate to | 2142 | /// base node, which points to a function type AST node. Next, navigate to |
| 2173 | /// the calling convention node. | 2143 | /// the calling convention node. |
| 2174 | node_offset_fn_type_align: i32, | 2144 | node_offset_fn_type_align: Ast.Node.Offset, |
| 2175 | /// The source location points to the addrspace expr of a function type | 2145 | /// The source location points to the addrspace expr of a function type |
| 2176 | /// expression, found by taking this AST node index offset from the containing | 2146 | /// expression, found by taking this AST node index offset from the containing |
| 2177 | /// base node, which points to a function type AST node. Next, navigate to | 2147 | /// base node, which points to a function type AST node. Next, navigate to |
| 2178 | /// the calling convention node. | 2148 | /// the calling convention node. |
| 2179 | node_offset_fn_type_addrspace: i32, | 2149 | node_offset_fn_type_addrspace: Ast.Node.Offset, |
| 2180 | /// The source location points to the linksection expr of a function type | 2150 | /// The source location points to the linksection expr of a function type |
| 2181 | /// expression, found by taking this AST node index offset from the containing | 2151 | /// expression, found by taking this AST node index offset from the containing |
| 2182 | /// base node, which points to a function type AST node. Next, navigate to | 2152 | /// base node, which points to a function type AST node. Next, navigate to |
| 2183 | /// the calling convention node. | 2153 | /// the calling convention node. |
| 2184 | node_offset_fn_type_section: i32, | 2154 | node_offset_fn_type_section: Ast.Node.Offset, |
| 2185 | /// The source location points to the calling convention of a function type | 2155 | /// The source location points to the calling convention of a function type |
| 2186 | /// expression, found by taking this AST node index offset from the containing | 2156 | /// expression, found by taking this AST node index offset from the containing |
| 2187 | /// base node, which points to a function type AST node. Next, navigate to | 2157 | /// base node, which points to a function type AST node. Next, navigate to |
| 2188 | /// the calling convention node. | 2158 | /// the calling convention node. |
| 2189 | node_offset_fn_type_cc: i32, | 2159 | node_offset_fn_type_cc: Ast.Node.Offset, |
| 2190 | /// The source location points to the return type of a function type | 2160 | /// The source location points to the return type of a function type |
| 2191 | /// expression, found by taking this AST node index offset from the containing | 2161 | /// expression, found by taking this AST node index offset from the containing |
| 2192 | /// base node, which points to a function type AST node. Next, navigate to | 2162 | /// base node, which points to a function type AST node. Next, navigate to |
| 2193 | /// the return type node. | 2163 | /// the return type node. |
| 2194 | node_offset_fn_type_ret_ty: i32, | 2164 | node_offset_fn_type_ret_ty: Ast.Node.Offset, |
| 2195 | node_offset_param: i32, | 2165 | node_offset_param: Ast.Node.Offset, |
| 2196 | token_offset_param: i32, | 2166 | token_offset_param: Ast.TokenOffset, |
| 2197 | /// The source location points to the type expression of an `anyframe->T` | 2167 | /// The source location points to the type expression of an `anyframe->T` |
| 2198 | /// expression, found by taking this AST node index offset from the containing | 2168 | /// expression, found by taking this AST node index offset from the containing |
| 2199 | /// base node, which points to a `anyframe->T` expression AST node. Next, navigate | 2169 | /// base node, which points to a `anyframe->T` expression AST node. Next, navigate |
| 2200 | /// to the type expression. | 2170 | /// to the type expression. |
| 2201 | node_offset_anyframe_type: i32, | 2171 | node_offset_anyframe_type: Ast.Node.Offset, |
| 2202 | /// The source location points to the string literal of `extern "foo"`, found | 2172 | /// The source location points to the string literal of `extern "foo"`, found |
| 2203 | /// by taking this AST node index offset from the containing | 2173 | /// by taking this AST node index offset from the containing |
| 2204 | /// base node, which points to a function prototype or variable declaration | 2174 | /// base node, which points to a function prototype or variable declaration |
| 2205 | /// expression AST node. Next, navigate to the string literal of the `extern "foo"`. | 2175 | /// expression AST node. Next, navigate to the string literal of the `extern "foo"`. |
| 2206 | node_offset_lib_name: i32, | 2176 | node_offset_lib_name: Ast.Node.Offset, |
| 2207 | /// The source location points to the len expression of an `[N:S]T` | 2177 | /// The source location points to the len expression of an `[N:S]T` |
| 2208 | /// expression, found by taking this AST node index offset from the containing | 2178 | /// expression, found by taking this AST node index offset from the containing |
| 2209 | /// base node, which points to an `[N:S]T` expression AST node. Next, navigate | 2179 | /// base node, which points to an `[N:S]T` expression AST node. Next, navigate |
| 2210 | /// to the len expression. | 2180 | /// to the len expression. |
| 2211 | node_offset_array_type_len: i32, | 2181 | node_offset_array_type_len: Ast.Node.Offset, |
| 2212 | /// The source location points to the sentinel expression of an `[N:S]T` | 2182 | /// The source location points to the sentinel expression of an `[N:S]T` |
| 2213 | /// expression, found by taking this AST node index offset from the containing | 2183 | /// expression, found by taking this AST node index offset from the containing |
| 2214 | /// base node, which points to an `[N:S]T` expression AST node. Next, navigate | 2184 | /// base node, which points to an `[N:S]T` expression AST node. Next, navigate |
| 2215 | /// to the sentinel expression. | 2185 | /// to the sentinel expression. |
| 2216 | node_offset_array_type_sentinel: i32, | 2186 | node_offset_array_type_sentinel: Ast.Node.Offset, |
| 2217 | /// The source location points to the elem expression of an `[N:S]T` | 2187 | /// The source location points to the elem expression of an `[N:S]T` |
| 2218 | /// expression, found by taking this AST node index offset from the containing | 2188 | /// expression, found by taking this AST node index offset from the containing |
| 2219 | /// base node, which points to an `[N:S]T` expression AST node. Next, navigate | 2189 | /// base node, which points to an `[N:S]T` expression AST node. Next, navigate |
| 2220 | /// to the elem expression. | 2190 | /// to the elem expression. |
| 2221 | node_offset_array_type_elem: i32, | 2191 | node_offset_array_type_elem: Ast.Node.Offset, |
| 2222 | /// The source location points to the operand of an unary expression. | 2192 | /// The source location points to the operand of an unary expression. |
| 2223 | node_offset_un_op: i32, | 2193 | node_offset_un_op: Ast.Node.Offset, |
| 2224 | /// The source location points to the elem type of a pointer. | 2194 | /// The source location points to the elem type of a pointer. |
| 2225 | node_offset_ptr_elem: i32, | 2195 | node_offset_ptr_elem: Ast.Node.Offset, |
| 2226 | /// The source location points to the sentinel of a pointer. | 2196 | /// The source location points to the sentinel of a pointer. |
| 2227 | node_offset_ptr_sentinel: i32, | 2197 | node_offset_ptr_sentinel: Ast.Node.Offset, |
| 2228 | /// The source location points to the align expr of a pointer. | 2198 | /// The source location points to the align expr of a pointer. |
| 2229 | node_offset_ptr_align: i32, | 2199 | node_offset_ptr_align: Ast.Node.Offset, |
| 2230 | /// The source location points to the addrspace expr of a pointer. | 2200 | /// The source location points to the addrspace expr of a pointer. |
| 2231 | node_offset_ptr_addrspace: i32, | 2201 | node_offset_ptr_addrspace: Ast.Node.Offset, |
| 2232 | /// The source location points to the bit-offset of a pointer. | 2202 | /// The source location points to the bit-offset of a pointer. |
| 2233 | node_offset_ptr_bitoffset: i32, | 2203 | node_offset_ptr_bitoffset: Ast.Node.Offset, |
| 2234 | /// The source location points to the host size of a pointer. | 2204 | /// The source location points to the host size of a pointer. |
| 2235 | node_offset_ptr_hostsize: i32, | 2205 | node_offset_ptr_hostsize: Ast.Node.Offset, |
| 2236 | /// The source location points to the tag type of an union or an enum. | 2206 | /// The source location points to the tag type of an union or an enum. |
| 2237 | node_offset_container_tag: i32, | 2207 | node_offset_container_tag: Ast.Node.Offset, |
| 2238 | /// The source location points to the default value of a field. | 2208 | /// The source location points to the default value of a field. |
| 2239 | node_offset_field_default: i32, | 2209 | node_offset_field_default: Ast.Node.Offset, |
| 2240 | /// The source location points to the type of an array or struct initializer. | 2210 | /// The source location points to the type of an array or struct initializer. |
| 2241 | node_offset_init_ty: i32, | 2211 | node_offset_init_ty: Ast.Node.Offset, |
| 2242 | /// The source location points to the LHS of an assignment. | 2212 | /// The source location points to the LHS of an assignment. |
| 2243 | node_offset_store_ptr: i32, | 2213 | node_offset_store_ptr: Ast.Node.Offset, |
| 2244 | /// The source location points to the RHS of an assignment. | 2214 | /// The source location points to the RHS of an assignment. |
| 2245 | node_offset_store_operand: i32, | 2215 | node_offset_store_operand: Ast.Node.Offset, |
| 2246 | /// The source location points to the operand of a `return` statement, or | 2216 | /// The source location points to the operand of a `return` statement, or |
| 2247 | /// the `return` itself if there is no explicit operand. | 2217 | /// the `return` itself if there is no explicit operand. |
| 2248 | node_offset_return_operand: i32, | 2218 | node_offset_return_operand: Ast.Node.Offset, |
| 2249 | /// The source location points to a for loop input. | 2219 | /// The source location points to a for loop input. |
| 2250 | for_input: struct { | 2220 | for_input: struct { |
| 2251 | /// Points to the for loop AST node. | 2221 | /// Points to the for loop AST node. |
| 2252 | for_node_offset: i32, | 2222 | for_node_offset: Ast.Node.Offset, |
| 2253 | /// Picks one of the inputs from the condition. | 2223 | /// Picks one of the inputs from the condition. |
| 2254 | input_index: u32, | 2224 | input_index: u32, |
| 2255 | }, | 2225 | }, |
| ... | @@ -2257,11 +2227,11 @@ pub const LazySrcLoc = struct { | ... | @@ -2257,11 +2227,11 @@ pub const LazySrcLoc = struct { |
| 2257 | /// by taking this AST node index offset from the containing | 2227 | /// by taking this AST node index offset from the containing |
| 2258 | /// base node, which points to one of the input nodes of a for loop. | 2228 | /// base node, which points to one of the input nodes of a for loop. |
| 2259 | /// Next, navigate to the corresponding capture. | 2229 | /// Next, navigate to the corresponding capture. |
| 2260 | for_capture_from_input: i32, | 2230 | for_capture_from_input: Ast.Node.Offset, |
| 2261 | /// The source location points to the argument node of a function call. | 2231 | /// The source location points to the argument node of a function call. |
| 2262 | call_arg: struct { | 2232 | call_arg: struct { |
| 2263 | /// Points to the function call AST node. | 2233 | /// Points to the function call AST node. |
| 2264 | call_node_offset: i32, | 2234 | call_node_offset: Ast.Node.Offset, |
| 2265 | /// The index of the argument the source location points to. | 2235 | /// The index of the argument the source location points to. |
| 2266 | arg_index: u32, | 2236 | arg_index: u32, |
| 2267 | }, | 2237 | }, |
| ... | @@ -2288,25 +2258,25 @@ pub const LazySrcLoc = struct { | ... | @@ -2288,25 +2258,25 @@ pub const LazySrcLoc = struct { |
| 2288 | /// array initialization expression. | 2258 | /// array initialization expression. |
| 2289 | init_elem: struct { | 2259 | init_elem: struct { |
| 2290 | /// Points to the AST node of the initialization expression. | 2260 | /// Points to the AST node of the initialization expression. |
| 2291 | init_node_offset: i32, | 2261 | init_node_offset: Ast.Node.Offset, |
| 2292 | /// The index of the field/element the source location points to. | 2262 | /// The index of the field/element the source location points to. |
| 2293 | elem_index: u32, | 2263 | elem_index: u32, |
| 2294 | }, | 2264 | }, |
| 2295 | // The following source locations are like `init_elem`, but refer to a | 2265 | // The following source locations are like `init_elem`, but refer to a |
| 2296 | // field with a specific name. If such a field is not given, the entire | 2266 | // field with a specific name. If such a field is not given, the entire |
| 2297 | // initialization expression is used instead. | 2267 | // initialization expression is used instead. |
| 2298 | // The `i32` points to the AST node of a builtin call, whose *second* | 2268 | // The `Ast.Node.Offset` points to the AST node of a builtin call, whose *second* |
| 2299 | // argument is the init expression. | 2269 | // argument is the init expression. |
| 2300 | init_field_name: i32, | 2270 | init_field_name: Ast.Node.Offset, |
| 2301 | init_field_linkage: i32, | 2271 | init_field_linkage: Ast.Node.Offset, |
| 2302 | init_field_section: i32, | 2272 | init_field_section: Ast.Node.Offset, |
| 2303 | init_field_visibility: i32, | 2273 | init_field_visibility: Ast.Node.Offset, |
| 2304 | init_field_rw: i32, | 2274 | init_field_rw: Ast.Node.Offset, |
| 2305 | init_field_locality: i32, | 2275 | init_field_locality: Ast.Node.Offset, |
| 2306 | init_field_cache: i32, | 2276 | init_field_cache: Ast.Node.Offset, |
| 2307 | init_field_library: i32, | 2277 | init_field_library: Ast.Node.Offset, |
| 2308 | init_field_thread_local: i32, | 2278 | init_field_thread_local: Ast.Node.Offset, |
| 2309 | init_field_dll_import: i32, | 2279 | init_field_dll_import: Ast.Node.Offset, |
| 2310 | /// The source location points to the value of an item in a specific | 2280 | /// The source location points to the value of an item in a specific |
| 2311 | /// case of a `switch`. | 2281 | /// case of a `switch`. |
| 2312 | switch_case_item: SwitchItem, | 2282 | switch_case_item: SwitchItem, |
| ... | @@ -2331,14 +2301,14 @@ pub const LazySrcLoc = struct { | ... | @@ -2331,14 +2301,14 @@ pub const LazySrcLoc = struct { |
| 2331 | 2301 | ||
| 2332 | pub const FnProtoParam = struct { | 2302 | pub const FnProtoParam = struct { |
| 2333 | /// The offset of the function prototype AST node. | 2303 | /// The offset of the function prototype AST node. |
| 2334 | fn_proto_node_offset: i32, | 2304 | fn_proto_node_offset: Ast.Node.Offset, |
| 2335 | /// The index of the parameter the source location points to. | 2305 | /// The index of the parameter the source location points to. |
| 2336 | param_index: u32, | 2306 | param_index: u32, |
| 2337 | }; | 2307 | }; |
| 2338 | 2308 | ||
| 2339 | pub const SwitchItem = struct { | 2309 | pub const SwitchItem = struct { |
| 2340 | /// The offset of the switch AST node. | 2310 | /// The offset of the switch AST node. |
| 2341 | switch_node_offset: i32, | 2311 | switch_node_offset: Ast.Node.Offset, |
| 2342 | /// The index of the case to point to within this switch. | 2312 | /// The index of the case to point to within this switch. |
| 2343 | case_idx: SwitchCaseIndex, | 2313 | case_idx: SwitchCaseIndex, |
| 2344 | /// The index of the item to point to within this case. | 2314 | /// The index of the item to point to within this case. |
| ... | @@ -2347,7 +2317,7 @@ pub const LazySrcLoc = struct { | ... | @@ -2347,7 +2317,7 @@ pub const LazySrcLoc = struct { |
| 2347 | 2317 | ||
| 2348 | pub const SwitchCapture = struct { | 2318 | pub const SwitchCapture = struct { |
| 2349 | /// The offset of the switch AST node. | 2319 | /// The offset of the switch AST node. |
| 2350 | switch_node_offset: i32, | 2320 | switch_node_offset: Ast.Node.Offset, |
| 2351 | /// The index of the case whose capture to point to. | 2321 | /// The index of the case whose capture to point to. |
| 2352 | case_idx: SwitchCaseIndex, | 2322 | case_idx: SwitchCaseIndex, |
| 2353 | }; | 2323 | }; |
| ... | @@ -2369,34 +2339,34 @@ pub const LazySrcLoc = struct { | ... | @@ -2369,34 +2339,34 @@ pub const LazySrcLoc = struct { |
| 2369 | 2339 | ||
| 2370 | pub const ArrayCat = struct { | 2340 | pub const ArrayCat = struct { |
| 2371 | /// Points to the array concat AST node. | 2341 | /// Points to the array concat AST node. |
| 2372 | array_cat_offset: i32, | 2342 | array_cat_offset: Ast.Node.Offset, |
| 2373 | /// The index of the element the source location points to. | 2343 | /// The index of the element the source location points to. |
| 2374 | elem_index: u32, | 2344 | elem_index: u32, |
| 2375 | }; | 2345 | }; |
| 2376 | 2346 | ||
| 2377 | pub const TupleField = struct { | 2347 | pub const TupleField = struct { |
| 2378 | /// Points to the AST node of the tuple type decaration. | 2348 | /// Points to the AST node of the tuple type decaration. |
| 2379 | tuple_decl_node_offset: i32, | 2349 | tuple_decl_node_offset: Ast.Node.Offset, |
| 2380 | /// The index of the tuple field the source location points to. | 2350 | /// The index of the tuple field the source location points to. |
| 2381 | elem_index: u32, | 2351 | elem_index: u32, |
| 2382 | }; | 2352 | }; |
| 2383 | 2353 | ||
| 2384 | pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease; | 2354 | pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease; |
| 2385 | 2355 | ||
| 2386 | noinline fn nodeOffsetDebug(node_offset: i32) Offset { | 2356 | noinline fn nodeOffsetDebug(node_offset: Ast.Node.Offset) Offset { |
| 2387 | var result: LazySrcLoc = .{ .node_offset = .{ .x = node_offset } }; | 2357 | var result: LazySrcLoc = .{ .node_offset = .{ .x = node_offset } }; |
| 2388 | result.node_offset.trace.addAddr(@returnAddress(), "init"); | 2358 | result.node_offset.trace.addAddr(@returnAddress(), "init"); |
| 2389 | return result; | 2359 | return result; |
| 2390 | } | 2360 | } |
| 2391 | 2361 | ||
| 2392 | fn nodeOffsetRelease(node_offset: i32) Offset { | 2362 | fn nodeOffsetRelease(node_offset: Ast.Node.Offset) Offset { |
| 2393 | return .{ .node_offset = .{ .x = node_offset } }; | 2363 | return .{ .node_offset = .{ .x = node_offset } }; |
| 2394 | } | 2364 | } |
| 2395 | 2365 | ||
| 2396 | /// This wraps a simple integer in debug builds so that later on we can find out | 2366 | /// This wraps a simple integer in debug builds so that later on we can find out |
| 2397 | /// where in semantic analysis the value got set. | 2367 | /// where in semantic analysis the value got set. |
| 2398 | pub const TracedOffset = struct { | 2368 | pub const TracedOffset = struct { |
| 2399 | x: i32, | 2369 | x: Ast.Node.Offset, |
| 2400 | trace: std.debug.Trace = std.debug.Trace.init, | 2370 | trace: std.debug.Trace = std.debug.Trace.init, |
| 2401 | 2371 | ||
| 2402 | const want_tracing = false; | 2372 | const want_tracing = false; |
| ... | @@ -2421,7 +2391,7 @@ pub const LazySrcLoc = struct { | ... | @@ -2421,7 +2391,7 @@ pub const LazySrcLoc = struct { |
| 2421 | 2391 | ||
| 2422 | // If we're relative to .main_struct_inst, we know the ast node is the root and don't need to resolve the ZIR, | 2392 | // If we're relative to .main_struct_inst, we know the ast node is the root and don't need to resolve the ZIR, |
| 2423 | // which may not exist e.g. in the case of errors in ZON files. | 2393 | // which may not exist e.g. in the case of errors in ZON files. |
| 2424 | if (zir_inst == .main_struct_inst) return .{ file, 0 }; | 2394 | if (zir_inst == .main_struct_inst) return .{ file, .root }; |
| 2425 | 2395 | ||
| 2426 | // Otherwise, make sure ZIR is loaded. | 2396 | // Otherwise, make sure ZIR is loaded. |
| 2427 | const zir = file.zir.?; | 2397 | const zir = file.zir.?; |
| ... | @@ -2454,7 +2424,7 @@ pub const LazySrcLoc = struct { | ... | @@ -2454,7 +2424,7 @@ pub const LazySrcLoc = struct { |
| 2454 | pub fn upgradeOrLost(lazy: LazySrcLoc, zcu: *Zcu) ?SrcLoc { | 2424 | pub fn upgradeOrLost(lazy: LazySrcLoc, zcu: *Zcu) ?SrcLoc { |
| 2455 | const file, const base_node: Ast.Node.Index = if (lazy.offset == .entire_file) .{ | 2425 | const file, const base_node: Ast.Node.Index = if (lazy.offset == .entire_file) .{ |
| 2456 | zcu.fileByIndex(lazy.base_node_inst.resolveFile(&zcu.intern_pool)), | 2426 | zcu.fileByIndex(lazy.base_node_inst.resolveFile(&zcu.intern_pool)), |
| 2457 | 0, | 2427 | .root, |
| 2458 | } else resolveBaseNode(lazy.base_node_inst, zcu) orelse return null; | 2428 | } else resolveBaseNode(lazy.base_node_inst, zcu) orelse return null; |
| 2459 | return .{ | 2429 | return .{ |
| 2460 | .file_scope = file, | 2430 | .file_scope = file, |
| ... | @@ -4023,7 +3993,7 @@ pub fn navSrcLoc(zcu: *const Zcu, nav_index: InternPool.Nav.Index) LazySrcLoc { | ... | @@ -4023,7 +3993,7 @@ pub fn navSrcLoc(zcu: *const Zcu, nav_index: InternPool.Nav.Index) LazySrcLoc { |
| 4023 | const ip = &zcu.intern_pool; | 3993 | const ip = &zcu.intern_pool; |
| 4024 | return .{ | 3994 | return .{ |
| 4025 | .base_node_inst = ip.getNav(nav_index).srcInst(ip), | 3995 | .base_node_inst = ip.getNav(nav_index).srcInst(ip), |
| 4026 | .offset = LazySrcLoc.Offset.nodeOffset(0), | 3996 | .offset = LazySrcLoc.Offset.nodeOffset(.zero), |
| 4027 | }; | 3997 | }; |
| 4028 | } | 3998 | } |
| 4029 | 3999 |
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+13-7| ... | @@ -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,15 +7284,19 @@ fn cmdFetch( | ... | @@ -7282,15 +7284,19 @@ 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 | try fixups.replace_nodes_with_string.put(gpa, dep.hash_node, hash_replace); | 7287 | if (dep.hash_node.unwrap()) |hash_node| { |
| 7288 | try fixups.replace_nodes_with_string.put(gpa, hash_node, hash_replace); | ||
| 7289 | } else { | ||
| 7290 | // https://github.com/ziglang/zig/issues/21690 | ||
| 7291 | } | ||
| 7286 | } else if (manifest.dependencies.count() > 0) { | 7292 | } else if (manifest.dependencies.count() > 0) { |
| 7287 | // Add fixup for adding another dependency. | 7293 | // Add fixup for adding another dependency. |
| 7288 | const deps = manifest.dependencies.values(); | 7294 | const deps = manifest.dependencies.values(); |
| 7289 | const last_dep_node = deps[deps.len - 1].node; | 7295 | const last_dep_node = deps[deps.len - 1].node; |
| 7290 | 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); |
| 7291 | } else if (manifest.dependencies_node != 0) { | 7297 | } else if (manifest.dependencies_node.unwrap()) |dependencies_node| { |
| 7292 | // Add fixup for replacing the entire dependencies struct. | 7298 | // Add fixup for replacing the entire dependencies struct. |
| 7293 | 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); |
| 7294 | } else { | 7300 | } else { |
| 7295 | // Add fixup for adding dependencies struct. | 7301 | // Add fixup for adding dependencies struct. |
| 7296 | 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); |
test/cases/translate_c/continue_from_while.c created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | void foo() { | ||
| 2 | for (;;) { | ||
| 3 | continue; | ||
| 4 | } | ||
| 5 | } | ||
| 6 | |||
| 7 | // translate-c | ||
| 8 | // c_frontend=clang | ||
| 9 | // | ||
| 10 | // pub export fn foo() void { | ||
| 11 | // while (true) { | ||
| 12 | // continue; | ||
| 13 | // } | ||
| 14 | // } | ||