Skip to content

Commit b1df629

Browse files
authored
Merge pull request #344 from boriel/bugfix/lbound_in_param_arrays
Bugfix/lbound in param arrays
2 parents 6243644 + 05004c0 commit b1df629

6 files changed

Lines changed: 386 additions & 4 deletions

File tree

arch/zx48k/translator.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,7 +1305,9 @@ def visit_LBOUND(self, node):
13051305
if entry.scope == SCOPE.global_:
13061306
self.ic_fparam(gl.PTR_TYPE, '#{}'.format(entry.mangled))
13071307
elif entry.scope == SCOPE.parameter:
1308-
self.ic_fparam(entry.t, entry.offset)
1308+
self.ic_pload(gl.PTR_TYPE, entry.t, entry.offset)
1309+
t1 = optemps.new_t()
1310+
self.ic_fparam(gl.PTR_TYPE, t1)
13091311
elif entry.scope == SCOPE.local:
13101312
self.ic_paddr(-entry.offset, entry.t)
13111313
t1 = optemps.new_t()
@@ -1320,7 +1322,9 @@ def visit_UBOUND(self, node):
13201322
if entry.scope == SCOPE.global_:
13211323
self.ic_fparam(gl.PTR_TYPE, '#{}'.format(entry.mangled))
13221324
elif entry.scope == SCOPE.parameter:
1323-
self.ic_fparam(entry.t, entry.offset)
1325+
self.ic_pload(gl.PTR_TYPE, entry.t, entry.offset)
1326+
t1 = optemps.new_t()
1327+
self.ic_fparam(gl.PTR_TYPE, t1)
13241328
elif entry.scope == SCOPE.local:
13251329
self.ic_paddr(-entry.offset, entry.t)
13261330
t1 = optemps.new_t()

arch/zx48k/translatorinstvisitor.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@ def ic_param(self, type_, t):
196196
def ic_pastore(self, type_, offset, t):
197197
return self.emit('pastore' + self.TSUFFIX(type_), offset, t)
198198

199-
def ic_pload(self, type_, t1, t2):
200-
return self.emit('pload' + self.TSUFFIX(type_), t1, t2)
199+
def ic_pload(self, type_, t1, offset):
200+
return self.emit('pload' + self.TSUFFIX(type_), t1, offset)
201201

202202
def ic_pow(self, type_):
203203
return self.emit('pow' + self.TSUFFIX(type_))

tests/functional/lbound7.asm

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
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+
ld hl, _a
14+
push hl
15+
call _test
16+
ld hl, (_b)
17+
push hl
18+
ld hl, _a
19+
call __LBOUND
20+
ld (_c), hl
21+
ld hl, 0
22+
ld b, h
23+
ld c, l
24+
__END_PROGRAM:
25+
di
26+
ld hl, (__CALL_BACK__)
27+
ld sp, hl
28+
exx
29+
pop hl
30+
exx
31+
pop iy
32+
pop ix
33+
ei
34+
ret
35+
__CALL_BACK__:
36+
DEFW 0
37+
_test:
38+
push ix
39+
ld ix, 0
40+
add ix, sp
41+
ld hl, 0
42+
ld (_b), hl
43+
jp __LABEL0
44+
__LABEL3:
45+
ld hl, (_b)
46+
push hl
47+
ld l, (ix+4)
48+
ld h, (ix+5)
49+
call __LBOUND
50+
ld (_c), hl
51+
__LABEL4:
52+
ld hl, (_b)
53+
inc hl
54+
ld (_b), hl
55+
__LABEL0:
56+
ld hl, 3
57+
ld de, (_b)
58+
or a
59+
sbc hl, de
60+
jp nc, __LABEL3
61+
__LABEL2:
62+
_test__leave:
63+
ld sp, ix
64+
pop ix
65+
exx
66+
pop hl
67+
ex (sp), hl
68+
exx
69+
ret
70+
#line 1 "bound.asm"
71+
; ---------------------------------------------------------
72+
; Copyleft (k)2011 by Jose Rodriguez (a.k.a. Boriel)
73+
; http://www.boriel.com
74+
;
75+
; ZX BASIC Compiler http://www.zxbasic.net
76+
; This code is released under the BSD License
77+
; ---------------------------------------------------------
78+
; Implements both LBOUND(array, N) and UBOUND(array, N) function
79+
; Parameters:
80+
; HL = PTR to array
81+
; [stack - 2] -> N (dimension)
82+
PROC
83+
LOCAL __BOUND
84+
LOCAL __DIM_NOT_EXIST
85+
LOCAL __CONT
86+
__LBOUND:
87+
ld a, 4
88+
jr __BOUND
89+
__UBOUND:
90+
ld a, 6
91+
__BOUND:
92+
ex de, hl ; DE <-- Array ptr
93+
pop hl ; HL <-- Ret address
94+
ex (sp), hl ; CALLEE: HL <-- N, (SP) <-- Ret address
95+
ex de, hl ; DE <-- N, HL <-- ARRAY_PTR
96+
push hl
97+
ld c, (hl)
98+
inc hl
99+
ld h, (hl)
100+
ld l, c ; HL = start of dimension table (first position contains number of dimensions - 1)
101+
ld c, (hl)
102+
inc hl
103+
ld b, (hl)
104+
inc bc ; Number of total dimensions of the array
105+
pop hl ; Recovers ARRAY PTR
106+
ex af, af' ; Saves A for later
107+
ld a, d
108+
or e
109+
jr nz, __CONT ; N = 0 => Return number of dimensions
110+
;; Return the number of dimensions of the array
111+
ld h, b
112+
ld l, c
113+
ret
114+
__CONT:
115+
dec de
116+
ex af, af' ; Recovers A (contains PTR offset)
117+
ex de, hl ; HL = N (dimension asked) - 1, DE = Array PTR
118+
or a
119+
sbc hl, bc ; if no Carry => the user asked for a dimension that does not exist. Return 0
120+
jr nc, __DIM_NOT_EXIST
121+
add hl, bc ; restores HL = (N - 1)
122+
add hl, hl ; hl *= 2
123+
ex de, hl ; hl = ARRAY_PTR + 3, DE jsz = (N - 1) * 2
124+
ld b, 0
125+
ld c, a
126+
add hl, bc ; HL = &BOUND_PTR
127+
ld a, (hl)
128+
inc hl
129+
ld h, (hl)
130+
ld l, a ; LD HL, (HL) => Origin of L/U Bound table
131+
add hl, de ; hl += OFFSET __LBOUND._xxxx
132+
ld e, (hl) ; de = (hl)
133+
inc hl
134+
ld d, (hl)
135+
ex de, hl ; hl = de => returns result in HL
136+
ret
137+
__DIM_NOT_EXIST:
138+
; The dimension requested by the user does not exists. Return 0
139+
ld hl, 0
140+
ret
141+
ENDP
142+
#line 59 "lbound7.bas"
143+
ZXBASIC_USER_DATA:
144+
_b:
145+
DEFB 00, 00
146+
_c:
147+
DEFB 00, 00
148+
_a:
149+
DEFW __LABEL5
150+
_a.__DATA__.__PTR__:
151+
DEFW _a.__DATA__
152+
DEFW _a.__LBOUND__
153+
DEFW 0
154+
_a.__DATA__:
155+
DEFB 00h
156+
DEFB 00h
157+
DEFB 00h
158+
DEFB 00h
159+
DEFB 00h
160+
DEFB 00h
161+
DEFB 00h
162+
DEFB 00h
163+
DEFB 00h
164+
__LABEL5:
165+
DEFW 0001h
166+
DEFW 0003h
167+
DEFB 01h
168+
_a.__LBOUND__:
169+
DEFW 0003h
170+
DEFW 0007h
171+
; Defines DATA END --> HEAP size is 0
172+
ZXBASIC_USER_DATA_END:
173+
; Defines USER DATA Length in bytes
174+
ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA
175+
END

tests/functional/lbound7.bas

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
DIM b, c as UInteger
3+
4+
DIM a(3 TO 5, 7 TO 9) As UByte
5+
SUB test(a() as UByte)
6+
FOR b = 0 TO 3
7+
c = LBound(a, b)
8+
NEXT
9+
END SUB
10+
11+
test(a)
12+
c = LBound(a, b) ' This will signal LBound is used on Array a
13+
14+

tests/functional/ubound7.asm

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
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+
ld hl, _a
14+
push hl
15+
call _test
16+
ld hl, (_b)
17+
push hl
18+
ld hl, _a
19+
call __UBOUND
20+
ld (_c), hl
21+
ld hl, 0
22+
ld b, h
23+
ld c, l
24+
__END_PROGRAM:
25+
di
26+
ld hl, (__CALL_BACK__)
27+
ld sp, hl
28+
exx
29+
pop hl
30+
exx
31+
pop iy
32+
pop ix
33+
ei
34+
ret
35+
__CALL_BACK__:
36+
DEFW 0
37+
_test:
38+
push ix
39+
ld ix, 0
40+
add ix, sp
41+
ld hl, 0
42+
ld (_b), hl
43+
jp __LABEL0
44+
__LABEL3:
45+
ld hl, (_b)
46+
push hl
47+
ld l, (ix+4)
48+
ld h, (ix+5)
49+
call __UBOUND
50+
ld (_c), hl
51+
__LABEL4:
52+
ld hl, (_b)
53+
inc hl
54+
ld (_b), hl
55+
__LABEL0:
56+
ld hl, 3
57+
ld de, (_b)
58+
or a
59+
sbc hl, de
60+
jp nc, __LABEL3
61+
__LABEL2:
62+
_test__leave:
63+
ld sp, ix
64+
pop ix
65+
exx
66+
pop hl
67+
ex (sp), hl
68+
exx
69+
ret
70+
#line 1 "bound.asm"
71+
; ---------------------------------------------------------
72+
; Copyleft (k)2011 by Jose Rodriguez (a.k.a. Boriel)
73+
; http://www.boriel.com
74+
;
75+
; ZX BASIC Compiler http://www.zxbasic.net
76+
; This code is released under the BSD License
77+
; ---------------------------------------------------------
78+
; Implements both LBOUND(array, N) and UBOUND(array, N) function
79+
; Parameters:
80+
; HL = PTR to array
81+
; [stack - 2] -> N (dimension)
82+
PROC
83+
LOCAL __BOUND
84+
LOCAL __DIM_NOT_EXIST
85+
LOCAL __CONT
86+
__LBOUND:
87+
ld a, 4
88+
jr __BOUND
89+
__UBOUND:
90+
ld a, 6
91+
__BOUND:
92+
ex de, hl ; DE <-- Array ptr
93+
pop hl ; HL <-- Ret address
94+
ex (sp), hl ; CALLEE: HL <-- N, (SP) <-- Ret address
95+
ex de, hl ; DE <-- N, HL <-- ARRAY_PTR
96+
push hl
97+
ld c, (hl)
98+
inc hl
99+
ld h, (hl)
100+
ld l, c ; HL = start of dimension table (first position contains number of dimensions - 1)
101+
ld c, (hl)
102+
inc hl
103+
ld b, (hl)
104+
inc bc ; Number of total dimensions of the array
105+
pop hl ; Recovers ARRAY PTR
106+
ex af, af' ; Saves A for later
107+
ld a, d
108+
or e
109+
jr nz, __CONT ; N = 0 => Return number of dimensions
110+
;; Return the number of dimensions of the array
111+
ld h, b
112+
ld l, c
113+
ret
114+
__CONT:
115+
dec de
116+
ex af, af' ; Recovers A (contains PTR offset)
117+
ex de, hl ; HL = N (dimension asked) - 1, DE = Array PTR
118+
or a
119+
sbc hl, bc ; if no Carry => the user asked for a dimension that does not exist. Return 0
120+
jr nc, __DIM_NOT_EXIST
121+
add hl, bc ; restores HL = (N - 1)
122+
add hl, hl ; hl *= 2
123+
ex de, hl ; hl = ARRAY_PTR + 3, DE jsz = (N - 1) * 2
124+
ld b, 0
125+
ld c, a
126+
add hl, bc ; HL = &BOUND_PTR
127+
ld a, (hl)
128+
inc hl
129+
ld h, (hl)
130+
ld l, a ; LD HL, (HL) => Origin of L/U Bound table
131+
add hl, de ; hl += OFFSET __LBOUND._xxxx
132+
ld e, (hl) ; de = (hl)
133+
inc hl
134+
ld d, (hl)
135+
ex de, hl ; hl = de => returns result in HL
136+
ret
137+
__DIM_NOT_EXIST:
138+
; The dimension requested by the user does not exists. Return 0
139+
ld hl, 0
140+
ret
141+
ENDP
142+
#line 59 "ubound7.bas"
143+
ZXBASIC_USER_DATA:
144+
_b:
145+
DEFB 00, 00
146+
_c:
147+
DEFB 00, 00
148+
_a:
149+
DEFW __LABEL5
150+
_a.__DATA__.__PTR__:
151+
DEFW _a.__DATA__
152+
DEFW 0
153+
DEFW _a.__UBOUND__
154+
_a.__DATA__:
155+
DEFB 00h
156+
DEFB 00h
157+
DEFB 00h
158+
DEFB 00h
159+
DEFB 00h
160+
DEFB 00h
161+
DEFB 00h
162+
DEFB 00h
163+
DEFB 00h
164+
__LABEL5:
165+
DEFW 0001h
166+
DEFW 0003h
167+
DEFB 01h
168+
_a.__UBOUND__:
169+
DEFW 0005h
170+
DEFW 0009h
171+
; Defines DATA END --> HEAP size is 0
172+
ZXBASIC_USER_DATA_END:
173+
; Defines USER DATA Length in bytes
174+
ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA
175+
END

0 commit comments

Comments
 (0)