Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions src/api/optimize.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,8 +407,9 @@ def visit_IF(self, node):
yield node

def visit_WHILE(self, node):
expr_ = yield node.children[0]
body_ = yield node.children[1]
node = yield self.generic_visit(node)
expr_ = node.children[0]
body_ = node.children[1]

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

def visit_FOR(self, node):
from_ = yield node.children[1]
to_ = yield node.children[2]
step_ = yield node.children[3]
body_ = yield node.children[4]
node = yield self.generic_visit(node)

from_ = node.children[1]
to_ = node.children[2]
step_ = node.children[3]
body_ = node.children[4]

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

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

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

def generic_visit(self, node: symbols.SYMBOL):
for i in range(len(node.children)):
node.children[i] = yield ToVisit(node.children[i])
for i, child in enumerate(node.children):
node.children[i] = yield ToVisit(child)

yield node

Expand Down
85 changes: 85 additions & 0 deletions tests/functional/zx48k/opt2_for_funcall.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
org 32768
.core.__START_PROGRAM:
di
push ix
push iy
exx
push hl
exx
ld hl, 0
add hl, sp
ld (.core.__CALL_BACK__), hl
ei
jp .core.__MAIN_PROGRAM__
.core.__CALL_BACK__:
DEFW 0
.core.ZXBASIC_USER_DATA:
; Defines USER DATA Length in bytes
.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA
.core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN
.core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA
.core.ZXBASIC_USER_DATA_END:
.core.__MAIN_PROGRAM__:
call _main
ld hl, 0
ld b, h
ld c, l
.core.__END_PROGRAM:
di
ld hl, (.core.__CALL_BACK__)
ld sp, hl
exx
pop hl
pop iy
pop ix
exx
ei
ret
_saludar:
push ix
ld ix, 0
add ix, sp
ld l, (ix+4)
ld h, (ix+5)
inc hl
_saludar__leave:
ld sp, ix
pop ix
exx
pop hl
ex (sp), hl
exx
ret
_main:
push ix
ld ix, 0
add ix, sp
ld hl, 0
push hl
ld (ix-2), 1
ld (ix-1), 0
jp .LABEL.__LABEL0
.LABEL.__LABEL3:
ld l, (ix-2)
ld h, (ix-1)
push hl
call _saludar
ld l, (ix-2)
ld h, (ix-1)
inc hl
ld (ix-2), l
ld (ix-1), h
.LABEL.__LABEL0:
ld l, (ix-2)
ld h, (ix-1)
ex de, hl
ld hl, 2
or a
sbc hl, de
jp nc, .LABEL.__LABEL3
_main__leave:
ld sp, ix
pop ix
ret
;; --- end of user code ---
END
12 changes: 12 additions & 0 deletions tests/functional/zx48k/opt2_for_funcall.bas
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
main()

function saludar(x as Uinteger) as Uinteger
return x + 1
end function

sub main()
dim i, result as uinteger
for i = 1 to 2
result = saludar(i)
next
end sub
83 changes: 83 additions & 0 deletions tests/functional/zx48k/opt2_while_funcall.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
org 32768
.core.__START_PROGRAM:
di
push ix
push iy
exx
push hl
exx
ld hl, 0
add hl, sp
ld (.core.__CALL_BACK__), hl
ei
jp .core.__MAIN_PROGRAM__
.core.__CALL_BACK__:
DEFW 0
.core.ZXBASIC_USER_DATA:
; Defines USER DATA Length in bytes
.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA
.core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN
.core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA
.core.ZXBASIC_USER_DATA_END:
.core.__MAIN_PROGRAM__:
call _main
ld hl, 0
ld b, h
ld c, l
.core.__END_PROGRAM:
di
ld hl, (.core.__CALL_BACK__)
ld sp, hl
exx
pop hl
pop iy
pop ix
exx
ei
ret
_saludar:
push ix
ld ix, 0
add ix, sp
ld l, (ix+4)
ld h, (ix+5)
inc hl
_saludar__leave:
ld sp, ix
pop ix
exx
pop hl
ex (sp), hl
exx
ret
_main:
push ix
ld ix, 0
add ix, sp
ld hl, 0
push hl
ld (ix-2), 0
ld (ix-1), 0
.LABEL.__LABEL0:
ld l, (ix-2)
ld h, (ix-1)
ld de, 2
or a
sbc hl, de
jp nc, _main__leave
ld l, (ix-2)
ld h, (ix-1)
push hl
call _saludar
ld l, (ix-2)
ld h, (ix-1)
inc hl
ld (ix-2), l
ld (ix-1), h
jp .LABEL.__LABEL0
_main__leave:
ld sp, ix
pop ix
ret
;; --- end of user code ---
END
14 changes: 14 additions & 0 deletions tests/functional/zx48k/opt2_while_funcall.bas
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
main()

function saludar(x as Uinteger) as Uinteger
return x + 1
end function

sub main()
dim i, result as uinteger
i = 0
while i < 2
result = saludar(i)
i = i + 1
end while
end sub