@@ -203,12 +203,21 @@ module.exports = grammar({
203203 body : ( $ ) =>
204204 choice (
205205 $ . _simple_statements ,
206+ $ . _inline_compound_statement ,
206207 $ . _newline ,
207208 $ . _body_end ,
208209 seq ( $ . _indent , repeat ( $ . _statement ) , choice ( $ . _body_end , $ . _dedent ) ) ,
209210 ) ,
210211
211- // Simple statements
212+ // Compound statements that are valid inline (same line after `:`). elif and
213+ // else are not supported by the official compiler (tested in Godot 4.6)
214+ _inline_compound_statement : ( $ ) =>
215+ choice (
216+ alias ( $ . _inline_if_statement , $ . if_statement ) ,
217+ $ . for_statement ,
218+ $ . while_statement ,
219+ $ . match_statement ,
220+ ) ,
212221
213222 _simple_statements : ( $ ) =>
214223 seq (
@@ -403,6 +412,17 @@ module.exports = grammar({
403412 optional ( field ( "alternative" , $ . else_clause ) ) ,
404413 ) ,
405414
415+ // This rule is used to implement inline if statements like `if condition:
416+ // do_something()`. elif and else blocks are not supported inline, e.g. if
417+ // true: pass elif false: pass does not parse. That's why this rule exists.
418+ // Without it, on top of being off spec, the parser gets confused as inline
419+ // cases are ambiguous (if a: if b: elif c -> what does elif belong to?).
420+ //
421+ // We alias this as if_statement so that the AST node type is the same
422+ // whether it's an inline if or a block.
423+ _inline_if_statement : ( $ ) =>
424+ seq ( "if" , field ( "condition" , $ . _expression ) , ":" , field ( "body" , $ . body ) ) ,
425+
406426 elif_clause : ( $ ) =>
407427 seq (
408428 "elif" ,
0 commit comments