Skip to content

Commit 469968f

Browse files
committed
Additional simplifier rules for Lets over Sequences
Pull any Literal out of the head of a Let Sequence and combine any following nested Let.
1 parent f5fa438 commit 469968f

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
lines changed

src/flitter/language/tree.pyx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,10 +1497,18 @@ cdef class Let(Expression):
14971497
sbody = (<Let>sbody).body
14981498
resimplify = True
14991499
touched = True
1500-
if not touched:
1501-
return self
15021500
if remaining:
1503-
sbody = Let(tuple(remaining), sbody)
1501+
if type(sbody) is Sequence and type((<Sequence>sbody).expressions[0]) is Literal:
1502+
if len((<Sequence>sbody).expressions) > 2:
1503+
sbody = Sequence(((<Sequence>sbody).expressions[0], Let(tuple(remaining), Sequence((<Sequence>sbody).expressions[1:]))))
1504+
else:
1505+
if type((<Sequence>sbody).expressions[1]) is Let:
1506+
resimplify = True
1507+
sbody = Sequence(((<Sequence>sbody).expressions[0], Let(tuple(remaining), (<Sequence>sbody).expressions[1])))
1508+
elif touched:
1509+
sbody = Let(tuple(remaining), sbody)
1510+
else:
1511+
return self
15041512
if resimplify:
15051513
return sbody._simplify(context)
15061514
return sbody

tests/test_language.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,13 @@ def assertCodeOutput(self, code, output, with_errors=None, skip_simplifier=False
111111
while not isinstance(expr, Literal):
112112
if isinstance(expr, Let):
113113
expr = expr.body
114-
elif isinstance(expr, Sequence) and len(expr.expressions) == 2 and isinstance(expr.expressions[1], Export):
115-
expr = expr.expressions[0]
114+
elif isinstance(expr, Sequence) and len(expr.expressions) == 2:
115+
if isinstance(expr.expressions[1], Export):
116+
expr = expr.expressions[0]
117+
elif isinstance(expr.expressions[1], Let) and isinstance(expr.expressions[1].body, Export):
118+
expr = expr.expressions[0]
119+
else:
120+
break
116121
else:
117122
break
118123
if isinstance(expr, Export):

tests/test_simplifier.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,14 @@ def test_unused_let_export(self):
10381038
Let((PolyBinding(('x',), Add(Name('z'), Literal(1))),), Export()),
10391039
dynamic={'z'}, unbound={'z', None})
10401040

1041+
def test_sequence_literal(self):
1042+
"""Literals at head of a sequence body are pushed out of the let"""
1043+
self.assertSimplifiesTo(Let((PolyBinding(('x',), Add(Name('y'), Literal(1))),), Sequence((Literal(1), Name('x')))),
1044+
Sequence((Literal(1), Let((PolyBinding(('x',), Add(Name('y'), Literal(1))),), Name('x')))), dynamic={'y'})
1045+
self.assertSimplifiesTo(Let((PolyBinding(('x',), Add(Name('y'), Literal(1))),), Sequence((Literal(1), Name('x'), Name('y')))),
1046+
Sequence((Literal(1), Let((PolyBinding(('x',), Add(Name('y'), Literal(1))),), Sequence((Name('x'), Name('y')))))),
1047+
dynamic={'y'})
1048+
10411049

10421050
class TestCall(SimplifierTestCase):
10431051
def test_dynamic(self):

0 commit comments

Comments
 (0)