Skip to content

Commit 245fb10

Browse files
authored
Merge pull request #1029 from boriel-basic/fix/USR_not_called
Fix/usr not called
2 parents 700cc31 + 7a7c522 commit 245fb10

9 files changed

Lines changed: 265 additions & 11 deletions

File tree

src/api/optimize.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -321,16 +321,20 @@ def visit_LET(self, node):
321321
lvalue = node.children[0]
322322
if self.O_LEVEL > 1 and not lvalue.accessed:
323323
warning_not_used(lvalue.lineno, lvalue.name, fname=lvalue.filename)
324-
block = symbols.BLOCK(
325-
*[
326-
symbols.CALL(x.entry, x.args, x.lineno, lvalue.filename)
327-
for x in self.filter_inorder(
328-
node.children[1],
329-
lambda x: x.token == "FUNCCALL",
330-
lambda x: x.token != "FUNCTION",
331-
)
332-
]
333-
)
324+
nodes = [
325+
symbols.CALL(x.entry, x.args, x.lineno, lvalue.filename) if x.token == "FUNCCALL" else x
326+
for x in self.filter_inorder(
327+
node.children[1],
328+
lambda x: x.token in ("FUNCCALL", "BUILTIN"),
329+
lambda x: x.token != "FUNCTION",
330+
)
331+
if x.token == "FUNCCALL" or getattr(x, "fname") in {"IN", "RND", "USR"}
332+
]
333+
for node_ in nodes:
334+
if node_.token == "BUILTIN":
335+
node_.discard_result = True
336+
337+
block = symbols.BLOCK(*nodes)
334338
yield block
335339
else:
336340
yield (yield self.generic_visit(node))

src/arch/z80/visitor/translator.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ def visit_BUILTIN(self, node):
152152
att = f"visit_{node.fname}"
153153
if hasattr(bvisitor, att):
154154
yield getattr(bvisitor, att)(node)
155+
if node.discard_result:
156+
self.ic_fparam(node.type_, optemps.new_t())
155157
return
156158

157159
raise InvalidBuiltinFunctionError(node.fname)

src/symbols/builtin.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414

1515
class SymbolBUILTIN(Symbol):
16-
"""Defines an BUILTIN function e.g. INKEY$(), RND() or LEN"""
16+
"""Defines a BUILTIN function e.g. INKEY$(), RND() or LEN"""
1717

1818
def __init__(self, lineno, fname, type_=None, *operands):
1919
assert isinstance(lineno, int)
@@ -22,6 +22,7 @@ def __init__(self, lineno, fname, type_=None, *operands):
2222
self.lineno = lineno
2323
self.fname = fname
2424
self.type_ = type_
25+
self.discard_result = False # Whether to discard the return value of the function
2526

2627
@property
2728
def type_(self):
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
org 32768
2+
.core.__START_PROGRAM:
3+
di
4+
push ix
5+
push iy
6+
exx
7+
push hl
8+
exx
9+
ld (.core.__CALL_BACK__), sp
10+
ei
11+
jp .core.__MAIN_PROGRAM__
12+
.core.__CALL_BACK__:
13+
DEFW 0
14+
.core.ZXBASIC_USER_DATA:
15+
; Defines USER DATA Length in bytes
16+
.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA
17+
.core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN
18+
.core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA
19+
.core.ZXBASIC_USER_DATA_END:
20+
.core.__MAIN_PROGRAM__:
21+
ld bc, 0
22+
in a, (c)
23+
ld hl, 0
24+
ld b, h
25+
ld c, l
26+
.core.__END_PROGRAM:
27+
di
28+
ld hl, (.core.__CALL_BACK__)
29+
ld sp, hl
30+
exx
31+
pop hl
32+
pop iy
33+
pop ix
34+
exx
35+
ei
36+
ret
37+
;; --- end of user code ---
38+
END
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
REM USR 0 must be compiled despite c being optimized
2+
LET c = IN 0
3+
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
org 32768
2+
.core.__START_PROGRAM:
3+
di
4+
push ix
5+
push iy
6+
exx
7+
push hl
8+
exx
9+
ld (.core.__CALL_BACK__), sp
10+
ei
11+
jp .core.__MAIN_PROGRAM__
12+
.core.__CALL_BACK__:
13+
DEFW 0
14+
.core.ZXBASIC_USER_DATA:
15+
; Defines USER DATA Length in bytes
16+
.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA
17+
.core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN
18+
.core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA
19+
.core.ZXBASIC_USER_DATA_END:
20+
.core.__MAIN_PROGRAM__:
21+
call .core.RND
22+
ld hl, 0
23+
ld b, h
24+
ld c, l
25+
.core.__END_PROGRAM:
26+
di
27+
ld hl, (.core.__CALL_BACK__)
28+
ld sp, hl
29+
exx
30+
pop hl
31+
pop iy
32+
pop ix
33+
exx
34+
ei
35+
ret
36+
;; --- end of user code ---
37+
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/random.asm"
38+
; RANDOM functions
39+
push namespace core
40+
RANDOMIZE:
41+
; Randomize with 32 bit seed in DE HL
42+
; if SEED = 0, calls ROM to take frames as seed
43+
PROC
44+
LOCAL TAKE_FRAMES
45+
LOCAL FRAMES
46+
ld a, h
47+
or l
48+
or d
49+
or e
50+
jr z, TAKE_FRAMES
51+
ld (RANDOM_SEED_LOW), hl
52+
ld (RANDOM_SEED_HIGH), de
53+
ret
54+
TAKE_FRAMES:
55+
; Takes the seed from frames
56+
ld hl, (FRAMES)
57+
ld (RANDOM_SEED_LOW), hl
58+
ld hl, (FRAMES + 2)
59+
ld (RANDOM_SEED_HIGH), hl
60+
ret
61+
FRAMES EQU 23672
62+
ENDP
63+
RANDOM_SEED_HIGH EQU RAND+1 ; RANDOM seed, 16 higher bits
64+
RANDOM_SEED_LOW EQU 23670 ; RANDOM seed, 16 lower bits
65+
RAND:
66+
PROC
67+
ld de,0C0DEh ; yw -> zt
68+
ld hl,(RANDOM_SEED_LOW) ; xz -> yw
69+
ld (RANDOM_SEED_LOW),de ; x = y, z = w
70+
ld a,e ; w = w ^ ( w << 3 )
71+
add a,a
72+
add a,a
73+
add a,a
74+
xor e
75+
ld e,a
76+
ld a,h ; t = x ^ (x << 1)
77+
add a,a
78+
xor h
79+
ld d,a
80+
rra ; t = t ^ (t >> 1) ^ w
81+
xor d
82+
xor e
83+
ld d,l ; y = z
84+
ld e,a ; w = t
85+
ld (RANDOM_SEED_HIGH),de
86+
ret
87+
ENDP
88+
RND:
89+
; Returns a FLOATING point integer
90+
; using RAND as a mantissa
91+
PROC
92+
LOCAL RND_LOOP
93+
call RAND
94+
; BC = HL since ZX BASIC uses ED CB A registers for FP
95+
ld b, h
96+
ld c, l
97+
ld a, e
98+
or d
99+
or c
100+
or b
101+
ret z ; Returns 0 if BC=DE=0
102+
; We already have a random 32 bit mantissa in ED CB
103+
; From 0001h to FFFFh
104+
ld l, 81h ; Exponent
105+
; At this point we have [0 .. 1) FP number;
106+
; Now we must shift mantissa left until highest bit goes into carry
107+
ld a, e ; Use A register for rotating E faster (using RLA instead of RL E)
108+
RND_LOOP:
109+
dec l
110+
sla b
111+
rl c
112+
rl d
113+
rla
114+
jp nc, RND_LOOP
115+
; Now undo last mantissa left-shift once
116+
ccf ; Clears carry to insert a 0 bit back into mantissa -> positive FP number
117+
rra
118+
rr d
119+
rr c
120+
rr b
121+
ld e, a ; E must have the highest byte
122+
ld a, l ; exponent in A
123+
ret
124+
ENDP
125+
pop namespace
126+
#line 18 "arch/zx48k/opt2_rnd_opt.bas"
127+
END
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
REM USR 0 must be compiled despite c being optimized
2+
LET c = RND
3+
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
org 32768
2+
.core.__START_PROGRAM:
3+
di
4+
push ix
5+
push iy
6+
exx
7+
push hl
8+
exx
9+
ld (.core.__CALL_BACK__), sp
10+
ei
11+
jp .core.__MAIN_PROGRAM__
12+
.core.__CALL_BACK__:
13+
DEFW 0
14+
.core.ZXBASIC_USER_DATA:
15+
; Defines USER DATA Length in bytes
16+
.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA
17+
.core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN
18+
.core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA
19+
.core.ZXBASIC_USER_DATA_END:
20+
.core.__MAIN_PROGRAM__:
21+
ld hl, 0
22+
call .core.USR
23+
ld hl, 0
24+
ld b, h
25+
ld c, l
26+
.core.__END_PROGRAM:
27+
di
28+
ld hl, (.core.__CALL_BACK__)
29+
ld sp, hl
30+
exx
31+
pop hl
32+
pop iy
33+
pop ix
34+
exx
35+
ei
36+
ret
37+
;; --- end of user code ---
38+
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/usr.asm"
39+
; Emulates the USR Sinclair BASIC function
40+
; Result value returns in BC
41+
; We use HL for returning values, su we must
42+
; copy BC into HL before returning
43+
;
44+
; The incoming parameter is HL (Address to JUMP)
45+
;
46+
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/table_jump.asm"
47+
push namespace core
48+
JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A
49+
add a, a
50+
JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE
51+
ld e, a
52+
ld d, 0
53+
JUMP_HL_PLUS_DE: ; Does JP (HL + DE)
54+
add hl, de
55+
ld e, (hl)
56+
inc hl
57+
ld d, (hl)
58+
ex de, hl
59+
CALL_HL:
60+
jp (hl)
61+
pop namespace
62+
#line 10 "/zxbasic/src/lib/arch/zx48k/runtime/usr.asm"
63+
push namespace core
64+
USR:
65+
push ix ; must preserve IX
66+
call CALL_HL
67+
pop ix
68+
ld h, b
69+
ld l, c
70+
ret
71+
pop namespace
72+
#line 19 "arch/zx48k/opt2_usr_opt.bas"
73+
END
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
REM USR 0 must be compiled despite c being optimized
2+
LET c = USR 0
3+

0 commit comments

Comments
 (0)