| ... | ... | @@ -1850,65 +1850,54 @@ const Parser = struct { |
| 1850 | 1850 | /// Block <- LBRACE Statement* RBRACE |
| 1851 | 1851 | fn parseBlock(p: *Parser) !Node.Index { |
| 1852 | 1852 | const lbrace = p.eatToken(.l_brace) orelse return null_node; |
| 1853 | | |
| 1854 | | if (p.eatToken(.r_brace)) |_| { |
| 1855 | | return p.addNode(.{ |
| 1853 | const scratch_top = p.scratch.items.len; |
| 1854 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 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 | 1866 | .tag = .block_two, |
| 1857 | 1867 | .main_token = lbrace, |
| 1858 | 1868 | .data = .{ |
| 1859 | 1869 | .lhs = 0, |
| 1860 | 1870 | .rhs = 0, |
| 1861 | 1871 | }, |
| 1862 | | }); |
| 1863 | | } |
| 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(.{ |
| 1872 | }), |
| 1873 | 1 => return p.addNode(.{ |
| 1869 | 1874 | .tag = if (semicolon) .block_two_semicolon else .block_two, |
| 1870 | 1875 | .main_token = lbrace, |
| 1871 | 1876 | .data = .{ |
| 1872 | | .lhs = stmt_one, |
| 1877 | .lhs = statements[0], |
| 1873 | 1878 | .rhs = 0, |
| 1874 | 1879 | }, |
| 1875 | | }); |
| 1876 | | } |
| 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(.{ |
| 1880 | }), |
| 1881 | 2 => return p.addNode(.{ |
| 1881 | 1882 | .tag = if (semicolon) .block_two_semicolon else .block_two, |
| 1882 | 1883 | .main_token = lbrace, |
| 1883 | 1884 | .data = .{ |
| 1884 | | .lhs = stmt_one, |
| 1885 | | .rhs = stmt_two, |
| 1885 | .lhs = statements[0], |
| 1886 | .rhs = statements[1], |
| 1886 | 1887 | }, |
| 1887 | | }); |
| 1888 | | } |
| 1889 | | |
| 1890 | | const scratch_top = p.scratch.items.len; |
| 1891 | | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 1892 | | |
| 1893 | | try p.scratch.appendSlice(p.gpa, &.{ stmt_one, stmt_two }); |
| 1894 | | |
| 1895 | | while (true) { |
| 1896 | | const statement = try p.expectStatementRecoverable(); |
| 1897 | | if (statement == 0) break; |
| 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, |
| 1888 | }), |
| 1889 | else => { |
| 1890 | const span = try p.listToSpan(statements); |
| 1891 | return p.addNode(.{ |
| 1892 | .tag = if (semicolon) .block_semicolon else .block, |
| 1893 | .main_token = lbrace, |
| 1894 | .data = .{ |
| 1895 | .lhs = span.start, |
| 1896 | .rhs = span.end, |
| 1897 | }, |
| 1898 | }); |
| 1910 | 1899 | }, |
| 1911 | | }); |
| 1900 | } |
| 1912 | 1901 | } |
| 1913 | 1902 | |
| 1914 | 1903 | /// ForPrefix <- KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload |
| ... | ... | @@ -2010,114 +1999,86 @@ const Parser = struct { |
| 2010 | 1999 | // If there are 0 or 1 items, we can use ArrayInitOne/StructInitOne; |
| 2011 | 2000 | // otherwise we use the full ArrayInit/StructInit. |
| 2012 | 2001 | |
| 2013 | | if (p.eatToken(.r_brace)) |_| { |
| 2014 | | return p.addNode(.{ |
| 2015 | | .tag = .struct_init_one, |
| 2016 | | .main_token = lbrace, |
| 2017 | | .data = .{ |
| 2018 | | .lhs = lhs, |
| 2019 | | .rhs = 0, |
| 2020 | | }, |
| 2021 | | }); |
| 2022 | | } |
| 2002 | const scratch_top = p.scratch.items.len; |
| 2003 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2023 | 2004 | const field_init = try p.parseFieldInit(); |
| 2024 | 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 | 2006 | try p.scratch.append(p.gpa, field_init); |
| 2041 | | |
| 2042 | 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 | 2016 | const next = try p.expectFieldInit(); |
| 2044 | 2017 | try p.scratch.append(p.gpa, next); |
| 2045 | | |
| 2046 | | switch (p.token_tags[p.nextToken()]) { |
| 2047 | | .comma => { |
| 2048 | | if (p.eatToken(.r_brace)) |_| break; |
| 2049 | | continue; |
| 2050 | | }, |
| 2051 | | .r_brace => break, |
| 2052 | | .colon, .r_paren, .r_bracket => { |
| 2053 | | p.tok_i -= 1; |
| 2054 | | return p.failExpected(.r_brace); |
| 2018 | } |
| 2019 | const comma = (p.token_tags[p.tok_i - 2] == .comma); |
| 2020 | const inits = p.scratch.items[scratch_top..]; |
| 2021 | switch (inits.len) { |
| 2022 | 0 => unreachable, |
| 2023 | 1 => return p.addNode(.{ |
| 2024 | .tag = if (comma) .struct_init_one_comma else .struct_init_one, |
| 2025 | .main_token = lbrace, |
| 2026 | .data = .{ |
| 2027 | .lhs = lhs, |
| 2028 | .rhs = inits[0], |
| 2055 | 2029 | }, |
| 2056 | | else => { |
| 2057 | | // This is likely just a missing comma; |
| 2058 | | // give an error but continue parsing this list. |
| 2059 | | p.tok_i -= 1; |
| 2060 | | try p.warnExpected(.comma); |
| 2030 | }), |
| 2031 | else => return p.addNode(.{ |
| 2032 | .tag = if (comma) .struct_init_comma else .struct_init, |
| 2033 | .main_token = lbrace, |
| 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..]); |
| 2065 | | return p.addNode(.{ |
| 2066 | | .tag = if (p.token_tags[p.tok_i - 2] == .comma) .struct_init_comma else .struct_init, |
| 2040 | } |
| 2041 | |
| 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 | 2059 | .main_token = lbrace, |
| 2068 | 2060 | .data = .{ |
| 2069 | 2061 | .lhs = lhs, |
| 2070 | | .rhs = try p.addExtra(Node.SubRange{ |
| 2071 | | .start = span.start, |
| 2072 | | .end = span.end, |
| 2073 | | }), |
| 2062 | .rhs = 0, |
| 2074 | 2063 | }, |
| 2075 | | }); |
| 2076 | | } |
| 2077 | | |
| 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, |
| 2064 | }), |
| 2065 | 1 => return p.addNode(.{ |
| 2066 | .tag = if (comma) .array_init_one_comma else .array_init_one, |
| 2083 | 2067 | .main_token = lbrace, |
| 2084 | 2068 | .data = .{ |
| 2085 | 2069 | .lhs = lhs, |
| 2086 | | .rhs = elem_init, |
| 2070 | .rhs = inits[0], |
| 2087 | 2071 | }, |
| 2088 | | }); |
| 2089 | | } |
| 2090 | | if (comma_one == null) { |
| 2091 | | try p.warnExpected(.comma); |
| 2092 | | } |
| 2093 | | |
| 2094 | | const scratch_top = p.scratch.items.len; |
| 2095 | | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2096 | | |
| 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 | | } |
| 2072 | }), |
| 2073 | else => return p.addNode(.{ |
| 2074 | .tag = if (comma) .array_init_comma else .array_init, |
| 2075 | .main_token = lbrace, |
| 2076 | .data = .{ |
| 2077 | .lhs = lhs, |
| 2078 | .rhs = try p.addExtra(try p.listToSpan(inits)), |
| 2079 | }, |
| 2080 | }), |
| 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 | 2084 | /// ErrorUnionExpr <- SuffixExpr (EXCLAMATIONMARK TypeExpr)? |
| ... | ... | @@ -2143,184 +2104,109 @@ const Parser = struct { |
| 2143 | 2104 | fn parseSuffixExpr(p: *Parser) !Node.Index { |
| 2144 | 2105 | if (p.eatToken(.keyword_async)) |async_token| { |
| 2145 | 2106 | var res = try p.expectPrimaryTypeExpr(); |
| 2146 | | |
| 2147 | 2107 | while (true) { |
| 2148 | 2108 | const node = try p.parseSuffixOp(res); |
| 2149 | 2109 | if (node == 0) break; |
| 2150 | 2110 | res = node; |
| 2151 | 2111 | } |
| 2152 | | const lparen = p.nextToken(); |
| 2153 | | if (p.token_tags[lparen] != .l_paren) { |
| 2154 | | p.tok_i -= 1; |
| 2112 | const lparen = p.eatToken(.l_paren) orelse { |
| 2155 | 2113 | try p.warn(.expected_param_list); |
| 2156 | 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)) |_| { |
| 2159 | | return p.addNode(.{ |
| 2160 | | .tag = .async_call_one, |
| 2130 | const comma = (p.token_tags[p.tok_i - 2] == .comma); |
| 2131 | const params = p.scratch.items[scratch_top..]; |
| 2132 | switch(params.len) { |
| 2133 | 0 => return p.addNode(.{ |
| 2134 | .tag = if (comma) .async_call_one_comma else .async_call_one, |
| 2161 | 2135 | .main_token = lparen, |
| 2162 | 2136 | .data = .{ |
| 2163 | 2137 | .lhs = res, |
| 2164 | 2138 | .rhs = 0, |
| 2165 | 2139 | }, |
| 2166 | | }); |
| 2167 | | } |
| 2168 | | const param_one = try p.expectExpr(); |
| 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, |
| 2140 | }), |
| 2141 | 1 => return p.addNode(.{ |
| 2142 | .tag = if (comma) .async_call_one_comma else .async_call_one, |
| 2173 | 2143 | .main_token = lparen, |
| 2174 | 2144 | .data = .{ |
| 2175 | 2145 | .lhs = res, |
| 2176 | | .rhs = param_one, |
| 2146 | .rhs = params[0], |
| 2177 | 2147 | }, |
| 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 | | }, |
| 2225 | | .colon, .r_brace, .r_bracket => { |
| 2226 | | p.tok_i -= 1; |
| 2227 | | return p.failExpected(.r_paren); |
| 2228 | | }, |
| 2229 | | else => { |
| 2230 | | p.tok_i -= 1; |
| 2231 | | try p.warnExpected(.comma); |
| 2148 | }), |
| 2149 | else => return p.addNode(.{ |
| 2150 | .tag = if (comma) .async_call_comma else .async_call, |
| 2151 | .main_token = lparen, |
| 2152 | .data = .{ |
| 2153 | .lhs = res, |
| 2154 | .rhs = try p.addExtra(try p.listToSpan(params)), |
| 2232 | 2155 | }, |
| 2233 | | } |
| 2156 | }), |
| 2234 | 2157 | } |
| 2235 | 2158 | } |
| 2159 | |
| 2236 | 2160 | var res = try p.parsePrimaryTypeExpr(); |
| 2237 | 2161 | if (res == 0) return res; |
| 2238 | | |
| 2239 | 2162 | while (true) { |
| 2240 | 2163 | const suffix_op = try p.parseSuffixOp(res); |
| 2241 | 2164 | if (suffix_op != 0) { |
| 2242 | 2165 | res = suffix_op; |
| 2243 | 2166 | continue; |
| 2244 | 2167 | } |
| 2245 | | res = res: { |
| 2246 | | const lparen = p.eatToken(.l_paren) orelse return res; |
| 2247 | | if (p.eatToken(.r_paren)) |_| { |
| 2248 | | break :res try p.addNode(.{ |
| 2249 | | .tag = .call_one, |
| 2250 | | .main_token = lparen, |
| 2251 | | .data = .{ |
| 2252 | | .lhs = res, |
| 2253 | | .rhs = 0, |
| 2254 | | }, |
| 2255 | | }); |
| 2256 | | } |
| 2257 | | const param_one = try p.expectExpr(); |
| 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 | | } |
| 2168 | const lparen = p.eatToken(.l_paren) orelse return res; |
| 2169 | const scratch_top = p.scratch.items.len; |
| 2170 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2171 | while (true) { |
| 2172 | if (p.eatToken(.r_paren)) |_| break; |
| 2173 | const param = try p.expectExpr(); |
| 2174 | try p.scratch.append(p.gpa, param); |
| 2175 | switch (p.token_tags[p.tok_i]) { |
| 2176 | .comma => p.tok_i += 1, |
| 2177 | .r_paren => { p.tok_i += 1; break; }, |
| 2178 | .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren), |
| 2179 | // Likely just a missing comma; give error but continue parsing. |
| 2180 | else => try p.warnExpected(.comma), |
| 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 | 2440 | // If there are 0, 1, or 2 items, we can use ArrayInitDotTwo/StructInitDotTwo; |
| 2555 | 2441 | // otherwise we use the full ArrayInitDot/StructInitDot. |
| 2556 | 2442 | |
| 2557 | | if (p.eatToken(.r_brace)) |_| { |
| 2558 | | return p.addNode(.{ |
| 2559 | | .tag = .struct_init_dot_two, |
| 2560 | | .main_token = lbrace, |
| 2561 | | .data = .{ |
| 2562 | | .lhs = 0, |
| 2563 | | .rhs = 0, |
| 2564 | | }, |
| 2565 | | }); |
| 2566 | | } |
| 2567 | | const field_init_one = try p.parseFieldInit(); |
| 2568 | | if (field_init_one != 0) { |
| 2569 | | const comma_one = p.eatToken(.comma); |
| 2570 | | if (p.eatToken(.r_brace)) |_| { |
| 2571 | | return p.addNode(.{ |
| 2572 | | .tag = if (comma_one != null) .struct_init_dot_two_comma else .struct_init_dot_two, |
| 2443 | const scratch_top = p.scratch.items.len; |
| 2444 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2445 | const field_init = try p.parseFieldInit(); |
| 2446 | if (field_init != 0) { |
| 2447 | try p.scratch.append(p.gpa, field_init); |
| 2448 | while (true) { |
| 2449 | switch (p.token_tags[p.tok_i]) { |
| 2450 | .comma => p.tok_i += 1, |
| 2451 | .r_brace => { p.tok_i += 1; break; }, |
| 2452 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), |
| 2453 | // Likely just a missing comma; give error but continue parsing. |
| 2454 | else => try p.warnExpected(.comma), |
| 2455 | } |
| 2456 | if (p.eatToken(.r_brace)) |_| break; |
| 2457 | const next = try p.expectFieldInit(); |
| 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 | 2466 | .main_token = lbrace, |
| 2574 | 2467 | .data = .{ |
| 2575 | | .lhs = field_init_one, |
| 2468 | .lhs = inits[0], |
| 2576 | 2469 | .rhs = 0, |
| 2577 | 2470 | }, |
| 2578 | | }); |
| 2579 | | } |
| 2580 | | if (comma_one == null) { |
| 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, |
| 2471 | }), |
| 2472 | 2 => return p.addNode(.{ |
| 2473 | .tag = if (comma) .struct_init_dot_two_comma else .struct_init_dot_two, |
| 2588 | 2474 | .main_token = lbrace, |
| 2589 | 2475 | .data = .{ |
| 2590 | | .lhs = field_init_one, |
| 2591 | | .rhs = field_init_two, |
| 2476 | .lhs = inits[0], |
| 2477 | .rhs = inits[1], |
| 2592 | 2478 | }, |
| 2593 | | }); |
| 2594 | | } |
| 2595 | | if (comma_two == null) { |
| 2596 | | try p.warnExpected(.comma); |
| 2479 | }), |
| 2480 | else => { |
| 2481 | const span = try p.listToSpan(inits); |
| 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; |
| 2599 | | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 2600 | | |
| 2601 | | try p.scratch.appendSlice(p.gpa, &.{ field_init_one, field_init_two }); |
| 2492 | } |
| 2602 | 2493 | |
| 2603 | | while (true) { |
| 2604 | | const next = try p.expectFieldInit(); |
| 2605 | | assert(next != 0); |
| 2606 | | try p.scratch.append(p.gpa, next); |
| 2607 | | switch (p.token_tags[p.nextToken()]) { |
| 2608 | | .comma => { |
| 2609 | | if (p.eatToken(.r_brace)) |_| break; |
| 2610 | | continue; |
| 2611 | | }, |
| 2612 | | .r_brace => break, |
| 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 | | } |
| 2494 | while (true) { |
| 2495 | if (p.eatToken(.r_brace)) |_| break; |
| 2496 | const elem_init = try p.expectExpr(); |
| 2497 | try p.scratch.append(p.gpa, elem_init); |
| 2498 | switch (p.token_tags[p.tok_i]) { |
| 2499 | .comma => p.tok_i += 1, |
| 2500 | .r_brace => { p.tok_i += 1; break; }, |
| 2501 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), |
| 2502 | // Likely just a missing comma; give error but continue parsing. |
| 2503 | else => try p.warnExpected(.comma), |
| 2622 | 2504 | } |
| 2623 | | const span = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 2624 | | const trailing_comma = p.token_tags[p.tok_i - 2] == .comma; |
| 2625 | | return p.addNode(.{ |
| 2626 | | .tag = if (trailing_comma) .struct_init_dot_comma else .struct_init_dot, |
| 2505 | } |
| 2506 | const comma = (p.token_tags[p.tok_i - 2] == .comma); |
| 2507 | const inits = p.scratch.items[scratch_top..]; |
| 2508 | switch (inits.len) { |
| 2509 | 0 => return p.addNode(.{ |
| 2510 | .tag = .struct_init_dot_two, |
| 2627 | 2511 | .main_token = lbrace, |
| 2628 | 2512 | .data = .{ |
| 2629 | | .lhs = span.start, |
| 2630 | | .rhs = span.end, |
| 2513 | .lhs = 0, |
| 2514 | .rhs = 0, |
| 2631 | 2515 | }, |
| 2632 | | }); |
| 2633 | | } |
| 2634 | | |
| 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, |
| 2516 | }), |
| 2517 | 1 => return p.addNode(.{ |
| 2518 | .tag = if (comma) .array_init_dot_two_comma else .array_init_dot_two, |
| 2640 | 2519 | .main_token = lbrace, |
| 2641 | 2520 | .data = .{ |
| 2642 | | .lhs = elem_init_one, |
| 2521 | .lhs = inits[0], |
| 2643 | 2522 | .rhs = 0, |
| 2644 | 2523 | }, |
| 2645 | | }); |
| 2646 | | } |
| 2647 | | if (comma_one == null) { |
| 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, |
| 2524 | }), |
| 2525 | 2 => return p.addNode(.{ |
| 2526 | .tag = if (comma) .array_init_dot_two_comma else .array_init_dot_two, |
| 2655 | 2527 | .main_token = lbrace, |
| 2656 | 2528 | .data = .{ |
| 2657 | | .lhs = elem_init_one, |
| 2658 | | .rhs = elem_init_two, |
| 2529 | .lhs = inits[0], |
| 2530 | .rhs = inits[1], |
| 2659 | 2531 | }, |
| 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 | | }, |
| 2684 | | else => { |
| 2685 | | p.tok_i -= 1; |
| 2686 | | try p.warnExpected(.comma); |
| 2687 | | }, |
| 2688 | | } |
| 2689 | | } |
| 2690 | | const span = try p.listToSpan(p.scratch.items[scratch_top..]); |
| 2691 | | return p.addNode(.{ |
| 2692 | | .tag = if (p.token_tags[p.tok_i - 2] == .comma) .array_init_dot_comma else .array_init_dot, |
| 2693 | | .main_token = lbrace, |
| 2694 | | .data = .{ |
| 2695 | | .lhs = span.start, |
| 2696 | | .rhs = span.end, |
| 2532 | }), |
| 2533 | else => { |
| 2534 | const span = try p.listToSpan(inits); |
| 2535 | return p.addNode(.{ |
| 2536 | .tag = if (comma) .array_init_dot_comma else .array_init_dot, |
| 2537 | .main_token = lbrace, |
| 2538 | .data = .{ |
| 2539 | .lhs = span.start, |
| 2540 | .rhs = span.end, |
| 2541 | }, |
| 2542 | }); |
| 2697 | 2543 | }, |
| 2698 | | }); |
| 2544 | } |
| 2699 | 2545 | }, |
| 2700 | 2546 | else => return null_node, |
| 2701 | 2547 | }, |
| ... | ... | @@ -2703,37 +2549,16 @@ const Parser = struct { |
| 2703 | 2549 | .l_brace => { |
| 2704 | 2550 | const error_token = p.tok_i; |
| 2705 | 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 | 2552 | while (true) { |
| 2553 | if (p.eatToken(.r_brace)) |_| break; |
| 2719 | 2554 | const doc_comment = try p.eatDocComments(); |
| 2720 | 2555 | const identifier = try p.expectToken(.identifier); |
| 2721 | | switch (p.token_tags[p.nextToken()]) { |
| 2722 | | .comma => { |
| 2723 | | if (p.eatToken(.r_brace)) |_| break; |
| 2724 | | continue; |
| 2725 | | }, |
| 2726 | | .r_brace => break, |
| 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 | | }, |
| 2556 | switch (p.token_tags[p.tok_i]) { |
| 2557 | .comma => p.tok_i += 1, |
| 2558 | .r_brace => { p.tok_i += 1; break; }, |
| 2559 | .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace), |
| 2560 | // Likely just a missing comma; give error but continue parsing. |
| 2561 | else => try p.warnExpected(.comma), |
| 2737 | 2562 | } |
| 2738 | 2563 | } |
| 2739 | 2564 | return p.addNode(.{ |
| ... | ... | @@ -2926,12 +2751,10 @@ const Parser = struct { |
| 2926 | 2751 | try p.scratch.append(p.gpa, output_item); |
| 2927 | 2752 | switch (p.token_tags[p.tok_i]) { |
| 2928 | 2753 | .comma => p.tok_i += 1, |
| 2929 | | .colon, .r_paren, .r_brace, .r_bracket => break, // All possible delimiters. |
| 2930 | | else => { |
| 2931 | | // This is likely just a missing comma; |
| 2932 | | // give an error but continue parsing this list. |
| 2933 | | try p.warnExpected(.comma); |
| 2934 | | }, |
| 2754 | // All possible delimiters. |
| 2755 | .colon, .r_paren, .r_brace, .r_bracket => break, |
| 2756 | // Likely just a missing comma; give error but continue parsing. |
| 2757 | else => try p.warnExpected(.comma), |
| 2935 | 2758 | } |
| 2936 | 2759 | } |
| 2937 | 2760 | if (p.eatToken(.colon)) |_| { |
| ... | ... | @@ -2941,12 +2764,10 @@ const Parser = struct { |
| 2941 | 2764 | try p.scratch.append(p.gpa, input_item); |
| 2942 | 2765 | switch (p.token_tags[p.tok_i]) { |
| 2943 | 2766 | .comma => p.tok_i += 1, |
| 2944 | | .colon, .r_paren, .r_brace, .r_bracket => break, // All possible delimiters. |
| 2945 | | else => { |
| 2946 | | // This is likely just a missing comma; |
| 2947 | | // give an error but continue parsing this list. |
| 2948 | | try p.warnExpected(.comma); |
| 2949 | | }, |
| 2767 | // All possible delimiters. |
| 2768 | .colon, .r_paren, .r_brace, .r_bracket => break, |
| 2769 | // Likely just a missing comma; give error but continue parsing. |
| 2770 | else => try p.warnExpected(.comma), |
| 2950 | 2771 | } |
| 2951 | 2772 | } |
| 2952 | 2773 | if (p.eatToken(.colon)) |_| { |
| ... | ... | @@ -2954,11 +2775,8 @@ const Parser = struct { |
| 2954 | 2775 | switch (p.token_tags[p.tok_i]) { |
| 2955 | 2776 | .comma => p.tok_i += 1, |
| 2956 | 2777 | .colon, .r_paren, .r_brace, .r_bracket => break, |
| 2957 | | else => { |
| 2958 | | // This is likely just a missing comma; |
| 2959 | | // give an error but continue parsing this list. |
| 2960 | | try p.warnExpected(.comma); |
| 2961 | | }, |
| 2778 | // Likely just a missing comma; give error but continue parsing. |
| 2779 | else => try p.warnExpected(.comma), |
| 2962 | 2780 | } |
| 2963 | 2781 | } |
| 2964 | 2782 | } |
| ... | ... | @@ -3201,10 +3019,7 @@ const Parser = struct { |
| 3201 | 3019 | .tag = .switch_case, |
| 3202 | 3020 | .main_token = arrow_token, |
| 3203 | 3021 | .data = .{ |
| 3204 | | .lhs = try p.addExtra(Node.SubRange{ |
| 3205 | | .start = span.start, |
| 3206 | | .end = span.end, |
| 3207 | | }), |
| 3022 | .lhs = try p.addExtra(span), |
| 3208 | 3023 | .rhs = try p.expectAssignExpr(), |
| 3209 | 3024 | }, |
| 3210 | 3025 | }); |
| ... | ... | @@ -3563,19 +3378,12 @@ const Parser = struct { |
| 3563 | 3378 | } else if (p.token_tags[p.tok_i - 1] == .ellipsis3) { |
| 3564 | 3379 | if (varargs == .none) varargs = .seen; |
| 3565 | 3380 | } |
| 3566 | | switch (p.token_tags[p.nextToken()]) { |
| 3567 | | .comma => {}, |
| 3568 | | .r_paren => break, |
| 3569 | | .colon, .r_brace, .r_bracket => { |
| 3570 | | p.tok_i -= 1; |
| 3571 | | return p.failExpected(.r_paren); |
| 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 | | }, |
| 3381 | switch (p.token_tags[p.tok_i]) { |
| 3382 | .comma => p.tok_i += 1, |
| 3383 | .r_paren => { p.tok_i += 1; break; }, |
| 3384 | .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren), |
| 3385 | // Likely just a missing comma; give error but continue parsing. |
| 3386 | else => try p.warnExpected(.comma), |
| 3579 | 3387 | } |
| 3580 | 3388 | } |
| 3581 | 3389 | if (varargs == .nonfinal) { |
| ... | ... | @@ -3605,13 +3413,10 @@ const Parser = struct { |
| 3605 | 3413 | |
| 3606 | 3414 | switch (p.token_tags[p.tok_i]) { |
| 3607 | 3415 | .comma => p.tok_i += 1, |
| 3608 | | // all possible delimiters |
| 3416 | // All possible delimiters. |
| 3609 | 3417 | .colon, .r_paren, .r_brace, .r_bracket => break, |
| 3610 | | else => { |
| 3611 | | // This is likely just a missing comma; |
| 3612 | | // give an error but continue parsing this list. |
| 3613 | | try p.warnExpected(.comma); |
| 3614 | | }, |
| 3418 | // Likely just a missing comma; give error but continue parsing. |
| 3419 | else => try p.warnExpected(.comma), |
| 3615 | 3420 | } |
| 3616 | 3421 | } |
| 3617 | 3422 | return p.listToSpan(p.scratch.items[scratch_top..]); |
| ... | ... | @@ -3636,117 +3441,58 @@ const Parser = struct { |
| 3636 | 3441 | }, |
| 3637 | 3442 | }); |
| 3638 | 3443 | } |
| 3639 | | if (p.eatToken(.r_paren)) |_| { |
| 3640 | | return p.addNode(.{ |
| 3444 | const scratch_top = p.scratch.items.len; |
| 3445 | defer p.scratch.shrinkRetainingCapacity(scratch_top); |
| 3446 | while (true) { |
| 3447 | if (p.eatToken(.r_paren)) |_| break; |
| 3448 | const param = try p.expectExpr(); |
| 3449 | try p.scratch.append(p.gpa, param); |
| 3450 | switch (p.token_tags[p.tok_i]) { |
| 3451 | .comma => p.tok_i += 1, |
| 3452 | .r_paren => { p.tok_i += 1; break; }, |
| 3453 | // Likely just a missing comma; give error but continue parsing. |
| 3454 | else => try p.warnExpected(.comma), |
| 3455 | } |
| 3456 | } |
| 3457 | const comma = (p.token_tags[p.tok_i - 2] == .comma); |
| 3458 | const params = p.scratch.items[scratch_top..]; |
| 3459 | switch (params.len) { |
| 3460 | 0 => return p.addNode(.{ |
| 3641 | 3461 | .tag = .builtin_call_two, |
| 3642 | 3462 | .main_token = builtin_token, |
| 3643 | 3463 | .data = .{ |
| 3644 | 3464 | .lhs = 0, |
| 3645 | 3465 | .rhs = 0, |
| 3646 | 3466 | }, |
| 3647 | | }); |
| 3648 | | } |
| 3649 | | const param_one = try p.expectExpr(); |
| 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, |
| 3467 | }), |
| 3468 | 1 => return p.addNode(.{ |
| 3469 | .tag = if (comma) .builtin_call_two_comma else .builtin_call_two, |
| 3665 | 3470 | .main_token = builtin_token, |
| 3666 | 3471 | .data = .{ |
| 3667 | | .lhs = param_one, |
| 3472 | .lhs = params[0], |
| 3668 | 3473 | .rhs = 0, |
| 3669 | 3474 | }, |
| 3670 | 3475 | }), |
| 3671 | | else => { |
| 3672 | | // This is likely just a missing comma; |
| 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, |
| 3476 | 2 => return p.addNode(.{ |
| 3477 | .tag = if (comma) .builtin_call_two_comma else .builtin_call_two, |
| 3694 | 3478 | .main_token = builtin_token, |
| 3695 | 3479 | .data = .{ |
| 3696 | | .lhs = param_one, |
| 3697 | | .rhs = param_two, |
| 3480 | .lhs = params[0], |
| 3481 | .rhs = params[1], |
| 3698 | 3482 | }, |
| 3699 | 3483 | }), |
| 3700 | 3484 | else => { |
| 3701 | | // This is likely just a missing comma; |
| 3702 | | // give an error but continue parsing this list. |
| 3703 | | p.tok_i -= 1; |
| 3704 | | try p.warnExpected(.comma); |
| 3485 | const span = try p.listToSpan(params); |
| 3486 | return p.addNode(.{ |
| 3487 | .tag = if (comma) .builtin_call_comma else .builtin_call, |
| 3488 | .main_token = builtin_token, |
| 3489 | .data = .{ |
| 3490 | .lhs = span.start, |
| 3491 | .rhs = span.end, |
| 3492 | }, |
| 3493 | }); |
| 3705 | 3494 | }, |
| 3706 | 3495 | } |
| 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 | 3496 | } |
| 3751 | 3497 | |
| 3752 | 3498 | // string literal or multiline string literal |