| ... | @@ -1850,65 +1850,54 @@ const Parser = struct { | ... | @@ -1850,65 +1850,54 @@ const Parser = struct { |
| 1850 | /// Block <- LBRACE Statement* RBRACE | 1850 | /// Block <- LBRACE Statement* RBRACE |
| 1851 | fn parseBlock(p: *Parser) !Node.Index { | 1851 | fn parseBlock(p: *Parser) !Node.Index { |
| 1852 | const lbrace = p.eatToken(.l_brace) orelse return null_node; | 1852 | const lbrace = p.eatToken(.l_brace) orelse return null_node; |
| 1853 | | 1853 | const scratch_top = p.scratch.items.len; |
| 1854 | if (p.eatToken(.r_brace)) |_| { | 1854 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 1855 | return p.addNode(.{ | 1855 | while (true) { |
| | 1856 | if (p.token_tags[p.tok_i] == .r_brace) break; |
| | 1857 | const statement = try p.expectStatementRecoverable(); |
| | 1858 | if (statement == 0) break; |
| | 1859 | try p.scratch.append(p.gpa, statement); |
| | 1860 | } |
| | 1861 | _ = try p.expectToken(.r_brace); |
| | 1862 | const semicolon = (p.token_tags[p.tok_i - 2] == .semicolon); |
| | 1863 | const statements = p.scratch.items[scratch_top..]; |
| | 1864 | switch (statements.len) { |
| | 1865 | 0 => return p.addNode(.{ |
| 1856 | .tag = .block_two, | 1866 | .tag = .block_two, |
| 1857 | .main_token = lbrace, | 1867 | .main_token = lbrace, |
| 1858 | .data = .{ | 1868 | .data = .{ |
| 1859 | .lhs = 0, | 1869 | .lhs = 0, |
| 1860 | .rhs = 0, | 1870 | .rhs = 0, |
| 1861 | }, | 1871 | }, |
| 1862 | }); | 1872 | }), |
| 1863 | } | 1873 | 1 => return p.addNode(.{ |
| 1864 | | | |
| 1865 | const stmt_one = try p.expectStatementRecoverable(); | | |
| 1866 | if (p.eatToken(.r_brace)) |_| { | | |
| 1867 | const semicolon = p.token_tags[p.tok_i - 2] == .semicolon; | | |
| 1868 | return p.addNode(.{ | | |
| 1869 | .tag = if (semicolon) .block_two_semicolon else .block_two, | 1874 | .tag = if (semicolon) .block_two_semicolon else .block_two, |
| 1870 | .main_token = lbrace, | 1875 | .main_token = lbrace, |
| 1871 | .data = .{ | 1876 | .data = .{ |
| 1872 | .lhs = stmt_one, | 1877 | .lhs = statements[0], |
| 1873 | .rhs = 0, | 1878 | .rhs = 0, |
| 1874 | }, | 1879 | }, |
| 1875 | }); | 1880 | }), |
| 1876 | } | 1881 | 2 => return p.addNode(.{ |
| 1877 | const stmt_two = try p.expectStatementRecoverable(); | | |
| 1878 | if (p.eatToken(.r_brace)) |_| { | | |
| 1879 | const semicolon = p.token_tags[p.tok_i - 2] == .semicolon; | | |
| 1880 | return p.addNode(.{ | | |
| 1881 | .tag = if (semicolon) .block_two_semicolon else .block_two, | 1882 | .tag = if (semicolon) .block_two_semicolon else .block_two, |
| 1882 | .main_token = lbrace, | 1883 | .main_token = lbrace, |
| 1883 | .data = .{ | 1884 | .data = .{ |
| 1884 | .lhs = stmt_one, | 1885 | .lhs = statements[0], |
| 1885 | .rhs = stmt_two, | 1886 | .rhs = statements[1], |
| 1886 | }, | 1887 | }, |
| 1887 | }); | 1888 | }), |
| 1888 | } | 1889 | else => { |
| 1889 | | 1890 | const span = try p.listToSpan(statements); |
| 1890 | const scratch_top = p.scratch.items.len; | 1891 | return p.addNode(.{ |
| 1891 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 1892 | .tag = if (semicolon) .block_semicolon else .block, |
| 1892 | | 1893 | .main_token = lbrace, |
| 1893 | try p.scratch.appendSlice(p.gpa, &.{ stmt_one, stmt_two }); | 1894 | .data = .{ |
| 1894 | | 1895 | .lhs = span.start, |
| 1895 | while (true) { | 1896 | .rhs = span.end, |
| 1896 | const statement = try p.expectStatementRecoverable(); | 1897 | }, |
| 1897 | if (statement == 0) break; | 1898 | }); |
| 1898 | try p.scratch.append(p.gpa, statement); | | |
| 1899 | if (p.token_tags[p.tok_i] == .r_brace) break; | | |
| 1900 | } | | |
| 1901 | _ = try p.expectToken(.r_brace); | | |
| 1902 | const semicolon = p.token_tags[p.tok_i - 2] == .semicolon; | | |
| 1903 | const statements_span = try p.listToSpan(p.scratch.items[scratch_top..]); | | |
| 1904 | return p.addNode(.{ | | |
| 1905 | .tag = if (semicolon) .block_semicolon else .block, | | |
| 1906 | .main_token = lbrace, | | |
| 1907 | .data = .{ | | |
| 1908 | .lhs = statements_span.start, | | |
| 1909 | .rhs = statements_span.end, | | |
| 1910 | }, | 1899 | }, |
| 1911 | }); | 1900 | } |
| 1912 | } | 1901 | } |
| 1913 | | 1902 | |
| 1914 | /// ForPrefix <- KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload | 1903 | /// ForPrefix <- KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload |
| ... | @@ -2010,114 +1999,86 @@ const Parser = struct { | ... | @@ -2010,114 +1999,86 @@ const Parser = struct { |
| 2010 | // If there are 0 or 1 items, we can use ArrayInitOne/StructInitOne; | 1999 | // If there are 0 or 1 items, we can use ArrayInitOne/StructInitOne; |
| 2011 | // otherwise we use the full ArrayInit/StructInit. | 2000 | // otherwise we use the full ArrayInit/StructInit. |
| 2012 | | 2001 | |
| 2013 | if (p.eatToken(.r_brace)) |_| { | 2002 | const scratch_top = p.scratch.items.len; |
| 2014 | return p.addNode(.{ | 2003 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2015 | .tag = .struct_init_one, | | |
| 2016 | .main_token = lbrace, | | |
| 2017 | .data = .{ | | |
| 2018 | .lhs = lhs, | | |
| 2019 | .rhs = 0, | | |
| 2020 | }, | | |
| 2021 | }); | | |
| 2022 | } | | |
| 2023 | const field_init = try p.parseFieldInit(); | 2004 | const field_init = try p.parseFieldInit(); |
| 2024 | if (field_init != 0) { | 2005 | if (field_init != 0) { |
| 2025 | const comma_one = p.eatToken(.comma); | | |
| 2026 | if (p.eatToken(.r_brace)) |_| { | | |
| 2027 | return p.addNode(.{ | | |
| 2028 | .tag = if (comma_one != null) .struct_init_one_comma else .struct_init_one, | | |
| 2029 | .main_token = lbrace, | | |
| 2030 | .data = .{ | | |
| 2031 | .lhs = lhs, | | |
| 2032 | .rhs = field_init, | | |
| 2033 | }, | | |
| 2034 | }); | | |
| 2035 | } | | |
| 2036 | | | |
| 2037 | const scratch_top = p.scratch.items.len; | | |
| 2038 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | | |
| 2039 | | | |
| 2040 | try p.scratch.append(p.gpa, field_init); | 2006 | try p.scratch.append(p.gpa, field_init); |
| 2041 | | | |
| 2042 | while (true) { | 2007 | while (true) { |
| | 2008 | switch (p.token_tags[p.tok_i]) { |
| | 2009 | .comma => p.tok_i += 1, |
| | 2010 | .r_brace => { p.tok_i += 1; break; }, |
| | 2011 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), |
| | 2012 | // Likely just a missing comma; give error but continue parsing. |
| | 2013 | else => try p.warnExpected(.comma), |
| | 2014 | } |
| | 2015 | if (p.eatToken(.r_brace)) |_| break; |
| 2043 | const next = try p.expectFieldInit(); | 2016 | const next = try p.expectFieldInit(); |
| 2044 | try p.scratch.append(p.gpa, next); | 2017 | try p.scratch.append(p.gpa, next); |
| 2045 | | 2018 | } |
| 2046 | switch (p.token_tags[p.nextToken()]) { | 2019 | const comma = (p.token_tags[p.tok_i - 2] == .comma); |
| 2047 | .comma => { | 2020 | const inits = p.scratch.items[scratch_top..]; |
| 2048 | if (p.eatToken(.r_brace)) |_| break; | 2021 | switch (inits.len) { |
| 2049 | continue; | 2022 | 0 => unreachable, |
| 2050 | }, | 2023 | 1 => return p.addNode(.{ |
| 2051 | .r_brace => break, | 2024 | .tag = if (comma) .struct_init_one_comma else .struct_init_one, |
| 2052 | .colon, .r_paren, .r_bracket => { | 2025 | .main_token = lbrace, |
| 2053 | p.tok_i -= 1; | 2026 | .data = .{ |
| 2054 | return p.failExpected(.r_brace); | 2027 | .lhs = lhs, |
| | 2028 | .rhs = inits[0], |
| 2055 | }, | 2029 | }, |
| 2056 | else => { | 2030 | }), |
| 2057 | // This is likely just a missing comma; | 2031 | else => return p.addNode(.{ |
| 2058 | // give an error but continue parsing this list. | 2032 | .tag = if (comma) .struct_init_comma else .struct_init, |
| 2059 | p.tok_i -= 1; | 2033 | .main_token = lbrace, |
| 2060 | try p.warnExpected(.comma); | 2034 | .data = .{ |
| | 2035 | .lhs = lhs, |
| | 2036 | .rhs = try p.addExtra(try p.listToSpan(inits)), |
| 2061 | }, | 2037 | }, |
| 2062 | } | 2038 | }), |
| 2063 | } | 2039 | } |
| 2064 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); | 2040 | } |
| 2065 | return p.addNode(.{ | 2041 | |
| 2066 | .tag = if (p.token_tags[p.tok_i - 2] == .comma) .struct_init_comma else .struct_init, | 2042 | while (true) { |
| | 2043 | if (p.eatToken(.r_brace)) |_| break; |
| | 2044 | const elem_init = try p.expectExpr(); |
| | 2045 | try p.scratch.append(p.gpa, elem_init); |
| | 2046 | switch (p.token_tags[p.tok_i]) { |
| | 2047 | .comma => p.tok_i += 1, |
| | 2048 | .r_brace => { p.tok_i += 1; break; }, |
| | 2049 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), |
| | 2050 | // Likely just a missing comma; give error but continue parsing. |
| | 2051 | else => try p.warnExpected(.comma), |
| | 2052 | } |
| | 2053 | } |
| | 2054 | const comma = (p.token_tags[p.tok_i - 2] == .comma); |
| | 2055 | const inits = p.scratch.items[scratch_top..]; |
| | 2056 | switch (inits.len) { |
| | 2057 | 0 => return p.addNode(.{ |
| | 2058 | .tag = .struct_init_one, |
| 2067 | .main_token = lbrace, | 2059 | .main_token = lbrace, |
| 2068 | .data = .{ | 2060 | .data = .{ |
| 2069 | .lhs = lhs, | 2061 | .lhs = lhs, |
| 2070 | .rhs = try p.addExtra(Node.SubRange{ | 2062 | .rhs = 0, |
| 2071 | .start = span.start, | | |
| 2072 | .end = span.end, | | |
| 2073 | }), | | |
| 2074 | }, | 2063 | }, |
| 2075 | }); | 2064 | }), |
| 2076 | } | 2065 | 1 => return p.addNode(.{ |
| 2077 | | 2066 | .tag = if (comma) .array_init_one_comma else .array_init_one, |
| 2078 | const elem_init = try p.expectExpr(); | | |
| 2079 | const comma_one = p.eatToken(.comma); | | |
| 2080 | if (p.eatToken(.r_brace)) |_| { | | |
| 2081 | return p.addNode(.{ | | |
| 2082 | .tag = if (comma_one != null) .array_init_one_comma else .array_init_one, | | |
| 2083 | .main_token = lbrace, | 2067 | .main_token = lbrace, |
| 2084 | .data = .{ | 2068 | .data = .{ |
| 2085 | .lhs = lhs, | 2069 | .lhs = lhs, |
| 2086 | .rhs = elem_init, | 2070 | .rhs = inits[0], |
| 2087 | }, | 2071 | }, |
| 2088 | }); | 2072 | }), |
| 2089 | } | 2073 | else => return p.addNode(.{ |
| 2090 | if (comma_one == null) { | 2074 | .tag = if (comma) .array_init_comma else .array_init, |
| 2091 | try p.warnExpected(.comma); | 2075 | .main_token = lbrace, |
| 2092 | } | 2076 | .data = .{ |
| 2093 | | 2077 | .lhs = lhs, |
| 2094 | const scratch_top = p.scratch.items.len; | 2078 | .rhs = try p.addExtra(try p.listToSpan(inits)), |
| 2095 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | 2079 | }, |
| 2096 | | 2080 | }), |
| 2097 | try p.scratch.append(p.gpa, elem_init); | | |
| 2098 | | | |
| 2099 | var trailing_comma = true; | | |
| 2100 | var next = try p.parseExpr(); | | |
| 2101 | while (next != 0) : (next = try p.parseExpr()) { | | |
| 2102 | try p.scratch.append(p.gpa, next); | | |
| 2103 | if (p.eatToken(.comma) == null) { | | |
| 2104 | trailing_comma = false; | | |
| 2105 | break; | | |
| 2106 | } | | |
| 2107 | } | 2081 | } |
| 2108 | _ = try p.expectToken(.r_brace); | | |
| 2109 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); | | |
| 2110 | return p.addNode(.{ | | |
| 2111 | .tag = if (trailing_comma) .array_init_comma else .array_init, | | |
| 2112 | .main_token = lbrace, | | |
| 2113 | .data = .{ | | |
| 2114 | .lhs = lhs, | | |
| 2115 | .rhs = try p.addExtra(Node.SubRange{ | | |
| 2116 | .start = span.start, | | |
| 2117 | .end = span.end, | | |
| 2118 | }), | | |
| 2119 | }, | | |
| 2120 | }); | | |
| 2121 | } | 2082 | } |
| 2122 | | 2083 | |
| 2123 | /// ErrorUnionExpr <- SuffixExpr (EXCLAMATIONMARK TypeExpr)? | 2084 | /// ErrorUnionExpr <- SuffixExpr (EXCLAMATIONMARK TypeExpr)? |
| ... | @@ -2143,184 +2104,109 @@ const Parser = struct { | ... | @@ -2143,184 +2104,109 @@ const Parser = struct { |
| 2143 | fn parseSuffixExpr(p: *Parser) !Node.Index { | 2104 | fn parseSuffixExpr(p: *Parser) !Node.Index { |
| 2144 | if (p.eatToken(.keyword_async)) |async_token| { | 2105 | if (p.eatToken(.keyword_async)) |async_token| { |
| 2145 | var res = try p.expectPrimaryTypeExpr(); | 2106 | var res = try p.expectPrimaryTypeExpr(); |
| 2146 | | | |
| 2147 | while (true) { | 2107 | while (true) { |
| 2148 | const node = try p.parseSuffixOp(res); | 2108 | const node = try p.parseSuffixOp(res); |
| 2149 | if (node == 0) break; | 2109 | if (node == 0) break; |
| 2150 | res = node; | 2110 | res = node; |
| 2151 | } | 2111 | } |
| 2152 | const lparen = p.nextToken(); | 2112 | const lparen = p.eatToken(.l_paren) orelse { |
| 2153 | if (p.token_tags[lparen] != .l_paren) { | | |
| 2154 | p.tok_i -= 1; | | |
| 2155 | try p.warn(.expected_param_list); | 2113 | try p.warn(.expected_param_list); |
| 2156 | return res; | 2114 | return res; |
| | 2115 | }; |
| | 2116 | const scratch_top = p.scratch.items.len; |
| | 2117 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| | 2118 | while (true) { |
| | 2119 | if (p.eatToken(.r_paren)) |_| break; |
| | 2120 | const param = try p.expectExpr(); |
| | 2121 | try p.scratch.append(p.gpa, param); |
| | 2122 | switch (p.token_tags[p.tok_i]) { |
| | 2123 | .comma => p.tok_i += 1, |
| | 2124 | .r_paren => { p.tok_i += 1; break; }, |
| | 2125 | .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren), |
| | 2126 | // Likely just a missing comma; give error but continue parsing. |
| | 2127 | else => try p.warnExpected(.comma), |
| | 2128 | } |
| 2157 | } | 2129 | } |
| 2158 | if (p.eatToken(.r_paren)) |_| { | 2130 | const comma = (p.token_tags[p.tok_i - 2] == .comma); |
| 2159 | return p.addNode(.{ | 2131 | const params = p.scratch.items[scratch_top..]; |
| 2160 | .tag = .async_call_one, | 2132 | switch(params.len) { |
| | 2133 | 0 => return p.addNode(.{ |
| | 2134 | .tag = if (comma) .async_call_one_comma else .async_call_one, |
| 2161 | .main_token = lparen, | 2135 | .main_token = lparen, |
| 2162 | .data = .{ | 2136 | .data = .{ |
| 2163 | .lhs = res, | 2137 | .lhs = res, |
| 2164 | .rhs = 0, | 2138 | .rhs = 0, |
| 2165 | }, | 2139 | }, |
| 2166 | }); | 2140 | }), |
| 2167 | } | 2141 | 1 => return p.addNode(.{ |
| 2168 | const param_one = try p.expectExpr(); | 2142 | .tag = if (comma) .async_call_one_comma else .async_call_one, |
| 2169 | const comma_one = p.eatToken(.comma); | | |
| 2170 | if (p.eatToken(.r_paren)) |_| { | | |
| 2171 | return p.addNode(.{ | | |
| 2172 | .tag = if (comma_one == null) .async_call_one else .async_call_one_comma, | | |
| 2173 | .main_token = lparen, | 2143 | .main_token = lparen, |
| 2174 | .data = .{ | 2144 | .data = .{ |
| 2175 | .lhs = res, | 2145 | .lhs = res, |
| 2176 | .rhs = param_one, | 2146 | .rhs = params[0], |
| 2177 | }, | | |
| 2178 | }); | | |
| 2179 | } | | |
| 2180 | if (comma_one == null) { | | |
| 2181 | try p.warnExpected(.comma); | | |
| 2182 | } | | |
| 2183 | | | |
| 2184 | const scratch_top = p.scratch.items.len; | | |
| 2185 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | | |
| 2186 | | | |
| 2187 | try p.scratch.append(p.gpa, param_one); | | |
| 2188 | | | |
| 2189 | while (true) { | | |
| 2190 | const next = try p.expectExpr(); | | |
| 2191 | try p.scratch.append(p.gpa, next); | | |
| 2192 | switch (p.token_tags[p.nextToken()]) { | | |
| 2193 | .comma => { | | |
| 2194 | if (p.eatToken(.r_paren)) |_| { | | |
| 2195 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); | | |
| 2196 | return p.addNode(.{ | | |
| 2197 | .tag = .async_call_comma, | | |
| 2198 | .main_token = lparen, | | |
| 2199 | .data = .{ | | |
| 2200 | .lhs = res, | | |
| 2201 | .rhs = try p.addExtra(Node.SubRange{ | | |
| 2202 | .start = span.start, | | |
| 2203 | .end = span.end, | | |
| 2204 | }), | | |
| 2205 | }, | | |
| 2206 | }); | | |
| 2207 | } else { | | |
| 2208 | continue; | | |
| 2209 | } | | |
| 2210 | }, | | |
| 2211 | .r_paren => { | | |
| 2212 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); | | |
| 2213 | return p.addNode(.{ | | |
| 2214 | .tag = .async_call, | | |
| 2215 | .main_token = lparen, | | |
| 2216 | .data = .{ | | |
| 2217 | .lhs = res, | | |
| 2218 | .rhs = try p.addExtra(Node.SubRange{ | | |
| 2219 | .start = span.start, | | |
| 2220 | .end = span.end, | | |
| 2221 | }), | | |
| 2222 | }, | | |
| 2223 | }); | | |
| 2224 | }, | 2147 | }, |
| 2225 | .colon, .r_brace, .r_bracket => { | 2148 | }), |
| 2226 | p.tok_i -= 1; | 2149 | else => return p.addNode(.{ |
| 2227 | return p.failExpected(.r_paren); | 2150 | .tag = if (comma) .async_call_comma else .async_call, |
| 2228 | }, | 2151 | .main_token = lparen, |
| 2229 | else => { | 2152 | .data = .{ |
| 2230 | p.tok_i -= 1; | 2153 | .lhs = res, |
| 2231 | try p.warnExpected(.comma); | 2154 | .rhs = try p.addExtra(try p.listToSpan(params)), |
| 2232 | }, | 2155 | }, |
| 2233 | } | 2156 | }), |
| 2234 | } | 2157 | } |
| 2235 | } | 2158 | } |
| | 2159 | |
| 2236 | var res = try p.parsePrimaryTypeExpr(); | 2160 | var res = try p.parsePrimaryTypeExpr(); |
| 2237 | if (res == 0) return res; | 2161 | if (res == 0) return res; |
| 2238 | | | |
| 2239 | while (true) { | 2162 | while (true) { |
| 2240 | const suffix_op = try p.parseSuffixOp(res); | 2163 | const suffix_op = try p.parseSuffixOp(res); |
| 2241 | if (suffix_op != 0) { | 2164 | if (suffix_op != 0) { |
| 2242 | res = suffix_op; | 2165 | res = suffix_op; |
| 2243 | continue; | 2166 | continue; |
| 2244 | } | 2167 | } |
| 2245 | res = res: { | 2168 | const lparen = p.eatToken(.l_paren) orelse return res; |
| 2246 | const lparen = p.eatToken(.l_paren) orelse return res; | 2169 | const scratch_top = p.scratch.items.len; |
| 2247 | if (p.eatToken(.r_paren)) |_| { | 2170 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2248 | break :res try p.addNode(.{ | 2171 | while (true) { |
| 2249 | .tag = .call_one, | 2172 | if (p.eatToken(.r_paren)) |_| break; |
| 2250 | .main_token = lparen, | 2173 | const param = try p.expectExpr(); |
| 2251 | .data = .{ | 2174 | try p.scratch.append(p.gpa, param); |
| 2252 | .lhs = res, | 2175 | switch (p.token_tags[p.tok_i]) { |
| 2253 | .rhs = 0, | 2176 | .comma => p.tok_i += 1, |
| 2254 | }, | 2177 | .r_paren => { p.tok_i += 1; break; }, |
| 2255 | }); | 2178 | .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren), |
| 2256 | } | 2179 | // Likely just a missing comma; give error but continue parsing. |
| 2257 | const param_one = try p.expectExpr(); | 2180 | else => try p.warnExpected(.comma), |
| 2258 | const comma_one = p.eatToken(.comma); | | |
| 2259 | if (p.eatToken(.r_paren)) |_| { | | |
| 2260 | break :res try p.addNode(.{ | | |
| 2261 | .tag = if (comma_one == null) .call_one else .call_one_comma, | | |
| 2262 | .main_token = lparen, | | |
| 2263 | .data = .{ | | |
| 2264 | .lhs = res, | | |
| 2265 | .rhs = param_one, | | |
| 2266 | }, | | |
| 2267 | }); | | |
| 2268 | } | | |
| 2269 | if (comma_one == null) { | | |
| 2270 | try p.warnExpected(.comma); | | |
| 2271 | } | | |
| 2272 | | | |
| 2273 | const scratch_top = p.scratch.items.len; | | |
| 2274 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | | |
| 2275 | | | |
| 2276 | try p.scratch.append(p.gpa, param_one); | | |
| 2277 | | | |
| 2278 | while (true) { | | |
| 2279 | const next = try p.expectExpr(); | | |
| 2280 | try p.scratch.append(p.gpa, next); | | |
| 2281 | switch (p.token_tags[p.nextToken()]) { | | |
| 2282 | .comma => { | | |
| 2283 | if (p.eatToken(.r_paren)) |_| { | | |
| 2284 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); | | |
| 2285 | break :res try p.addNode(.{ | | |
| 2286 | .tag = .call_comma, | | |
| 2287 | .main_token = lparen, | | |
| 2288 | .data = .{ | | |
| 2289 | .lhs = res, | | |
| 2290 | .rhs = try p.addExtra(Node.SubRange{ | | |
| 2291 | .start = span.start, | | |
| 2292 | .end = span.end, | | |
| 2293 | }), | | |
| 2294 | }, | | |
| 2295 | }); | | |
| 2296 | } else { | | |
| 2297 | continue; | | |
| 2298 | } | | |
| 2299 | }, | | |
| 2300 | .r_paren => { | | |
| 2301 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); | | |
| 2302 | break :res try p.addNode(.{ | | |
| 2303 | .tag = .call, | | |
| 2304 | .main_token = lparen, | | |
| 2305 | .data = .{ | | |
| 2306 | .lhs = res, | | |
| 2307 | .rhs = try p.addExtra(Node.SubRange{ | | |
| 2308 | .start = span.start, | | |
| 2309 | .end = span.end, | | |
| 2310 | }), | | |
| 2311 | }, | | |
| 2312 | }); | | |
| 2313 | }, | | |
| 2314 | .colon, .r_brace, .r_bracket => { | | |
| 2315 | p.tok_i -= 1; | | |
| 2316 | return p.failExpected(.r_paren); | | |
| 2317 | }, | | |
| 2318 | else => { | | |
| 2319 | p.tok_i -= 1; | | |
| 2320 | try p.warnExpected(.comma); | | |
| 2321 | }, | | |
| 2322 | } | | |
| 2323 | } | 2181 | } |
| | 2182 | } |
| | 2183 | const comma = (p.token_tags[p.tok_i - 2] == .comma); |
| | 2184 | const params = p.scratch.items[scratch_top..]; |
| | 2185 | res = switch(params.len) { |
| | 2186 | 0 => try p.addNode(.{ |
| | 2187 | .tag = if (comma) .call_one_comma else .call_one, |
| | 2188 | .main_token = lparen, |
| | 2189 | .data = .{ |
| | 2190 | .lhs = res, |
| | 2191 | .rhs = 0, |
| | 2192 | }, |
| | 2193 | }), |
| | 2194 | 1 => try p.addNode(.{ |
| | 2195 | .tag = if (comma) .call_one_comma else .call_one, |
| | 2196 | .main_token = lparen, |
| | 2197 | .data = .{ |
| | 2198 | .lhs = res, |
| | 2199 | .rhs = params[0], |
| | 2200 | }, |
| | 2201 | }), |
| | 2202 | else => try p.addNode(.{ |
| | 2203 | .tag = if (comma) .call_comma else .call, |
| | 2204 | .main_token = lparen, |
| | 2205 | .data = .{ |
| | 2206 | .lhs = res, |
| | 2207 | .rhs = try p.addExtra(try p.listToSpan(params)), |
| | 2208 | }, |
| | 2209 | }), |
| 2324 | }; | 2210 | }; |
| 2325 | } | 2211 | } |
| 2326 | } | 2212 | } |
| ... | @@ -2554,148 +2440,108 @@ const Parser = struct { | ... | @@ -2554,148 +2440,108 @@ const Parser = struct { |
| 2554 | // If there are 0, 1, or 2 items, we can use ArrayInitDotTwo/StructInitDotTwo; | 2440 | // If there are 0, 1, or 2 items, we can use ArrayInitDotTwo/StructInitDotTwo; |
| 2555 | // otherwise we use the full ArrayInitDot/StructInitDot. | 2441 | // otherwise we use the full ArrayInitDot/StructInitDot. |
| 2556 | | 2442 | |
| 2557 | if (p.eatToken(.r_brace)) |_| { | 2443 | const scratch_top = p.scratch.items.len; |
| 2558 | return p.addNode(.{ | 2444 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2559 | .tag = .struct_init_dot_two, | 2445 | const field_init = try p.parseFieldInit(); |
| 2560 | .main_token = lbrace, | 2446 | if (field_init != 0) { |
| 2561 | .data = .{ | 2447 | try p.scratch.append(p.gpa, field_init); |
| 2562 | .lhs = 0, | 2448 | while (true) { |
| 2563 | .rhs = 0, | 2449 | switch (p.token_tags[p.tok_i]) { |
| 2564 | }, | 2450 | .comma => p.tok_i += 1, |
| 2565 | }); | 2451 | .r_brace => { p.tok_i += 1; break; }, |
| 2566 | } | 2452 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), |
| 2567 | const field_init_one = try p.parseFieldInit(); | 2453 | // Likely just a missing comma; give error but continue parsing. |
| 2568 | if (field_init_one != 0) { | 2454 | else => try p.warnExpected(.comma), |
| 2569 | const comma_one = p.eatToken(.comma); | 2455 | } |
| 2570 | if (p.eatToken(.r_brace)) |_| { | 2456 | if (p.eatToken(.r_brace)) |_| break; |
| 2571 | return p.addNode(.{ | 2457 | const next = try p.expectFieldInit(); |
| 2572 | .tag = if (comma_one != null) .struct_init_dot_two_comma else .struct_init_dot_two, | 2458 | try p.scratch.append(p.gpa, next); |
| | 2459 | } |
| | 2460 | const comma = (p.token_tags[p.tok_i - 2] == .comma); |
| | 2461 | const inits = p.scratch.items[scratch_top..]; |
| | 2462 | switch (inits.len) { |
| | 2463 | 0 => unreachable, |
| | 2464 | 1 => return p.addNode(.{ |
| | 2465 | .tag = if (comma) .struct_init_dot_two_comma else .struct_init_dot_two, |
| 2573 | .main_token = lbrace, | 2466 | .main_token = lbrace, |
| 2574 | .data = .{ | 2467 | .data = .{ |
| 2575 | .lhs = field_init_one, | 2468 | .lhs = inits[0], |
| 2576 | .rhs = 0, | 2469 | .rhs = 0, |
| 2577 | }, | 2470 | }, |
| 2578 | }); | 2471 | }), |
| 2579 | } | 2472 | 2 => return p.addNode(.{ |
| 2580 | if (comma_one == null) { | 2473 | .tag = if (comma) .struct_init_dot_two_comma else .struct_init_dot_two, |
| 2581 | try p.warnExpected(.comma); | | |
| 2582 | } | | |
| 2583 | const field_init_two = try p.expectFieldInit(); | | |
| 2584 | const comma_two = p.eatToken(.comma); | | |
| 2585 | if (p.eatToken(.r_brace)) |_| { | | |
| 2586 | return p.addNode(.{ | | |
| 2587 | .tag = if (comma_two != null) .struct_init_dot_two_comma else .struct_init_dot_two, | | |
| 2588 | .main_token = lbrace, | 2474 | .main_token = lbrace, |
| 2589 | .data = .{ | 2475 | .data = .{ |
| 2590 | .lhs = field_init_one, | 2476 | .lhs = inits[0], |
| 2591 | .rhs = field_init_two, | 2477 | .rhs = inits[1], |
| 2592 | }, | 2478 | }, |
| 2593 | }); | 2479 | }), |
| 2594 | } | 2480 | else => { |
| 2595 | if (comma_two == null) { | 2481 | const span = try p.listToSpan(inits); |
| 2596 | try p.warnExpected(.comma); | 2482 | return p.addNode(.{ |
| | 2483 | .tag = if (comma) .struct_init_dot_comma else .struct_init_dot, |
| | 2484 | .main_token = lbrace, |
| | 2485 | .data = .{ |
| | 2486 | .lhs = span.start, |
| | 2487 | .rhs = span.end, |
| | 2488 | }, |
| | 2489 | }); |
| | 2490 | }, |
| 2597 | } | 2491 | } |
| 2598 | const scratch_top = p.scratch.items.len; | 2492 | } |
| 2599 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | | |
| 2600 | | | |
| 2601 | try p.scratch.appendSlice(p.gpa, &.{ field_init_one, field_init_two }); | | |
| 2602 | | 2493 | |
| 2603 | while (true) { | 2494 | while (true) { |
| 2604 | const next = try p.expectFieldInit(); | 2495 | if (p.eatToken(.r_brace)) |_| break; |
| 2605 | assert(next != 0); | 2496 | const elem_init = try p.expectExpr(); |
| 2606 | try p.scratch.append(p.gpa, next); | 2497 | try p.scratch.append(p.gpa, elem_init); |
| 2607 | switch (p.token_tags[p.nextToken()]) { | 2498 | switch (p.token_tags[p.tok_i]) { |
| 2608 | .comma => { | 2499 | .comma => p.tok_i += 1, |
| 2609 | if (p.eatToken(.r_brace)) |_| break; | 2500 | .r_brace => { p.tok_i += 1; break; }, |
| 2610 | continue; | 2501 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), |
| 2611 | }, | 2502 | // Likely just a missing comma; give error but continue parsing. |
| 2612 | .r_brace => break, | 2503 | else => try p.warnExpected(.comma), |
| 2613 | .colon, .r_paren, .r_bracket => { | | |
| 2614 | p.tok_i -= 1; | | |
| 2615 | return p.failExpected(.r_brace); | | |
| 2616 | }, | | |
| 2617 | else => { | | |
| 2618 | p.tok_i -= 1; | | |
| 2619 | try p.warnExpected(.comma); | | |
| 2620 | }, | | |
| 2621 | } | | |
| 2622 | } | 2504 | } |
| 2623 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); | 2505 | } |
| 2624 | const trailing_comma = p.token_tags[p.tok_i - 2] == .comma; | 2506 | const comma = (p.token_tags[p.tok_i - 2] == .comma); |
| 2625 | return p.addNode(.{ | 2507 | const inits = p.scratch.items[scratch_top..]; |
| 2626 | .tag = if (trailing_comma) .struct_init_dot_comma else .struct_init_dot, | 2508 | switch (inits.len) { |
| | 2509 | 0 => return p.addNode(.{ |
| | 2510 | .tag = .struct_init_dot_two, |
| 2627 | .main_token = lbrace, | 2511 | .main_token = lbrace, |
| 2628 | .data = .{ | 2512 | .data = .{ |
| 2629 | .lhs = span.start, | 2513 | .lhs = 0, |
| 2630 | .rhs = span.end, | 2514 | .rhs = 0, |
| 2631 | }, | 2515 | }, |
| 2632 | }); | 2516 | }), |
| 2633 | } | 2517 | 1 => return p.addNode(.{ |
| 2634 | | 2518 | .tag = if (comma) .array_init_dot_two_comma else .array_init_dot_two, |
| 2635 | const elem_init_one = try p.expectExpr(); | | |
| 2636 | const comma_one = p.eatToken(.comma); | | |
| 2637 | if (p.eatToken(.r_brace)) |_| { | | |
| 2638 | return p.addNode(.{ | | |
| 2639 | .tag = if (comma_one != null) .array_init_dot_two_comma else .array_init_dot_two, | | |
| 2640 | .main_token = lbrace, | 2519 | .main_token = lbrace, |
| 2641 | .data = .{ | 2520 | .data = .{ |
| 2642 | .lhs = elem_init_one, | 2521 | .lhs = inits[0], |
| 2643 | .rhs = 0, | 2522 | .rhs = 0, |
| 2644 | }, | 2523 | }, |
| 2645 | }); | 2524 | }), |
| 2646 | } | 2525 | 2 => return p.addNode(.{ |
| 2647 | if (comma_one == null) { | 2526 | .tag = if (comma) .array_init_dot_two_comma else .array_init_dot_two, |
| 2648 | try p.warnExpected(.comma); | | |
| 2649 | } | | |
| 2650 | const elem_init_two = try p.expectExpr(); | | |
| 2651 | const comma_two = p.eatToken(.comma); | | |
| 2652 | if (p.eatToken(.r_brace)) |_| { | | |
| 2653 | return p.addNode(.{ | | |
| 2654 | .tag = if (comma_two != null) .array_init_dot_two_comma else .array_init_dot_two, | | |
| 2655 | .main_token = lbrace, | 2527 | .main_token = lbrace, |
| 2656 | .data = .{ | 2528 | .data = .{ |
| 2657 | .lhs = elem_init_one, | 2529 | .lhs = inits[0], |
| 2658 | .rhs = elem_init_two, | 2530 | .rhs = inits[1], |
| 2659 | }, | | |
| 2660 | }); | | |
| 2661 | } | | |
| 2662 | if (comma_two == null) { | | |
| 2663 | try p.warnExpected(.comma); | | |
| 2664 | } | | |
| 2665 | const scratch_top = p.scratch.items.len; | | |
| 2666 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | | |
| 2667 | | | |
| 2668 | try p.scratch.appendSlice(p.gpa, &.{ elem_init_one, elem_init_two }); | | |
| 2669 | | | |
| 2670 | while (true) { | | |
| 2671 | const next = try p.expectExpr(); | | |
| 2672 | if (next == 0) break; | | |
| 2673 | try p.scratch.append(p.gpa, next); | | |
| 2674 | switch (p.token_tags[p.nextToken()]) { | | |
| 2675 | .comma => { | | |
| 2676 | if (p.eatToken(.r_brace)) |_| break; | | |
| 2677 | continue; | | |
| 2678 | }, | | |
| 2679 | .r_brace => break, | | |
| 2680 | .colon, .r_paren, .r_bracket => { | | |
| 2681 | p.tok_i -= 1; | | |
| 2682 | return p.failExpected(.r_brace); | | |
| 2683 | }, | 2531 | }, |
| 2684 | else => { | 2532 | }), |
| 2685 | p.tok_i -= 1; | 2533 | else => { |
| 2686 | try p.warnExpected(.comma); | 2534 | const span = try p.listToSpan(inits); |
| 2687 | }, | 2535 | return p.addNode(.{ |
| 2688 | } | 2536 | .tag = if (comma) .array_init_dot_comma else .array_init_dot, |
| 2689 | } | 2537 | .main_token = lbrace, |
| 2690 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); | 2538 | .data = .{ |
| 2691 | return p.addNode(.{ | 2539 | .lhs = span.start, |
| 2692 | .tag = if (p.token_tags[p.tok_i - 2] == .comma) .array_init_dot_comma else .array_init_dot, | 2540 | .rhs = span.end, |
| 2693 | .main_token = lbrace, | 2541 | }, |
| 2694 | .data = .{ | 2542 | }); |
| 2695 | .lhs = span.start, | | |
| 2696 | .rhs = span.end, | | |
| 2697 | }, | 2543 | }, |
| 2698 | }); | 2544 | } |
| 2699 | }, | 2545 | }, |
| 2700 | else => return null_node, | 2546 | else => return null_node, |
| 2701 | }, | 2547 | }, |
| ... | @@ -2703,37 +2549,16 @@ const Parser = struct { | ... | @@ -2703,37 +2549,16 @@ const Parser = struct { |
| 2703 | .l_brace => { | 2549 | .l_brace => { |
| 2704 | const error_token = p.tok_i; | 2550 | const error_token = p.tok_i; |
| 2705 | p.tok_i += 2; | 2551 | p.tok_i += 2; |
| 2706 | | | |
| 2707 | if (p.eatToken(.r_brace)) |rbrace| { | | |
| 2708 | return p.addNode(.{ | | |
| 2709 | .tag = .error_set_decl, | | |
| 2710 | .main_token = error_token, | | |
| 2711 | .data = .{ | | |
| 2712 | .lhs = undefined, | | |
| 2713 | .rhs = rbrace, | | |
| 2714 | }, | | |
| 2715 | }); | | |
| 2716 | } | | |
| 2717 | | | |
| 2718 | while (true) { | 2552 | while (true) { |
| | 2553 | if (p.eatToken(.r_brace)) |_| break; |
| 2719 | const doc_comment = try p.eatDocComments(); | 2554 | const doc_comment = try p.eatDocComments(); |
| 2720 | const identifier = try p.expectToken(.identifier); | 2555 | const identifier = try p.expectToken(.identifier); |
| 2721 | switch (p.token_tags[p.nextToken()]) { | 2556 | switch (p.token_tags[p.tok_i]) { |
| 2722 | .comma => { | 2557 | .comma => p.tok_i += 1, |
| 2723 | if (p.eatToken(.r_brace)) |_| break; | 2558 | .r_brace => { p.tok_i += 1; break; }, |
| 2724 | continue; | 2559 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), |
| 2725 | }, | 2560 | // Likely just a missing comma; give error but continue parsing. |
| 2726 | .r_brace => break, | 2561 | else => try p.warnExpected(.comma), |
| 2727 | .colon, .r_paren, .r_bracket => { | | |
| 2728 | p.tok_i -= 1; | | |
| 2729 | return p.failExpected(.r_brace); | | |
| 2730 | }, | | |
| 2731 | else => { | | |
| 2732 | // This is likely just a missing comma; | | |
| 2733 | // give an error but continue parsing this list. | | |
| 2734 | p.tok_i -= 1; | | |
| 2735 | try p.warnExpected(.comma); | | |
| 2736 | }, | | |
| 2737 | } | 2562 | } |
| 2738 | } | 2563 | } |
| 2739 | return p.addNode(.{ | 2564 | return p.addNode(.{ |
| ... | @@ -2791,7 +2616,7 @@ const Parser = struct { | ... | @@ -2791,7 +2616,7 @@ const Parser = struct { |
| 2791 | const found_payload = try p.parsePtrIndexPayload(); | 2616 | const found_payload = try p.parsePtrIndexPayload(); |
| 2792 | if (found_payload == 0) try p.warn(.expected_loop_payload); | 2617 | if (found_payload == 0) try p.warn(.expected_loop_payload); |
| 2793 | | 2618 | |
| 2794 | const then_expr = try p.expectExpr(); | 2619 | const then_expr = try p.expectTypeExpr(); |
| 2795 | const else_token = p.eatToken(.keyword_else) orelse { | 2620 | const else_token = p.eatToken(.keyword_else) orelse { |
| 2796 | return p.addNode(.{ | 2621 | return p.addNode(.{ |
| 2797 | .tag = .for_simple, | 2622 | .tag = .for_simple, |
| ... | @@ -2926,12 +2751,10 @@ const Parser = struct { | ... | @@ -2926,12 +2751,10 @@ const Parser = struct { |
| 2926 | try p.scratch.append(p.gpa, output_item); | 2751 | try p.scratch.append(p.gpa, output_item); |
| 2927 | switch (p.token_tags[p.tok_i]) { | 2752 | switch (p.token_tags[p.tok_i]) { |
| 2928 | .comma => p.tok_i += 1, | 2753 | .comma => p.tok_i += 1, |
| 2929 | .colon, .r_paren, .r_brace, .r_bracket => break, // All possible delimiters. | 2754 | // All possible delimiters. |
| 2930 | else => { | 2755 | .colon, .r_paren, .r_brace, .r_bracket => break, |
| 2931 | // This is likely just a missing comma; | 2756 | // Likely just a missing comma; give error but continue parsing. |
| 2932 | // give an error but continue parsing this list. | 2757 | else => try p.warnExpected(.comma), |
| 2933 | try p.warnExpected(.comma); | | |
| 2934 | }, | | |
| 2935 | } | 2758 | } |
| 2936 | } | 2759 | } |
| 2937 | if (p.eatToken(.colon)) |_| { | 2760 | if (p.eatToken(.colon)) |_| { |
| ... | @@ -2941,12 +2764,10 @@ const Parser = struct { | ... | @@ -2941,12 +2764,10 @@ const Parser = struct { |
| 2941 | try p.scratch.append(p.gpa, input_item); | 2764 | try p.scratch.append(p.gpa, input_item); |
| 2942 | switch (p.token_tags[p.tok_i]) { | 2765 | switch (p.token_tags[p.tok_i]) { |
| 2943 | .comma => p.tok_i += 1, | 2766 | .comma => p.tok_i += 1, |
| 2944 | .colon, .r_paren, .r_brace, .r_bracket => break, // All possible delimiters. | 2767 | // All possible delimiters. |
| 2945 | else => { | 2768 | .colon, .r_paren, .r_brace, .r_bracket => break, |
| 2946 | // This is likely just a missing comma; | 2769 | // Likely just a missing comma; give error but continue parsing. |
| 2947 | // give an error but continue parsing this list. | 2770 | else => try p.warnExpected(.comma), |
| 2948 | try p.warnExpected(.comma); | | |
| 2949 | }, | | |
| 2950 | } | 2771 | } |
| 2951 | } | 2772 | } |
| 2952 | if (p.eatToken(.colon)) |_| { | 2773 | if (p.eatToken(.colon)) |_| { |
| ... | @@ -2954,11 +2775,8 @@ const Parser = struct { | ... | @@ -2954,11 +2775,8 @@ const Parser = struct { |
| 2954 | switch (p.token_tags[p.tok_i]) { | 2775 | switch (p.token_tags[p.tok_i]) { |
| 2955 | .comma => p.tok_i += 1, | 2776 | .comma => p.tok_i += 1, |
| 2956 | .colon, .r_paren, .r_brace, .r_bracket => break, | 2777 | .colon, .r_paren, .r_brace, .r_bracket => break, |
| 2957 | else => { | 2778 | // Likely just a missing comma; give error but continue parsing. |
| 2958 | // This is likely just a missing comma; | 2779 | else => try p.warnExpected(.comma), |
| 2959 | // give an error but continue parsing this list. | | |
| 2960 | try p.warnExpected(.comma); | | |
| 2961 | }, | | |
| 2962 | } | 2780 | } |
| 2963 | } | 2781 | } |
| 2964 | } | 2782 | } |
| ... | @@ -3158,56 +2976,48 @@ const Parser = struct { | ... | @@ -3158,56 +2976,48 @@ const Parser = struct { |
| 3158 | /// <- SwitchItem (COMMA SwitchItem)* COMMA? | 2976 | /// <- SwitchItem (COMMA SwitchItem)* COMMA? |
| 3159 | /// / KEYWORD_else | 2977 | /// / KEYWORD_else |
| 3160 | fn parseSwitchProng(p: *Parser) !Node.Index { | 2978 | fn parseSwitchProng(p: *Parser) !Node.Index { |
| 3161 | if (p.eatToken(.keyword_else)) |_| { | 2979 | const scratch_top = p.scratch.items.len; |
| 3162 | const arrow_token = try p.expectToken(.equal_angle_bracket_right); | 2980 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 3163 | _ = try p.parsePtrPayload(); | 2981 | |
| 3164 | return p.addNode(.{ | 2982 | if (p.eatToken(.keyword_else) == null) { |
| | 2983 | while (true) { |
| | 2984 | const item = try p.parseSwitchItem(); |
| | 2985 | if (item == 0) break; |
| | 2986 | try p.scratch.append(p.gpa, item); |
| | 2987 | if (p.eatToken(.comma) == null) break; |
| | 2988 | } |
| | 2989 | if (scratch_top == p.scratch.items.len) return null_node; |
| | 2990 | } |
| | 2991 | const arrow_token = try p.expectToken(.equal_angle_bracket_right); |
| | 2992 | _ = try p.parsePtrPayload(); |
| | 2993 | |
| | 2994 | const items = p.scratch.items[scratch_top..]; |
| | 2995 | switch(items.len) { |
| | 2996 | 0 => return p.addNode(.{ |
| 3165 | .tag = .switch_case_one, | 2997 | .tag = .switch_case_one, |
| 3166 | .main_token = arrow_token, | 2998 | .main_token = arrow_token, |
| 3167 | .data = .{ | 2999 | .data = .{ |
| 3168 | .lhs = 0, | 3000 | .lhs = 0, |
| 3169 | .rhs = try p.expectAssignExpr(), | 3001 | .rhs = try p.expectAssignExpr(), |
| 3170 | }, | 3002 | } |
| 3171 | }); | 3003 | }), |
| 3172 | } | 3004 | 1 => return p.addNode(.{ |
| 3173 | const first_item = try p.parseSwitchItem(); | | |
| 3174 | if (first_item == 0) return null_node; | | |
| 3175 | | | |
| 3176 | if (p.eatToken(.equal_angle_bracket_right)) |arrow_token| { | | |
| 3177 | _ = try p.parsePtrPayload(); | | |
| 3178 | return p.addNode(.{ | | |
| 3179 | .tag = .switch_case_one, | 3005 | .tag = .switch_case_one, |
| 3180 | .main_token = arrow_token, | 3006 | .main_token = arrow_token, |
| 3181 | .data = .{ | 3007 | .data = .{ |
| 3182 | .lhs = first_item, | 3008 | .lhs = items[0], |
| | 3009 | .rhs = try p.expectAssignExpr(), |
| | 3010 | } |
| | 3011 | }), |
| | 3012 | else => return p.addNode(.{ |
| | 3013 | .tag = .switch_case, |
| | 3014 | .main_token = arrow_token, |
| | 3015 | .data = .{ |
| | 3016 | .lhs = try p.addExtra(try p.listToSpan(items)), |
| 3183 | .rhs = try p.expectAssignExpr(), | 3017 | .rhs = try p.expectAssignExpr(), |
| 3184 | }, | 3018 | }, |
| 3185 | }); | 3019 | }), |
| 3186 | } | | |
| 3187 | | | |
| 3188 | const scratch_top = p.scratch.items.len; | | |
| 3189 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | | |
| 3190 | | | |
| 3191 | try p.scratch.append(p.gpa, first_item); | | |
| 3192 | while (p.eatToken(.comma)) |_| { | | |
| 3193 | const next_item = try p.parseSwitchItem(); | | |
| 3194 | if (next_item == 0) break; | | |
| 3195 | try p.scratch.append(p.gpa, next_item); | | |
| 3196 | } | 3020 | } |
| 3197 | const span = try p.listToSpan(p.scratch.items[scratch_top..]); | | |
| 3198 | const arrow_token = try p.expectToken(.equal_angle_bracket_right); | | |
| 3199 | _ = try p.parsePtrPayload(); | | |
| 3200 | return p.addNode(.{ | | |
| 3201 | .tag = .switch_case, | | |
| 3202 | .main_token = arrow_token, | | |
| 3203 | .data = .{ | | |
| 3204 | .lhs = try p.addExtra(Node.SubRange{ | | |
| 3205 | .start = span.start, | | |
| 3206 | .end = span.end, | | |
| 3207 | }), | | |
| 3208 | .rhs = try p.expectAssignExpr(), | | |
| 3209 | }, | | |
| 3210 | }); | | |
| 3211 | } | 3021 | } |
| 3212 | | 3022 | |
| 3213 | /// SwitchItem <- Expr (DOT3 Expr)? | 3023 | /// SwitchItem <- Expr (DOT3 Expr)? |
| ... | @@ -3563,19 +3373,12 @@ const Parser = struct { | ... | @@ -3563,19 +3373,12 @@ const Parser = struct { |
| 3563 | } else if (p.token_tags[p.tok_i - 1] == .ellipsis3) { | 3373 | } else if (p.token_tags[p.tok_i - 1] == .ellipsis3) { |
| 3564 | if (varargs == .none) varargs = .seen; | 3374 | if (varargs == .none) varargs = .seen; |
| 3565 | } | 3375 | } |
| 3566 | switch (p.token_tags[p.nextToken()]) { | 3376 | switch (p.token_tags[p.tok_i]) { |
| 3567 | .comma => {}, | 3377 | .comma => p.tok_i += 1, |
| 3568 | .r_paren => break, | 3378 | .r_paren => { p.tok_i += 1; break; }, |
| 3569 | .colon, .r_brace, .r_bracket => { | 3379 | .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren), |
| 3570 | p.tok_i -= 1; | 3380 | // Likely just a missing comma; give error but continue parsing. |
| 3571 | return p.failExpected(.r_paren); | 3381 | else => try p.warnExpected(.comma), |
| 3572 | }, | | |
| 3573 | else => { | | |
| 3574 | // This is likely just a missing comma; | | |
| 3575 | // give an error but continue parsing this list. | | |
| 3576 | p.tok_i -= 1; | | |
| 3577 | try p.warnExpected(.comma); | | |
| 3578 | }, | | |
| 3579 | } | 3382 | } |
| 3580 | } | 3383 | } |
| 3581 | if (varargs == .nonfinal) { | 3384 | if (varargs == .nonfinal) { |
| ... | @@ -3605,13 +3408,10 @@ const Parser = struct { | ... | @@ -3605,13 +3408,10 @@ const Parser = struct { |
| 3605 | | 3408 | |
| 3606 | switch (p.token_tags[p.tok_i]) { | 3409 | switch (p.token_tags[p.tok_i]) { |
| 3607 | .comma => p.tok_i += 1, | 3410 | .comma => p.tok_i += 1, |
| 3608 | // all possible delimiters | 3411 | // All possible delimiters. |
| 3609 | .colon, .r_paren, .r_brace, .r_bracket => break, | 3412 | .colon, .r_paren, .r_brace, .r_bracket => break, |
| 3610 | else => { | 3413 | // Likely just a missing comma; give error but continue parsing. |
| 3611 | // This is likely just a missing comma; | 3414 | else => try p.warnExpected(.comma), |
| 3612 | // give an error but continue parsing this list. | | |
| 3613 | try p.warnExpected(.comma); | | |
| 3614 | }, | | |
| 3615 | } | 3415 | } |
| 3616 | } | 3416 | } |
| 3617 | return p.listToSpan(p.scratch.items[scratch_top..]); | 3417 | return p.listToSpan(p.scratch.items[scratch_top..]); |
| ... | @@ -3636,117 +3436,58 @@ const Parser = struct { | ... | @@ -3636,117 +3436,58 @@ const Parser = struct { |
| 3636 | }, | 3436 | }, |
| 3637 | }); | 3437 | }); |
| 3638 | } | 3438 | } |
| 3639 | if (p.eatToken(.r_paren)) |_| { | 3439 | const scratch_top = p.scratch.items.len; |
| 3640 | return p.addNode(.{ | 3440 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| | 3441 | while (true) { |
| | 3442 | if (p.eatToken(.r_paren)) |_| break; |
| | 3443 | const param = try p.expectExpr(); |
| | 3444 | try p.scratch.append(p.gpa, param); |
| | 3445 | switch (p.token_tags[p.tok_i]) { |
| | 3446 | .comma => p.tok_i += 1, |
| | 3447 | .r_paren => { p.tok_i += 1; break; }, |
| | 3448 | // Likely just a missing comma; give error but continue parsing. |
| | 3449 | else => try p.warnExpected(.comma), |
| | 3450 | } |
| | 3451 | } |
| | 3452 | const comma = (p.token_tags[p.tok_i - 2] == .comma); |
| | 3453 | const params = p.scratch.items[scratch_top..]; |
| | 3454 | switch (params.len) { |
| | 3455 | 0 => return p.addNode(.{ |
| 3641 | .tag = .builtin_call_two, | 3456 | .tag = .builtin_call_two, |
| 3642 | .main_token = builtin_token, | 3457 | .main_token = builtin_token, |
| 3643 | .data = .{ | 3458 | .data = .{ |
| 3644 | .lhs = 0, | 3459 | .lhs = 0, |
| 3645 | .rhs = 0, | 3460 | .rhs = 0, |
| 3646 | }, | 3461 | }, |
| 3647 | }); | 3462 | }), |
| 3648 | } | 3463 | 1 => return p.addNode(.{ |
| 3649 | const param_one = try p.expectExpr(); | 3464 | .tag = if (comma) .builtin_call_two_comma else .builtin_call_two, |
| 3650 | switch (p.token_tags[p.nextToken()]) { | | |
| 3651 | .comma => { | | |
| 3652 | if (p.eatToken(.r_paren)) |_| { | | |
| 3653 | return p.addNode(.{ | | |
| 3654 | .tag = .builtin_call_two_comma, | | |
| 3655 | .main_token = builtin_token, | | |
| 3656 | .data = .{ | | |
| 3657 | .lhs = param_one, | | |
| 3658 | .rhs = 0, | | |
| 3659 | }, | | |
| 3660 | }); | | |
| 3661 | } | | |
| 3662 | }, | | |
| 3663 | .r_paren => return p.addNode(.{ | | |
| 3664 | .tag = .builtin_call_two, | | |
| 3665 | .main_token = builtin_token, | 3465 | .main_token = builtin_token, |
| 3666 | .data = .{ | 3466 | .data = .{ |
| 3667 | .lhs = param_one, | 3467 | .lhs = params[0], |
| 3668 | .rhs = 0, | 3468 | .rhs = 0, |
| 3669 | }, | 3469 | }, |
| 3670 | }), | 3470 | }), |
| 3671 | else => { | 3471 | 2 => return p.addNode(.{ |
| 3672 | // This is likely just a missing comma; | 3472 | .tag = if (comma) .builtin_call_two_comma else .builtin_call_two, |
| 3673 | // give an error but continue parsing this list. | | |
| 3674 | p.tok_i -= 1; | | |
| 3675 | try p.warnExpected(.comma); | | |
| 3676 | }, | | |
| 3677 | } | | |
| 3678 | const param_two = try p.expectExpr(); | | |
| 3679 | switch (p.token_tags[p.nextToken()]) { | | |
| 3680 | .comma => { | | |
| 3681 | if (p.eatToken(.r_paren)) |_| { | | |
| 3682 | return p.addNode(.{ | | |
| 3683 | .tag = .builtin_call_two_comma, | | |
| 3684 | .main_token = builtin_token, | | |
| 3685 | .data = .{ | | |
| 3686 | .lhs = param_one, | | |
| 3687 | .rhs = param_two, | | |
| 3688 | }, | | |
| 3689 | }); | | |
| 3690 | } | | |
| 3691 | }, | | |
| 3692 | .r_paren => return p.addNode(.{ | | |
| 3693 | .tag = .builtin_call_two, | | |
| 3694 | .main_token = builtin_token, | 3473 | .main_token = builtin_token, |
| 3695 | .data = .{ | 3474 | .data = .{ |
| 3696 | .lhs = param_one, | 3475 | .lhs = params[0], |
| 3697 | .rhs = param_two, | 3476 | .rhs = params[1], |
| 3698 | }, | 3477 | }, |
| 3699 | }), | 3478 | }), |
| 3700 | else => { | 3479 | else => { |
| 3701 | // This is likely just a missing comma; | 3480 | const span = try p.listToSpan(params); |
| 3702 | // give an error but continue parsing this list. | 3481 | return p.addNode(.{ |
| 3703 | p.tok_i -= 1; | 3482 | .tag = if (comma) .builtin_call_comma else .builtin_call, |
| 3704 | try p.warnExpected(.comma); | 3483 | .main_token = builtin_token, |
| | 3484 | .data = .{ |
| | 3485 | .lhs = span.start, |
| | 3486 | .rhs = span.end, |
| | 3487 | }, |
| | 3488 | }); |
| 3705 | }, | 3489 | }, |
| 3706 | } | 3490 | } |
| 3707 | | | |
| 3708 | const scratch_top = p.scratch.items.len; | | |
| 3709 | defer p.scratch.shrinkRetainingCapacity(scratch_top); | | |
| 3710 | | | |
| 3711 | try p.scratch.appendSlice(p.gpa, &.{ param_one, param_two }); | | |
| 3712 | | | |
| 3713 | while (true) { | | |
| 3714 | const param = try p.expectExpr(); | | |
| 3715 | try p.scratch.append(p.gpa, param); | | |
| 3716 | switch (p.token_tags[p.nextToken()]) { | | |
| 3717 | .comma => { | | |
| 3718 | if (p.eatToken(.r_paren)) |_| { | | |
| 3719 | const params = try p.listToSpan(p.scratch.items[scratch_top..]); | | |
| 3720 | return p.addNode(.{ | | |
| 3721 | .tag = .builtin_call_comma, | | |
| 3722 | .main_token = builtin_token, | | |
| 3723 | .data = .{ | | |
| 3724 | .lhs = params.start, | | |
| 3725 | .rhs = params.end, | | |
| 3726 | }, | | |
| 3727 | }); | | |
| 3728 | } | | |
| 3729 | continue; | | |
| 3730 | }, | | |
| 3731 | .r_paren => { | | |
| 3732 | const params = try p.listToSpan(p.scratch.items[scratch_top..]); | | |
| 3733 | return p.addNode(.{ | | |
| 3734 | .tag = .builtin_call, | | |
| 3735 | .main_token = builtin_token, | | |
| 3736 | .data = .{ | | |
| 3737 | .lhs = params.start, | | |
| 3738 | .rhs = params.end, | | |
| 3739 | }, | | |
| 3740 | }); | | |
| 3741 | }, | | |
| 3742 | else => { | | |
| 3743 | // This is likely just a missing comma; | | |
| 3744 | // give an error but continue parsing this list. | | |
| 3745 | p.tok_i -= 1; | | |
| 3746 | try p.warnExpected(.comma); | | |
| 3747 | }, | | |
| 3748 | } | | |
| 3749 | } | | |
| 3750 | } | 3491 | } |
| 3751 | | 3492 | |
| 3752 | // string literal or multiline string literal | 3493 | // string literal or multiline string literal |