Skip to content

Commit 9de33a4

Browse files
committed
Add support for if statements inline within lambdas
1 parent 0b5cda1 commit 9de33a4

2 files changed

Lines changed: 47 additions & 1 deletion

File tree

grammar.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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",

test/corpus/lambdas.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,3 +462,29 @@ func x():
462462
(pass_statement))))))
463463
(string)))))))
464464

465+
================================
466+
Lambda with inline if statement
467+
================================
468+
469+
visibility_changed.connect(func() -> void: if visible: _update())
470+
471+
---
472+
473+
(source
474+
(expression_statement
475+
(attribute
476+
(identifier)
477+
(attribute_call
478+
(identifier)
479+
arguments: (arguments
480+
(lambda
481+
parameters: (parameters)
482+
return_type: (type (identifier))
483+
body: (body
484+
(if_statement
485+
condition: (identifier)
486+
body: (body
487+
(expression_statement
488+
(call
489+
(identifier)
490+
arguments: (arguments))))))))))))

0 commit comments

Comments
 (0)