Skip to content

Commit b623949

Browse files
authored
Merge pull request #360 from boriel/bugfix/optimization_wrong
Ensure function calls on some optimizations cases
2 parents e228bcb + 5f4aa5e commit b623949

File tree

5 files changed

+122
-9
lines changed

5 files changed

+122
-9
lines changed

api/optimize.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ def visit_FUNCTION(self, node):
148148
def visit_LET(self, node):
149149
if self.O_LEVEL > 1 and not node.children[0].accessed:
150150
warning_not_used(node.children[0].lineno, node.children[0].name)
151-
yield self.NOP
151+
yield symbols.BLOCK(*list(self.filter_inorder(node.children[1], lambda x: isinstance(x, symbols.CALL))))
152152
else:
153153
yield (yield self.generic_visit(node))
154154

ast_/ast.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
# the GNU General License
1010
# ----------------------------------------------------------------------
1111

12+
from typing import Callable, Any
1213
import types
1314
from .tree import Tree
1415

@@ -50,5 +51,16 @@ def _visit(self, node):
5051
return meth(node)
5152

5253
@staticmethod
53-
def generic_visit(node):
54+
def generic_visit(node: Ast):
5455
raise RuntimeError("No {}() method defined".format('visit_' + node.token))
56+
57+
def filter_inorder(self, node, filter_func: Callable[[Any], bool]):
58+
""" Visit the tree inorder, but only those that return true for filter
59+
"""
60+
stack = [node]
61+
while stack:
62+
node = stack.pop()
63+
if filter_func(node):
64+
yield self.visit(node)
65+
elif isinstance(node, Ast):
66+
stack.extend(node.children[::-1])

ast_/tree.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,22 @@ class Tree:
2929
class ChildrenList:
3030
def __init__(self, node: 'Tree'):
3131
assert isinstance(node, Tree)
32-
self.node = node # Node having this children
32+
self.parent = node # Node having this children
3333
self._children = []
3434

3535
def __getitem__(self, key):
3636
if isinstance(key, int):
3737
return self._children[key]
3838

39-
result = Tree.ChildrenList(self.node)
39+
result = Tree.ChildrenList(self.parent)
4040
for x in self._children[key]:
4141
result.append(x)
4242
return result
4343

4444
def __setitem__(self, key, value):
4545
assert value is None or isinstance(value, Tree)
4646
if value is not None:
47-
value.parent = self.node
47+
value.parent = self.parent
4848
self._children[key] = value
4949

5050
def __delitem__(self, key):
@@ -53,12 +53,12 @@ def __delitem__(self, key):
5353

5454
def append(self, value):
5555
assert isinstance(value, Tree)
56-
value.parent = self.node
56+
value.parent = self.parent
5757
self._children.append(value)
5858

5959
def insert(self, pos, value):
6060
assert isinstance(value, Tree)
61-
value.parent = self.node
61+
value.parent = self.parent
6262
self._children.insert(pos, value)
6363

6464
def pop(self, pos=-1):
@@ -73,15 +73,15 @@ def __add__(self, other):
7373
if not isinstance(other, Tree.ChildrenList):
7474
assert isinstance(other, collections.Container)
7575

76-
result = Tree.ChildrenList(self.node)
76+
result = Tree.ChildrenList(self.parent)
7777
for x in self:
7878
result.append(x)
7979
for x in other:
8080
result.append(x)
8181
return result
8282

8383
def __repr__(self):
84-
return "%s:%s" % (self.node.__repr__(), str([x.__repr__() for x in self._children]))
84+
return "%s:%s" % (self.parent.__repr__(), str([x.__repr__() for x in self._children]))
8585

8686
def __init__(self):
8787
self._children = Tree.ChildrenList(self)

tests/functional/opt2_unused_var.asm

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
org 32768
2+
__START_PROGRAM:
3+
di
4+
push ix
5+
push iy
6+
exx
7+
push hl
8+
exx
9+
ld hl, 0
10+
add hl, sp
11+
ld (__CALL_BACK__), hl
12+
ei
13+
call _Check
14+
ld hl, 0
15+
call __PAUSE
16+
ld hl, 0
17+
ld b, h
18+
ld c, l
19+
__END_PROGRAM:
20+
di
21+
ld hl, (__CALL_BACK__)
22+
ld sp, hl
23+
exx
24+
pop hl
25+
pop iy
26+
pop ix
27+
exx
28+
ei
29+
ret
30+
__CALL_BACK__:
31+
DEFW 0
32+
_TestPrint:
33+
push ix
34+
ld ix, 0
35+
add ix, sp
36+
ld a, (ix+7)
37+
ld (0), a
38+
ld a, (ix+5)
39+
ld (0), a
40+
_TestPrint__leave:
41+
ld sp, ix
42+
pop ix
43+
exx
44+
pop hl
45+
pop bc
46+
ex (sp), hl
47+
exx
48+
ret
49+
_Check:
50+
push ix
51+
ld ix, 0
52+
add ix, sp
53+
ld a, 10
54+
push af
55+
ld a, 5
56+
push af
57+
call _TestPrint
58+
push bc
59+
push de
60+
push af
61+
ld a, 11
62+
push af
63+
ld a, 6
64+
push af
65+
call _TestPrint
66+
push bc
67+
push de
68+
push af
69+
_Check__leave:
70+
ld sp, ix
71+
pop ix
72+
ret
73+
#line 1 "pause.asm"
74+
; The PAUSE statement (Calling the ROM)
75+
__PAUSE:
76+
ld b, h
77+
ld c, l
78+
jp 1F3Dh ; PAUSE_1
79+
#line 62 "opt2_unused_var.bas"
80+
ZXBASIC_USER_DATA:
81+
; Defines DATA END --> HEAP size is 0
82+
ZXBASIC_USER_DATA_END:
83+
; Defines USER DATA Length in bytes
84+
ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA
85+
END

tests/functional/opt2_unused_var.bas

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
' BugTest
2+
Check()
3+
pause 0
4+
5+
6+
function TestPrint(y as ubyte, x as ubyte)
7+
poke 0, x
8+
poke 0, y
9+
end function
10+
11+
12+
SUB Check()
13+
dim y as ubyte
14+
y=TestPrint(5,10) * 5 + (4 + TestPrint(6, 11))
15+
end sub
16+

0 commit comments

Comments
 (0)