| ... | @@ -210,7 +210,7 @@ pub fn parseZon(p: *Parse) !void { | ... | @@ -210,7 +210,7 @@ pub fn parseZon(p: *Parse) !void { |
| 210 | /// ContainerDeclaration <- TestDecl / ComptimeDecl / doc_comment? KEYWORD_pub? Decl | 210 | /// ContainerDeclaration <- TestDecl / ComptimeDecl / doc_comment? KEYWORD_pub? Decl |
| 211 | /// | 211 | /// |
| 212 | /// ComptimeDecl <- KEYWORD_comptime Block | 212 | /// ComptimeDecl <- KEYWORD_comptime Block |
| 213 | fn parseContainerMembers(p: *Parse) !Members { | 213 | fn parseContainerMembers(p: *Parse) Allocator.Error!Members { |
| 214 | const scratch_top = p.scratch.items.len; | 214 | const scratch_top = p.scratch.items.len; |
| 215 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 215 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 216 | | 216 | |
| ... | @@ -565,12 +565,9 @@ fn findNextStmt(p: *Parse) void { | ... | @@ -565,12 +565,9 @@ fn findNextStmt(p: *Parse) void { |
| 565 | /// TestDecl <- KEYWORD_test (STRINGLITERALSINGLE / IDENTIFIER)? Block | 565 | /// TestDecl <- KEYWORD_test (STRINGLITERALSINGLE / IDENTIFIER)? Block |
| 566 | fn expectTestDecl(p: *Parse) !Node.Index { | 566 | fn expectTestDecl(p: *Parse) !Node.Index { |
| 567 | const test_token = p.assertToken(.keyword_test); | 567 | const test_token = p.assertToken(.keyword_test); |
| 568 | const name_token = switch (p.token_tags[p.nextToken()]) { | 568 | const name_token = switch (p.token_tags[p.tok_i]) { |
| 569 | .string_literal, .identifier => p.tok_i - 1, | 569 | .string_literal, .identifier => p.nextToken(), |
| 570 | else => blk: { | 570 | else => null, |
| 571 | p.tok_i -= 1; | | |
| 572 | break :blk null; | | |
| 573 | }, | | |
| 574 | }; | 571 | }; |
| 575 | const block_node = try p.parseBlock(); | 572 | const block_node = try p.parseBlock(); |
| 576 | if (block_node == 0) return p.fail(.expected_block); | 573 | if (block_node == 0) return p.fail(.expected_block); |
| ... | @@ -922,8 +919,8 @@ fn expectContainerField(p: *Parse) !Node.Index { | ... | @@ -922,8 +919,8 @@ fn expectContainerField(p: *Parse) !Node.Index { |
| 922 | .data = .{ | 919 | .data = .{ |
| 923 | .lhs = type_expr, | 920 | .lhs = type_expr, |
| 924 | .rhs = try p.addExtra(Node.ContainerField{ | 921 | .rhs = try p.addExtra(Node.ContainerField{ |
| 925 | .value_expr = value_expr, | | |
| 926 | .align_expr = align_expr, | 922 | .align_expr = align_expr, |
| | 923 | .value_expr = value_expr, |
| 927 | }), | 924 | }), |
| 928 | }, | 925 | }, |
| 929 | }); | 926 | }); |
| ... | @@ -2051,9 +2048,9 @@ fn parseTypeExpr(p: *Parse) Error!Node.Index { | ... | @@ -2051,9 +2048,9 @@ fn parseTypeExpr(p: *Parse) Error!Node.Index { |
| 2051 | .main_token = lbracket, | 2048 | .main_token = lbracket, |
| 2052 | .data = .{ | 2049 | .data = .{ |
| 2053 | .lhs = len_expr, | 2050 | .lhs = len_expr, |
| 2054 | .rhs = try p.addExtra(.{ | 2051 | .rhs = try p.addExtra(Node.ArrayTypeSentinel{ |
| 2055 | .elem_type = elem_type, | | |
| 2056 | .sentinel = sentinel, | 2052 | .sentinel = sentinel, |
| | 2053 | .elem_type = elem_type, |
| 2057 | }), | 2054 | }), |
| 2058 | }, | 2055 | }, |
| 2059 | }); | 2056 | }); |
| ... | @@ -2090,10 +2087,9 @@ fn parsePrimaryExpr(p: *Parse) !Node.Index { | ... | @@ -2090,10 +2087,9 @@ fn parsePrimaryExpr(p: *Parse) !Node.Index { |
| 2090 | .keyword_asm => return p.expectAsmExpr(), | 2087 | .keyword_asm => return p.expectAsmExpr(), |
| 2091 | .keyword_if => return p.parseIfExpr(), | 2088 | .keyword_if => return p.parseIfExpr(), |
| 2092 | .keyword_break => { | 2089 | .keyword_break => { |
| 2093 | p.tok_i += 1; | | |
| 2094 | return p.addNode(.{ | 2090 | return p.addNode(.{ |
| 2095 | .tag = .@"break", | 2091 | .tag = .@"break", |
| 2096 | .main_token = p.tok_i - 1, | 2092 | .main_token = p.nextToken(), |
| 2097 | .data = .{ | 2093 | .data = .{ |
| 2098 | .lhs = try p.parseBreakLabel(), | 2094 | .lhs = try p.parseBreakLabel(), |
| 2099 | .rhs = try p.parseExpr(), | 2095 | .rhs = try p.parseExpr(), |
| ... | @@ -2101,10 +2097,9 @@ fn parsePrimaryExpr(p: *Parse) !Node.Index { | ... | @@ -2101,10 +2097,9 @@ fn parsePrimaryExpr(p: *Parse) !Node.Index { |
| 2101 | }); | 2097 | }); |
| 2102 | }, | 2098 | }, |
| 2103 | .keyword_continue => { | 2099 | .keyword_continue => { |
| 2104 | p.tok_i += 1; | | |
| 2105 | return p.addNode(.{ | 2100 | return p.addNode(.{ |
| 2106 | .tag = .@"continue", | 2101 | .tag = .@"continue", |
| 2107 | .main_token = p.tok_i - 1, | 2102 | .main_token = p.nextToken(), |
| 2108 | .data = .{ | 2103 | .data = .{ |
| 2109 | .lhs = try p.parseBreakLabel(), | 2104 | .lhs = try p.parseBreakLabel(), |
| 2110 | .rhs = undefined, | 2105 | .rhs = undefined, |
| ... | @@ -2112,10 +2107,9 @@ fn parsePrimaryExpr(p: *Parse) !Node.Index { | ... | @@ -2112,10 +2107,9 @@ fn parsePrimaryExpr(p: *Parse) !Node.Index { |
| 2112 | }); | 2107 | }); |
| 2113 | }, | 2108 | }, |
| 2114 | .keyword_comptime => { | 2109 | .keyword_comptime => { |
| 2115 | p.tok_i += 1; | | |
| 2116 | return p.addNode(.{ | 2110 | return p.addNode(.{ |
| 2117 | .tag = .@"comptime", | 2111 | .tag = .@"comptime", |
| 2118 | .main_token = p.tok_i - 1, | 2112 | .main_token = p.nextToken(), |
| 2119 | .data = .{ | 2113 | .data = .{ |
| 2120 | .lhs = try p.expectExpr(), | 2114 | .lhs = try p.expectExpr(), |
| 2121 | .rhs = undefined, | 2115 | .rhs = undefined, |
| ... | @@ -2123,10 +2117,9 @@ fn parsePrimaryExpr(p: *Parse) !Node.Index { | ... | @@ -2123,10 +2117,9 @@ fn parsePrimaryExpr(p: *Parse) !Node.Index { |
| 2123 | }); | 2117 | }); |
| 2124 | }, | 2118 | }, |
| 2125 | .keyword_nosuspend => { | 2119 | .keyword_nosuspend => { |
| 2126 | p.tok_i += 1; | | |
| 2127 | return p.addNode(.{ | 2120 | return p.addNode(.{ |
| 2128 | .tag = .@"nosuspend", | 2121 | .tag = .@"nosuspend", |
| 2129 | .main_token = p.tok_i - 1, | 2122 | .main_token = p.nextToken(), |
| 2130 | .data = .{ | 2123 | .data = .{ |
| 2131 | .lhs = try p.expectExpr(), | 2124 | .lhs = try p.expectExpr(), |
| 2132 | .rhs = undefined, | 2125 | .rhs = undefined, |
| ... | @@ -2134,10 +2127,9 @@ fn parsePrimaryExpr(p: *Parse) !Node.Index { | ... | @@ -2134,10 +2127,9 @@ fn parsePrimaryExpr(p: *Parse) !Node.Index { |
| 2134 | }); | 2127 | }); |
| 2135 | }, | 2128 | }, |
| 2136 | .keyword_resume => { | 2129 | .keyword_resume => { |
| 2137 | p.tok_i += 1; | | |
| 2138 | return p.addNode(.{ | 2130 | return p.addNode(.{ |
| 2139 | .tag = .@"resume", | 2131 | .tag = .@"resume", |
| 2140 | .main_token = p.tok_i - 1, | 2132 | .main_token = p.nextToken(), |
| 2141 | .data = .{ | 2133 | .data = .{ |
| 2142 | .lhs = try p.expectExpr(), | 2134 | .lhs = try p.expectExpr(), |
| 2143 | .rhs = undefined, | 2135 | .rhs = undefined, |
| ... | @@ -2145,10 +2137,9 @@ fn parsePrimaryExpr(p: *Parse) !Node.Index { | ... | @@ -2145,10 +2137,9 @@ fn parsePrimaryExpr(p: *Parse) !Node.Index { |
| 2145 | }); | 2137 | }); |
| 2146 | }, | 2138 | }, |
| 2147 | .keyword_return => { | 2139 | .keyword_return => { |
| 2148 | p.tok_i += 1; | | |
| 2149 | return p.addNode(.{ | 2140 | return p.addNode(.{ |
| 2150 | .tag = .@"return", | 2141 | .tag = .@"return", |
| 2151 | .main_token = p.tok_i - 1, | 2142 | .main_token = p.nextToken(), |
| 2152 | .data = .{ | 2143 | .data = .{ |
| 2153 | .lhs = try p.parseExpr(), | 2144 | .lhs = try p.parseExpr(), |
| 2154 | .rhs = undefined, | 2145 | .rhs = undefined, |
| ... | @@ -2161,14 +2152,14 @@ fn parsePrimaryExpr(p: *Parse) !Node.Index { | ... | @@ -2161,14 +2152,14 @@ fn parsePrimaryExpr(p: *Parse) !Node.Index { |
| 2161 | .keyword_inline => { | 2152 | .keyword_inline => { |
| 2162 | p.tok_i += 3; | 2153 | p.tok_i += 3; |
| 2163 | switch (p.token_tags[p.tok_i]) { | 2154 | switch (p.token_tags[p.tok_i]) { |
| 2164 | .keyword_for => return p.parseForExpr(), | 2155 | .keyword_for => return p.parseFor(expectExpr), |
| 2165 | .keyword_while => return p.parseWhileExpr(), | 2156 | .keyword_while => return p.parseWhileExpr(), |
| 2166 | else => return p.fail(.expected_inlinable), | 2157 | else => return p.fail(.expected_inlinable), |
| 2167 | } | 2158 | } |
| 2168 | }, | 2159 | }, |
| 2169 | .keyword_for => { | 2160 | .keyword_for => { |
| 2170 | p.tok_i += 2; | 2161 | p.tok_i += 2; |
| 2171 | return p.parseForExpr(); | 2162 | return p.parseFor(expectExpr); |
| 2172 | }, | 2163 | }, |
| 2173 | .keyword_while => { | 2164 | .keyword_while => { |
| 2174 | p.tok_i += 2; | 2165 | p.tok_i += 2; |
| ... | @@ -2187,12 +2178,12 @@ fn parsePrimaryExpr(p: *Parse) !Node.Index { | ... | @@ -2187,12 +2178,12 @@ fn parsePrimaryExpr(p: *Parse) !Node.Index { |
| 2187 | .keyword_inline => { | 2178 | .keyword_inline => { |
| 2188 | p.tok_i += 1; | 2179 | p.tok_i += 1; |
| 2189 | switch (p.token_tags[p.tok_i]) { | 2180 | switch (p.token_tags[p.tok_i]) { |
| 2190 | .keyword_for => return p.parseForExpr(), | 2181 | .keyword_for => return p.parseFor(expectExpr), |
| 2191 | .keyword_while => return p.parseWhileExpr(), | 2182 | .keyword_while => return p.parseWhileExpr(), |
| 2192 | else => return p.fail(.expected_inlinable), | 2183 | else => return p.fail(.expected_inlinable), |
| 2193 | } | 2184 | } |
| 2194 | }, | 2185 | }, |
| 2195 | .keyword_for => return p.parseForExpr(), | 2186 | .keyword_for => return p.parseFor(expectExpr), |
| 2196 | .keyword_while => return p.parseWhileExpr(), | 2187 | .keyword_while => return p.parseWhileExpr(), |
| 2197 | .l_brace => return p.parseBlock(), | 2188 | .l_brace => return p.parseBlock(), |
| 2198 | else => return p.parseCurlySuffixExpr(), | 2189 | else => return p.parseCurlySuffixExpr(), |
| ... | @@ -2257,46 +2248,6 @@ fn parseBlock(p: *Parse) !Node.Index { | ... | @@ -2257,46 +2248,6 @@ fn parseBlock(p: *Parse) !Node.Index { |
| 2257 | } | 2248 | } |
| 2258 | } | 2249 | } |
| 2259 | | 2250 | |
| 2260 | /// ForExpr <- ForPrefix Expr (KEYWORD_else Expr)? | | |
| 2261 | fn parseForExpr(p: *Parse) !Node.Index { | | |
| 2262 | const for_token = p.eatToken(.keyword_for) orelse return null_node; | | |
| 2263 | | | |
| 2264 | const scratch_top = p.scratch.items.len; | | |
| 2265 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | | |
| 2266 | const inputs = try p.forPrefix(); | | |
| 2267 | | | |
| 2268 | const then_expr = try p.expectExpr(); | | |
| 2269 | var has_else = false; | | |
| 2270 | if (p.eatToken(.keyword_else)) |_| { | | |
| 2271 | try p.scratch.append(p.gpa, then_expr); | | |
| 2272 | const else_expr = try p.expectExpr(); | | |
| 2273 | try p.scratch.append(p.gpa, else_expr); | | |
| 2274 | has_else = true; | | |
| 2275 | } else if (inputs == 1) { | | |
| 2276 | return p.addNode(.{ | | |
| 2277 | .tag = .for_simple, | | |
| 2278 | .main_token = for_token, | | |
| 2279 | .data = .{ | | |
| 2280 | .lhs = p.scratch.items[scratch_top], | | |
| 2281 | .rhs = then_expr, | | |
| 2282 | }, | | |
| 2283 | }); | | |
| 2284 | } else { | | |
| 2285 | try p.scratch.append(p.gpa, then_expr); | | |
| 2286 | } | | |
| 2287 | return p.addNode(.{ | | |
| 2288 | .tag = .@"for", | | |
| 2289 | .main_token = for_token, | | |
| 2290 | .data = .{ | | |
| 2291 | .lhs = (try p.listToSpan(p.scratch.items[scratch_top..])).start, | | |
| 2292 | .rhs = @as(u32, @bitCast(Node.For{ | | |
| 2293 | .inputs = @as(u31, @intCast(inputs)), | | |
| 2294 | .has_else = has_else, | | |
| 2295 | })), | | |
| 2296 | }, | | |
| 2297 | }); | | |
| 2298 | } | | |
| 2299 | | | |
| 2300 | /// ForPrefix <- KEYWORD_for LPAREN ForInput (COMMA ForInput)* COMMA? RPAREN ForPayload | 2251 | /// ForPrefix <- KEYWORD_for LPAREN ForInput (COMMA ForInput)* COMMA? RPAREN ForPayload |
| 2301 | /// | 2252 | /// |
| 2302 | /// ForInput <- Expr (DOT2 Expr?)? | 2253 | /// ForInput <- Expr (DOT2 Expr?)? |
| ... | @@ -2793,14 +2744,14 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2793,14 +2744,14 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2793 | .keyword_inline => { | 2744 | .keyword_inline => { |
| 2794 | p.tok_i += 3; | 2745 | p.tok_i += 3; |
| 2795 | switch (p.token_tags[p.tok_i]) { | 2746 | switch (p.token_tags[p.tok_i]) { |
| 2796 | .keyword_for => return p.parseForTypeExpr(), | 2747 | .keyword_for => return p.parseFor(expectTypeExpr), |
| 2797 | .keyword_while => return p.parseWhileTypeExpr(), | 2748 | .keyword_while => return p.parseWhileTypeExpr(), |
| 2798 | else => return p.fail(.expected_inlinable), | 2749 | else => return p.fail(.expected_inlinable), |
| 2799 | } | 2750 | } |
| 2800 | }, | 2751 | }, |
| 2801 | .keyword_for => { | 2752 | .keyword_for => { |
| 2802 | p.tok_i += 2; | 2753 | p.tok_i += 2; |
| 2803 | return p.parseForTypeExpr(); | 2754 | return p.parseFor(expectTypeExpr); |
| 2804 | }, | 2755 | }, |
| 2805 | .keyword_while => { | 2756 | .keyword_while => { |
| 2806 | p.tok_i += 2; | 2757 | p.tok_i += 2; |
| ... | @@ -2831,12 +2782,12 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { | ... | @@ -2831,12 +2782,12 @@ fn parsePrimaryTypeExpr(p: *Parse) !Node.Index { |
| 2831 | .keyword_inline => { | 2782 | .keyword_inline => { |
| 2832 | p.tok_i += 1; | 2783 | p.tok_i += 1; |
| 2833 | switch (p.token_tags[p.tok_i]) { | 2784 | switch (p.token_tags[p.tok_i]) { |
| 2834 | .keyword_for => return p.parseForTypeExpr(), | 2785 | .keyword_for => return p.parseFor(expectTypeExpr), |
| 2835 | .keyword_while => return p.parseWhileTypeExpr(), | 2786 | .keyword_while => return p.parseWhileTypeExpr(), |
| 2836 | else => return p.fail(.expected_inlinable), | 2787 | else => return p.fail(.expected_inlinable), |
| 2837 | } | 2788 | } |
| 2838 | }, | 2789 | }, |
| 2839 | .keyword_for => return p.parseForTypeExpr(), | 2790 | .keyword_for => return p.parseFor(expectTypeExpr), |
| 2840 | .keyword_while => return p.parseWhileTypeExpr(), | 2791 | .keyword_while => return p.parseWhileTypeExpr(), |
| 2841 | .period => switch (p.token_tags[p.tok_i + 1]) { | 2792 | .period => switch (p.token_tags[p.tok_i + 1]) { |
| 2842 | .identifier => return p.addNode(.{ | 2793 | .identifier => return p.addNode(.{ |
| ... | @@ -3029,46 +2980,6 @@ fn expectPrimaryTypeExpr(p: *Parse) !Node.Index { | ... | @@ -3029,46 +2980,6 @@ fn expectPrimaryTypeExpr(p: *Parse) !Node.Index { |
| 3029 | return node; | 2980 | return node; |
| 3030 | } | 2981 | } |
| 3031 | | 2982 | |
| 3032 | /// ForTypeExpr <- ForPrefix TypeExpr (KEYWORD_else TypeExpr)? | | |
| 3033 | fn parseForTypeExpr(p: *Parse) !Node.Index { | | |
| 3034 | const for_token = p.eatToken(.keyword_for) orelse return null_node; | | |
| 3035 | | | |
| 3036 | const scratch_top = p.scratch.items.len; | | |
| 3037 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | | |
| 3038 | const inputs = try p.forPrefix(); | | |
| 3039 | | | |
| 3040 | const then_expr = try p.expectTypeExpr(); | | |
| 3041 | var has_else = false; | | |
| 3042 | if (p.eatToken(.keyword_else)) |_| { | | |
| 3043 | try p.scratch.append(p.gpa, then_expr); | | |
| 3044 | const else_expr = try p.expectTypeExpr(); | | |
| 3045 | try p.scratch.append(p.gpa, else_expr); | | |
| 3046 | has_else = true; | | |
| 3047 | } else if (inputs == 1) { | | |
| 3048 | return p.addNode(.{ | | |
| 3049 | .tag = .for_simple, | | |
| 3050 | .main_token = for_token, | | |
| 3051 | .data = .{ | | |
| 3052 | .lhs = p.scratch.items[scratch_top], | | |
| 3053 | .rhs = then_expr, | | |
| 3054 | }, | | |
| 3055 | }); | | |
| 3056 | } else { | | |
| 3057 | try p.scratch.append(p.gpa, then_expr); | | |
| 3058 | } | | |
| 3059 | return p.addNode(.{ | | |
| 3060 | .tag = .@"for", | | |
| 3061 | .main_token = for_token, | | |
| 3062 | .data = .{ | | |
| 3063 | .lhs = (try p.listToSpan(p.scratch.items[scratch_top..])).start, | | |
| 3064 | .rhs = @as(u32, @bitCast(Node.For{ | | |
| 3065 | .inputs = @as(u31, @intCast(inputs)), | | |
| 3066 | .has_else = has_else, | | |
| 3067 | })), | | |
| 3068 | }, | | |
| 3069 | }); | | |
| 3070 | } | | |
| 3071 | | | |
| 3072 | /// WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr? | 2983 | /// WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr? |
| 3073 | /// | 2984 | /// |
| 3074 | /// WhileTypeExpr <- WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)? | 2985 | /// WhileTypeExpr <- WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)? |
| ... | @@ -3279,7 +3190,7 @@ fn parseAsmInputItem(p: *Parse) !Node.Index { | ... | @@ -3279,7 +3190,7 @@ fn parseAsmInputItem(p: *Parse) !Node.Index { |
| 3279 | | 3190 | |
| 3280 | /// BreakLabel <- COLON IDENTIFIER | 3191 | /// BreakLabel <- COLON IDENTIFIER |
| 3281 | fn parseBreakLabel(p: *Parse) !TokenIndex { | 3192 | fn parseBreakLabel(p: *Parse) !TokenIndex { |
| 3282 | _ = p.eatToken(.colon) orelse return @as(TokenIndex, 0); | 3193 | _ = p.eatToken(.colon) orelse return null_node; |
| 3283 | return p.expectToken(.identifier); | 3194 | return p.expectToken(.identifier); |
| 3284 | } | 3195 | } |
| 3285 | | 3196 | |
| ... | @@ -3397,7 +3308,7 @@ fn expectParamDecl(p: *Parse) !Node.Index { | ... | @@ -3397,7 +3308,7 @@ fn expectParamDecl(p: *Parse) !Node.Index { |
| 3397 | | 3308 | |
| 3398 | /// Payload <- PIPE IDENTIFIER PIPE | 3309 | /// Payload <- PIPE IDENTIFIER PIPE |
| 3399 | fn parsePayload(p: *Parse) !TokenIndex { | 3310 | fn parsePayload(p: *Parse) !TokenIndex { |
| 3400 | _ = p.eatToken(.pipe) orelse return @as(TokenIndex, 0); | 3311 | _ = p.eatToken(.pipe) orelse return null_node; |
| 3401 | const identifier = try p.expectToken(.identifier); | 3312 | const identifier = try p.expectToken(.identifier); |
| 3402 | _ = try p.expectToken(.pipe); | 3313 | _ = try p.expectToken(.pipe); |
| 3403 | return identifier; | 3314 | return identifier; |
| ... | @@ -3405,7 +3316,7 @@ fn parsePayload(p: *Parse) !TokenIndex { | ... | @@ -3405,7 +3316,7 @@ fn parsePayload(p: *Parse) !TokenIndex { |
| 3405 | | 3316 | |
| 3406 | /// PtrPayload <- PIPE ASTERISK? IDENTIFIER PIPE | 3317 | /// PtrPayload <- PIPE ASTERISK? IDENTIFIER PIPE |
| 3407 | fn parsePtrPayload(p: *Parse) !TokenIndex { | 3318 | fn parsePtrPayload(p: *Parse) !TokenIndex { |
| 3408 | _ = p.eatToken(.pipe) orelse return @as(TokenIndex, 0); | 3319 | _ = p.eatToken(.pipe) orelse return null_node; |
| 3409 | _ = p.eatToken(.asterisk); | 3320 | _ = p.eatToken(.asterisk); |
| 3410 | const identifier = try p.expectToken(.identifier); | 3321 | const identifier = try p.expectToken(.identifier); |
| 3411 | _ = try p.expectToken(.pipe); | 3322 | _ = try p.expectToken(.pipe); |
| ... | @@ -3416,7 +3327,7 @@ fn parsePtrPayload(p: *Parse) !TokenIndex { | ... | @@ -3416,7 +3327,7 @@ fn parsePtrPayload(p: *Parse) !TokenIndex { |
| 3416 | /// | 3327 | /// |
| 3417 | /// PtrIndexPayload <- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE | 3328 | /// PtrIndexPayload <- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE |
| 3418 | fn parsePtrIndexPayload(p: *Parse) !TokenIndex { | 3329 | fn parsePtrIndexPayload(p: *Parse) !TokenIndex { |
| 3419 | _ = p.eatToken(.pipe) orelse return @as(TokenIndex, 0); | 3330 | _ = p.eatToken(.pipe) orelse return null_node; |
| 3420 | _ = p.eatToken(.asterisk); | 3331 | _ = p.eatToken(.asterisk); |
| 3421 | const identifier = try p.expectToken(.identifier); | 3332 | const identifier = try p.expectToken(.identifier); |
| 3422 | if (p.eatToken(.comma) != null) { | 3333 | if (p.eatToken(.comma) != null) { |
| ... | @@ -3925,8 +3836,7 @@ fn parseParamDeclList(p: *Parse) !SmallSpan { | ... | @@ -3925,8 +3836,7 @@ fn parseParamDeclList(p: *Parse) !SmallSpan { |
| 3925 | /// ExprList <- (Expr COMMA)* Expr? | 3836 | /// ExprList <- (Expr COMMA)* Expr? |
| 3926 | fn parseBuiltinCall(p: *Parse) !Node.Index { | 3837 | fn parseBuiltinCall(p: *Parse) !Node.Index { |
| 3927 | const builtin_token = p.assertToken(.builtin); | 3838 | const builtin_token = p.assertToken(.builtin); |
| 3928 | if (p.token_tags[p.nextToken()] != .l_paren) { | 3839 | _ = p.eatToken(.l_paren) orelse { |
| 3929 | p.tok_i -= 1; | | |
| 3930 | try p.warn(.expected_param_list); | 3840 | try p.warn(.expected_param_list); |
| 3931 | // Pretend this was an identifier so we can continue parsing. | 3841 | // Pretend this was an identifier so we can continue parsing. |
| 3932 | return p.addNode(.{ | 3842 | return p.addNode(.{ |
| ... | @@ -3937,7 +3847,7 @@ fn parseBuiltinCall(p: *Parse) !Node.Index { | ... | @@ -3937,7 +3847,7 @@ fn parseBuiltinCall(p: *Parse) !Node.Index { |
| 3937 | .rhs = undefined, | 3847 | .rhs = undefined, |
| 3938 | }, | 3848 | }, |
| 3939 | }); | 3849 | }); |
| 3940 | } | 3850 | }; |
| 3941 | const scratch_top = p.scratch.items.len; | 3851 | const scratch_top = p.scratch.items.len; |
| 3942 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 3852 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 3943 | while (true) { | 3853 | while (true) { |
| ... | @@ -4031,8 +3941,50 @@ fn parseIf(p: *Parse, comptime bodyParseFn: fn (p: *Parse) Error!Node.Index) !No | ... | @@ -4031,8 +3941,50 @@ fn parseIf(p: *Parse, comptime bodyParseFn: fn (p: *Parse) Error!Node.Index) !No |
| 4031 | }); | 3941 | }); |
| 4032 | } | 3942 | } |
| 4033 | | 3943 | |
| | 3944 | /// ForExpr <- ForPrefix Expr (KEYWORD_else Expr)? |
| | 3945 | /// |
| | 3946 | /// ForTypeExpr <- ForPrefix TypeExpr (KEYWORD_else TypeExpr)? |
| | 3947 | fn parseFor(p: *Parse, comptime bodyParseFn: fn (p: *Parse) Error!Node.Index) !Node.Index { |
| | 3948 | const for_token = p.eatToken(.keyword_for) orelse return null_node; |
| | 3949 | |
| | 3950 | const scratch_top = p.scratch.items.len; |
| | 3951 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| | 3952 | const inputs = try p.forPrefix(); |
| | 3953 | |
| | 3954 | const then_expr = try bodyParseFn(p); |
| | 3955 | var has_else = false; |
| | 3956 | if (p.eatToken(.keyword_else)) |_| { |
| | 3957 | try p.scratch.append(p.gpa, then_expr); |
| | 3958 | const else_expr = try bodyParseFn(p); |
| | 3959 | try p.scratch.append(p.gpa, else_expr); |
| | 3960 | has_else = true; |
| | 3961 | } else if (inputs == 1) { |
| | 3962 | return p.addNode(.{ |
| | 3963 | .tag = .for_simple, |
| | 3964 | .main_token = for_token, |
| | 3965 | .data = .{ |
| | 3966 | .lhs = p.scratch.items[scratch_top], |
| | 3967 | .rhs = then_expr, |
| | 3968 | }, |
| | 3969 | }); |
| | 3970 | } else { |
| | 3971 | try p.scratch.append(p.gpa, then_expr); |
| | 3972 | } |
| | 3973 | return p.addNode(.{ |
| | 3974 | .tag = .@"for", |
| | 3975 | .main_token = for_token, |
| | 3976 | .data = .{ |
| | 3977 | .lhs = (try p.listToSpan(p.scratch.items[scratch_top..])).start, |
| | 3978 | .rhs = @as(u32, @bitCast(Node.For{ |
| | 3979 | .inputs = @as(u31, @intCast(inputs)), |
| | 3980 | .has_else = has_else, |
| | 3981 | })), |
| | 3982 | }, |
| | 3983 | }); |
| | 3984 | } |
| | 3985 | |
| 4034 | /// Skips over doc comment tokens. Returns the first one, if any. | 3986 | /// Skips over doc comment tokens. Returns the first one, if any. |
| 4035 | fn eatDocComments(p: *Parse) !?TokenIndex { | 3987 | fn eatDocComments(p: *Parse) Allocator.Error!?TokenIndex { |
| 4036 | if (p.eatToken(.doc_comment)) |tok| { | 3988 | if (p.eatToken(.doc_comment)) |tok| { |
| 4037 | var first_line = tok; | 3989 | var first_line = tok; |
| 4038 | if (tok > 0 and tokensOnSameLine(p, tok - 1, tok)) { | 3990 | if (tok > 0 and tokensOnSameLine(p, tok - 1, tok)) { |