Skip to content

Commit 6629acb

Browse files
authored
Merge pull request #608 from boriel/fix/bad_optimization
fix: fix optimization for FOR loop
2 parents 86a32df + 66abcf2 commit 6629acb

File tree

5 files changed

+205
-10
lines changed

5 files changed

+205
-10
lines changed

src/api/optimize.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,9 @@ def visit_IF(self, node):
407407
yield node
408408

409409
def visit_WHILE(self, node):
410-
expr_ = yield node.children[0]
411-
body_ = yield node.children[1]
410+
node = yield self.generic_visit(node)
411+
expr_ = node.children[0]
412+
body_ = node.children[1]
412413

413414
if self.O_LEVEL >= 1:
414415
if chk.is_number(expr_) and not expr_.value and not chk.is_block_accessed(body_):
@@ -420,10 +421,12 @@ def visit_WHILE(self, node):
420421
yield node
421422

422423
def visit_FOR(self, node):
423-
from_ = yield node.children[1]
424-
to_ = yield node.children[2]
425-
step_ = yield node.children[3]
426-
body_ = yield node.children[4]
424+
node = yield self.generic_visit(node)
425+
426+
from_ = node.children[1]
427+
to_ = node.children[2]
428+
step_ = node.children[3]
429+
body_ = node.children[4]
427430

428431
if self.O_LEVEL > 0 and chk.is_number(from_, to_, step_) and not chk.is_block_accessed(body_):
429432
if from_ > to_ and step_ > 0:
@@ -433,8 +436,6 @@ def visit_FOR(self, node):
433436
yield self.NOP
434437
return
435438

436-
for i, child in enumerate((from_, to_, step_, body_), start=1):
437-
node.children[i] = child
438439
yield node
439440

440441
# TODO: ignore unused labels
@@ -445,8 +446,8 @@ def _visit_LABEL(self, node):
445446
yield node
446447

447448
def generic_visit(self, node: symbols.SYMBOL):
448-
for i in range(len(node.children)):
449-
node.children[i] = yield ToVisit(node.children[i])
449+
for i, child in enumerate(node.children):
450+
node.children[i] = yield ToVisit(child)
450451

451452
yield node
452453

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
org 32768
2+
.core.__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 (.core.__CALL_BACK__), hl
12+
ei
13+
jp .core.__MAIN_PROGRAM__
14+
.core.__CALL_BACK__:
15+
DEFW 0
16+
.core.ZXBASIC_USER_DATA:
17+
; Defines USER DATA Length in bytes
18+
.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA
19+
.core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN
20+
.core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA
21+
.core.ZXBASIC_USER_DATA_END:
22+
.core.__MAIN_PROGRAM__:
23+
call _main
24+
ld hl, 0
25+
ld b, h
26+
ld c, l
27+
.core.__END_PROGRAM:
28+
di
29+
ld hl, (.core.__CALL_BACK__)
30+
ld sp, hl
31+
exx
32+
pop hl
33+
pop iy
34+
pop ix
35+
exx
36+
ei
37+
ret
38+
_saludar:
39+
push ix
40+
ld ix, 0
41+
add ix, sp
42+
ld l, (ix+4)
43+
ld h, (ix+5)
44+
inc hl
45+
_saludar__leave:
46+
ld sp, ix
47+
pop ix
48+
exx
49+
pop hl
50+
ex (sp), hl
51+
exx
52+
ret
53+
_main:
54+
push ix
55+
ld ix, 0
56+
add ix, sp
57+
ld hl, 0
58+
push hl
59+
ld (ix-2), 1
60+
ld (ix-1), 0
61+
jp .LABEL.__LABEL0
62+
.LABEL.__LABEL3:
63+
ld l, (ix-2)
64+
ld h, (ix-1)
65+
push hl
66+
call _saludar
67+
ld l, (ix-2)
68+
ld h, (ix-1)
69+
inc hl
70+
ld (ix-2), l
71+
ld (ix-1), h
72+
.LABEL.__LABEL0:
73+
ld l, (ix-2)
74+
ld h, (ix-1)
75+
ex de, hl
76+
ld hl, 2
77+
or a
78+
sbc hl, de
79+
jp nc, .LABEL.__LABEL3
80+
_main__leave:
81+
ld sp, ix
82+
pop ix
83+
ret
84+
;; --- end of user code ---
85+
END
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
main()
2+
3+
function saludar(x as Uinteger) as Uinteger
4+
return x + 1
5+
end function
6+
7+
sub main()
8+
dim i, result as uinteger
9+
for i = 1 to 2
10+
result = saludar(i)
11+
next
12+
end sub
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
org 32768
2+
.core.__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 (.core.__CALL_BACK__), hl
12+
ei
13+
jp .core.__MAIN_PROGRAM__
14+
.core.__CALL_BACK__:
15+
DEFW 0
16+
.core.ZXBASIC_USER_DATA:
17+
; Defines USER DATA Length in bytes
18+
.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA
19+
.core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN
20+
.core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA
21+
.core.ZXBASIC_USER_DATA_END:
22+
.core.__MAIN_PROGRAM__:
23+
call _main
24+
ld hl, 0
25+
ld b, h
26+
ld c, l
27+
.core.__END_PROGRAM:
28+
di
29+
ld hl, (.core.__CALL_BACK__)
30+
ld sp, hl
31+
exx
32+
pop hl
33+
pop iy
34+
pop ix
35+
exx
36+
ei
37+
ret
38+
_saludar:
39+
push ix
40+
ld ix, 0
41+
add ix, sp
42+
ld l, (ix+4)
43+
ld h, (ix+5)
44+
inc hl
45+
_saludar__leave:
46+
ld sp, ix
47+
pop ix
48+
exx
49+
pop hl
50+
ex (sp), hl
51+
exx
52+
ret
53+
_main:
54+
push ix
55+
ld ix, 0
56+
add ix, sp
57+
ld hl, 0
58+
push hl
59+
ld (ix-2), 0
60+
ld (ix-1), 0
61+
.LABEL.__LABEL0:
62+
ld l, (ix-2)
63+
ld h, (ix-1)
64+
ld de, 2
65+
or a
66+
sbc hl, de
67+
jp nc, _main__leave
68+
ld l, (ix-2)
69+
ld h, (ix-1)
70+
push hl
71+
call _saludar
72+
ld l, (ix-2)
73+
ld h, (ix-1)
74+
inc hl
75+
ld (ix-2), l
76+
ld (ix-1), h
77+
jp .LABEL.__LABEL0
78+
_main__leave:
79+
ld sp, ix
80+
pop ix
81+
ret
82+
;; --- end of user code ---
83+
END
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
main()
2+
3+
function saludar(x as Uinteger) as Uinteger
4+
return x + 1
5+
end function
6+
7+
sub main()
8+
dim i, result as uinteger
9+
i = 0
10+
while i < 2
11+
result = saludar(i)
12+
i = i + 1
13+
end while
14+
end sub

0 commit comments

Comments
 (0)