Skip to content

Commit 4d0d729

Browse files
committed
Add support for binding the result of an indented sequence to a name
1 parent 22a9ef7 commit 4d0d729

File tree

4 files changed

+44
-0
lines changed

4 files changed

+44
-0
lines changed

docs/language.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,25 @@ ignored. If the vector is shorter, then the the additional names will be bound
559559
to items wrapped around from the start again. If the vector is `null` then all
560560
names will be bound to `null`.
561561

562+
A let binding may also bind one or more names to the result of evaluating an
563+
indented "body" sequence of expressions. For example:
564+
565+
```flitter
566+
let foo=
567+
!foo bar=12
568+
!baz
569+
```
570+
571+
A let binding of this form may only have one name (or semicolon-separated list
572+
of names for an unpacked vector binding) followed by an `=`, a newline and then
573+
an indented sequence of expressions. This *sequence let* may contain any
574+
multi-line sequence expressions, the same as the body of a function or a loop.
575+
This is particularly useful for binding nested node structures to a name.
576+
577+
If a semicolon-separated name list is provided in a sequence let, then the
578+
names will be bound to values following the unpacking logic described above,
579+
with the vector formed from the indented body being the source vector.
580+
562581
Names introduced with a `let` can redefine engine-supplied values, like `beat`,
563582
and built-ins, like `sin`.
564583

src/flitter/language/grammar.lark

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ sequence : expressions
2727
expressions : expression* let_expression? -> tuple
2828

2929
let_expression : "let" multiline_bindings sequence -> let
30+
| "let" name_list "=" _NL _INDENT sequence _DEDENT sequence -> sequence_let
3031
| function sequence -> let_function
3132
| "import" name_list "from" composition _NL sequence -> let_import
3233

src/flitter/language/parser.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ def template_call(self, function, bindings, sequence):
9898
def let_function(self, function, sequence):
9999
return tree.Let((tree.PolyBinding((function.name,), function),), sequence)
100100

101+
def sequence_let(self, names, value, sequence):
102+
return tree.Let((tree.PolyBinding(names, value),), sequence)
103+
101104
def anonymous_function(self, parameters, body):
102105
return tree.Function('<anon>', parameters, body)
103106

tests/test_language.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,27 @@ def test_contains(self):
372372
!foo x=1 y=1 z=0
373373
""", x=Vector((4, 5, 6)), y=Vector.range(10))
374374

375+
def test_sequence_let(self):
376+
self.assertCodeOutput(
377+
"""
378+
let foo;bar =
379+
!foo x=1
380+
!bar
381+
!baz
382+
!bar b=2
383+
384+
!frob
385+
bar
386+
foo
387+
""",
388+
"""
389+
!frob
390+
!bar b=2
391+
!foo x=1
392+
!bar
393+
!baz
394+
""")
395+
375396

376397
class ScriptTest(utils.TestCase):
377398
"""

0 commit comments

Comments
 (0)