Skip to content

Commit de82c95

Browse files
committed
bugfix: access param array values correctly
1 parent 3210892 commit de82c95

4 files changed

Lines changed: 265 additions & 2 deletions

File tree

arch/zx48k/translator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ def visit_ARRAYLOAD(self, node):
238238
if scope == SCOPE.global_:
239239
self.ic_aload(node.type_, node.entry.t, node.entry.mangled)
240240
elif scope == SCOPE.parameter:
241-
self.ic_paload(node.type_, node.t, node.entry.offset)
241+
self.ic_paload(node.type_, node.t, '*{}'.format(node.entry.offset))
242242
elif scope == SCOPE.local:
243243
self.ic_paload(node.type_, node.t, -node.entry.offset)
244244
else:

symbols/arrayaccess.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ def make_node(cls, id_, arglist, lineno):
116116

117117
# Checks for array subscript range if the subscript is constant
118118
# e.g. A(1) is a constant subscript access
119+
btype = gl.SYMBOL_TABLE.basic_types[gl.BOUND_TYPE]
119120
for i, b in zip(arglist, variable.bounds):
120-
btype = gl.SYMBOL_TABLE.basic_types[gl.BOUND_TYPE]
121121
lower_bound = NUMBER(b.lower, type_=btype, lineno=lineno)
122122
i.value = BINARY.make_node('MINUS',
123123
TYPECAST.make_node(btype, i.value, lineno),
@@ -127,6 +127,10 @@ def make_node(cls, id_, arglist, lineno):
127127
val = i.value.value
128128
if val < 0 or val > b.count:
129129
warning(lineno, "Array '%s' subscript out of range" % id_)
130+
else:
131+
btype = gl.SYMBOL_TABLE.basic_types[gl.BOUND_TYPE]
132+
for arg in arglist:
133+
arg.value = TYPECAST.make_node(btype, arg.value, arg.value.lineno)
130134

131135
# Returns the variable entry and the node
132136
return cls(variable, arglist, lineno)

tests/functional/pararray8.asm

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
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 _max
16+
ld (_maximum), a
17+
ld hl, 0
18+
ld b, h
19+
ld c, l
20+
__END_PROGRAM:
21+
di
22+
ld hl, (__CALL_BACK__)
23+
ld sp, hl
24+
exx
25+
pop hl
26+
exx
27+
pop iy
28+
pop ix
29+
ei
30+
ret
31+
__CALL_BACK__:
32+
DEFW 0
33+
_max:
34+
push ix
35+
ld ix, 0
36+
add ix, sp
37+
ld hl, 0
38+
push hl
39+
ld hl, 0
40+
push hl
41+
push ix
42+
pop hl
43+
ld de, 4
44+
add hl, de
45+
call __ARRAY_PTR
46+
ld a, (hl)
47+
ld (ix-1), a
48+
ld (ix-2), 1
49+
jp __LABEL0
50+
__LABEL3:
51+
ld a, (ix-1)
52+
push af
53+
ld a, (ix-2)
54+
ld l, a
55+
ld h, 0
56+
push hl
57+
push ix
58+
pop hl
59+
ld de, 4
60+
add hl, de
61+
call __ARRAY_PTR
62+
pop af
63+
cp (hl)
64+
jp nc, __LABEL6
65+
ld a, (ix-2)
66+
ld l, a
67+
ld h, 0
68+
push hl
69+
push ix
70+
pop hl
71+
ld de, 4
72+
add hl, de
73+
call __ARRAY_PTR
74+
ld a, (hl)
75+
ld (ix-1), a
76+
__LABEL6:
77+
__LABEL4:
78+
inc (ix-2)
79+
__LABEL0:
80+
ld a, (ix-2)
81+
push af
82+
ld a, 5
83+
pop hl
84+
cp h
85+
jp nc, __LABEL3
86+
__LABEL2:
87+
ld a, (ix-1)
88+
_max__leave:
89+
ld sp, ix
90+
pop ix
91+
exx
92+
pop hl
93+
ex (sp), hl
94+
exx
95+
ret
96+
#line 1 "array.asm"
97+
; vim: ts=4:et:sw=4:
98+
; Copyleft (K) by Jose M. Rodriguez de la Rosa
99+
; (a.k.a. Boriel)
100+
; http://www.boriel.com
101+
; -------------------------------------------------------------------
102+
; Simple array Index routine
103+
; Number of total indexes dimensions - 1 at beginning of memory
104+
; HL = Start of array memory (First two bytes contains N-1 dimensions)
105+
; Dimension values on the stack, (top of the stack, highest dimension)
106+
; E.g. A(2, 4) -> PUSH <4>; PUSH <2>
107+
; For any array of N dimension A(aN-1, ..., a1, a0)
108+
; and dimensions D[bN-1, ..., b1, b0], the offset is calculated as
109+
; O = [a0 + b0 * (a1 + b1 * (a2 + ... bN-2(aN-1)))]
110+
; What I will do here is to calculate the following sequence:
111+
; ((aN-1 * bN-2) + aN-2) * bN-3 + ...
112+
#line 1 "mul16.asm"
113+
__MUL16: ; Mutiplies HL with the last value stored into de stack
114+
; Works for both signed and unsigned
115+
PROC
116+
LOCAL __MUL16LOOP
117+
LOCAL __MUL16NOADD
118+
ex de, hl
119+
pop hl ; Return address
120+
ex (sp), hl ; CALLEE caller convention
121+
__MUL16_FAST:
122+
ld b, 16
123+
ld a, h
124+
ld c, l
125+
ld hl, 0
126+
__MUL16LOOP:
127+
add hl, hl ; hl << 1
128+
sla c
129+
rla ; a,c << 1
130+
jp nc, __MUL16NOADD
131+
add hl, de
132+
__MUL16NOADD:
133+
djnz __MUL16LOOP
134+
ret ; Result in hl (16 lower bits)
135+
ENDP
136+
#line 20 "array.asm"
137+
#line 24 "/zxbasic/library-asm/array.asm"
138+
__ARRAY_PTR: ;; computes an array offset from a pointer
139+
ld c, (hl)
140+
inc hl
141+
ld h, (hl)
142+
ld l, c
143+
__ARRAY:
144+
PROC
145+
LOCAL LOOP
146+
LOCAL ARRAY_END
147+
LOCAL RET_ADDRESS ; Stores return address
148+
LOCAL TMP_ARR_PTR ; Stores pointer temporarily
149+
ld e, (hl)
150+
inc hl
151+
ld d, (hl)
152+
inc hl
153+
ld (TMP_ARR_PTR), hl
154+
ex de, hl
155+
ex (sp), hl ; Return address in HL, array address in the stack
156+
ld (RET_ADDRESS + 1), hl ; Stores it for later
157+
exx
158+
pop hl ; Will use H'L' as the pointer
159+
ld c, (hl) ; Loads Number of dimensions from (hl)
160+
inc hl
161+
ld b, (hl)
162+
inc hl ; Ready
163+
exx
164+
ld hl, 0 ; HL = Offset "accumulator"
165+
LOOP:
166+
#line 62 "/zxbasic/library-asm/array.asm"
167+
pop bc ; Get next index (Ai) from the stack
168+
#line 72 "/zxbasic/library-asm/array.asm"
169+
add hl, bc ; Adds current index
170+
exx ; Checks if B'C' = 0
171+
ld a, b ; Which means we must exit (last element is not multiplied by anything)
172+
or c
173+
jr z, ARRAY_END ; if B'Ci == 0 we are done
174+
ld e, (hl) ; Loads next dimension into D'E'
175+
inc hl
176+
ld d, (hl)
177+
inc hl
178+
push de
179+
dec bc ; Decrements loop counter
180+
exx
181+
pop de ; DE = Max bound Number (i-th dimension)
182+
call __FNMUL
183+
jp LOOP
184+
ARRAY_END:
185+
ld a, (hl)
186+
exx
187+
#line 101 "/zxbasic/library-asm/array.asm"
188+
LOCAL ARRAY_SIZE_LOOP
189+
ex de, hl
190+
ld hl, 0
191+
ld b, a
192+
ARRAY_SIZE_LOOP:
193+
add hl, de
194+
djnz ARRAY_SIZE_LOOP
195+
#line 111 "/zxbasic/library-asm/array.asm"
196+
ex de, hl
197+
ld hl, (TMP_ARR_PTR)
198+
ld a, (hl)
199+
inc hl
200+
ld h, (hl)
201+
ld l, a
202+
add hl, de ; Adds element start
203+
RET_ADDRESS:
204+
jp 0
205+
;; Performs a faster multiply for little 16bit numbs
206+
LOCAL __FNMUL, __FNMUL2
207+
__FNMUL:
208+
xor a
209+
or h
210+
jp nz, __MUL16_FAST
211+
or l
212+
ret z
213+
cp 33
214+
jp nc, __MUL16_FAST
215+
ld b, l
216+
ld l, h ; HL = 0
217+
__FNMUL2:
218+
add hl, de
219+
djnz __FNMUL2
220+
ret
221+
TMP_ARR_PTR:
222+
DW 0 ; temporary storage for pointer to tables
223+
ENDP
224+
#line 85 "pararray8.bas"
225+
ZXBASIC_USER_DATA:
226+
_maximum:
227+
DEFB 00
228+
_a:
229+
DEFW __LABEL7
230+
_a.__DATA__.__PTR__:
231+
DEFW _a.__DATA__
232+
_a.__DATA__:
233+
DEFB 04h
234+
DEFB 03h
235+
DEFB 01h
236+
DEFB 05h
237+
DEFB 07h
238+
DEFB 08h
239+
__LABEL7:
240+
DEFW 0000h
241+
DEFB 01h
242+
; Defines DATA END --> HEAP size is 0
243+
ZXBASIC_USER_DATA_END:
244+
; Defines USER DATA Length in bytes
245+
ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA
246+
END

tests/functional/pararray8.bas

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
Function max(a() as Ubyte) as Ubyte
3+
DIM max as UByte
4+
max = a(0)
5+
for i = 1 to 5
6+
if max < a(i) then max = a(i)
7+
next
8+
return max
9+
End Function
10+
11+
DIM a(5) as Ubyte = {4, 3, 1, 5, 7, 8}
12+
maximum = max(a)
13+

0 commit comments

Comments
 (0)