@@ -11,6 +11,7 @@ const IdentRegex = /[_\p{XID_Start}][\p{XID_Continue}]*/u;
1111
1212const PREC = {
1313 call : 15 ,
14+ field : 14 ,
1415 as : 11 ,
1516 assign : 0 ,
1617 semi : - 1 ,
@@ -65,7 +66,6 @@ module.exports = grammar({
6566 $ . return_expr ,
6667 $ . break_expr ,
6768 $ . cont_expr ,
68- $ . labeled ,
6969 $ . block ,
7070 $ . if_expr ,
7171 $ . while_expr ,
@@ -187,69 +187,147 @@ module.exports = grammar({
187187 field ( 'ty' , $ . _type ) ,
188188 ) ) ,
189189
190- return_expr : $ => prec . right ( choice (
190+ return_expr : $ => choice (
191+ $ . _prefix_return ,
192+ $ . _suffix_return ,
193+ ) ,
194+
195+ _prefix_return : $ => prec . right ( choice (
191196 seq (
192197 'return' ,
193198 field ( 'val' , $ . _expr ) ,
194199 ) ,
195200 'return' ,
196201 ) ) ,
197202
198- break_expr : $ => prec . right ( seq (
203+ _suffix_return : $ => prec ( PREC . field , seq (
204+ field ( 'val' , $ . _expr ) ,
205+ '.' ,
206+ 'return' ,
207+ ) ) ,
208+
209+ break_expr : $ => choice (
210+ $ . _prefix_break ,
211+ $ . _suffix_break ,
212+ ) ,
213+
214+ _prefix_break : $ => prec . right ( seq (
199215 'break' ,
200216 field ( 'lab' , optional ( $ . label ) ) ,
201217 field ( 'val' , $ . _expr ) ,
202218 ) ) ,
203219
220+ _suffix_break : $ => prec ( PREC . field , seq (
221+ field ( 'val' , $ . _expr ) ,
222+ '.' ,
223+ 'break' ,
224+ field ( 'lab' , optional ( $ . label ) ) ,
225+ ) ) ,
226+
204227 cont_expr : $ => seq (
205228 'cont' ,
206229 field ( 'lab' , optional ( $ . label ) ) ,
207230 ) ,
208231
209- if_expr : $ => seq (
232+ if_expr : $ => choice (
233+ $ . _prefix_if ,
234+ $ . _suffix_if ,
235+ ) ,
236+
237+ _prefix_if : $ => seq (
210238 'if' ,
211239 field ( 'cond' , $ . _expr ) ,
212240 field ( 'body' , $ . block ) ,
213- optional ( field ( 'el' , $ . _else_clause ) ) ,
241+ optional ( $ . _else_clause ) ,
214242 ) ,
215243
244+ _suffix_if : $ => prec ( PREC . field , seq (
245+ field ( 'cond' , $ . _expr ) ,
246+ '.' ,
247+ 'if' ,
248+ field ( 'body' , $ . block ) ,
249+ optional ( $ . _else_clause ) ,
250+ ) ) ,
251+
216252 _else_clause : $ => seq (
217253 'else' ,
218- choice (
254+ field ( 'el' , choice (
219255 $ . block ,
220- $ . if_expr ,
221- ) ,
256+ alias ( $ . _prefix_if , $ . if_expr ) ,
257+ ) ) ,
258+ ) ,
259+
260+ while_expr : $ => choice (
261+ $ . _prefix_while ,
262+ $ . _suffix_while ,
222263 ) ,
223264
224- while_expr : $ => seq (
265+ _prefix_while : $ => seq (
266+ optional ( seq (
267+ field ( 'lab' , $ . label ) ,
268+ ':' ,
269+ ) ) ,
225270 'while' ,
226271 field ( 'cond' , $ . _expr ) ,
227272 field ( 'body' , $ . block ) ,
228- optional ( field ( 'el' , $ . _loop_else_clause ) ) ,
273+ optional ( $ . _loop_else_clause ) ,
229274 ) ,
230275
231- for_expr : $ => seq (
276+ _suffix_while : $ => prec ( PREC . field , seq (
277+ field ( 'cond' , $ . _expr ) ,
278+ '.' ,
279+ optional ( seq (
280+ field ( 'lab' , $ . label ) ,
281+ ':' ,
282+ ) ) ,
283+ 'while' ,
284+ field ( 'body' , $ . block ) ,
285+ optional ( $ . _loop_else_clause ) ,
286+ ) ) ,
287+
288+ for_expr : $ => choice (
289+ $ . _prefix_for ,
290+ $ . _suffix_for ,
291+ ) ,
292+
293+ _prefix_for : $ => seq (
294+ optional ( seq (
295+ field ( 'lab' , $ . label ) ,
296+ ':' ,
297+ ) ) ,
232298 'for' ,
233299 field ( 'pat' , $ . _pattern ) ,
234300 'in' ,
235301 field ( 'range' , $ . _expr ) ,
236302 field ( 'body' , $ . block ) ,
237- optional ( field ( 'el' , $ . _loop_else_clause ) ) ,
303+ optional ( $ . _loop_else_clause ) ,
238304 ) ,
239305
306+ _suffix_for : $ => prec ( PREC . field , seq (
307+ field ( 'range' , $ . _expr ) ,
308+ '.' ,
309+ optional ( seq (
310+ field ( 'lab' , $ . label ) ,
311+ ':' ,
312+ ) ) ,
313+ 'for' ,
314+ field ( 'pat' , $ . _pattern ) ,
315+ 'in' ,
316+ field ( 'body' , $ . block ) ,
317+ optional ( $ . _loop_else_clause ) ,
318+ ) ) ,
319+
240320 _loop_else_clause : $ => seq (
241321 'else' ,
242- $ . block ,
322+ field ( 'el' , $ . block ) ,
243323 ) ,
244324
245- labeled : $ => seq (
246- field ( 'lab' , $ . label ) ,
247- ':' ,
248- field ( 'block' , choice (
249- $ . block ,
250- $ . while_expr ,
251- $ . for_expr ,
325+ labeled_block : $ => seq (
326+ optional ( seq (
327+ field ( 'lab' , $ . label ) ,
328+ ':' ,
252329 ) ) ,
330+ field ( 'block' , $ . block ) ,
253331 ) ,
254332
255333 block : $ => seq (
0 commit comments