Skip to content

Commit eed8ca0

Browse files
authored
Merge pull request #601 from boriel/bugfix/tmp_labels_in_different_files
fix: fix termporary labels across multiple files
2 parents 7c6e1dd + a016a64 commit eed8ca0

3 files changed

Lines changed: 43 additions & 26 deletions

File tree

src/zxbasm/memory.py

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ class Memory:
1717
"""A class to describe memory"""
1818

1919
MAX_MEM = 65535 # Max memory limit
20-
_tmp_labels: Dict[int, Dict[str, Label]]
21-
_tmp_labels_lines: List[int]
22-
_tmp_pending_labels: List[Label]
20+
_tmp_labels: Dict[Tuple[str, int], Dict[str, Label]]
21+
_tmp_labels_lines: Dict[str, List[int]]
22+
_tmp_pending_labels: Dict[str, List[Label]]
2323

2424
def __init__(self, org: int = 0):
2525
"""Initializes the origin of code.
@@ -121,24 +121,24 @@ def set_memory_slot(self):
121121
self.orgs[self.org] = [] # Declares an empty memory slot if not already done
122122
self.memory_bytes[self.org] = 0 # Declares an empty memory slot if not already done
123123

124-
def resolve_temporary_label(self, label: Label):
124+
def resolve_temporary_label(self, fname: str, label: Label):
125125
if label.direction == -1:
126-
idx = bisect_right(self._tmp_labels_lines, label.lineno)
127-
for line in self._tmp_labels_lines[:idx][::-1]:
128-
if label == self._tmp_labels[line].get(label.name):
129-
label.value = self._tmp_labels[line][label.name].value
126+
idx = bisect_right(self._tmp_labels_lines[fname], label.lineno)
127+
for line in self._tmp_labels_lines[fname][:idx][::-1]:
128+
if label == self._tmp_labels[(fname, line)].get(label.name):
129+
label.value = self._tmp_labels[(fname, line)][label.name].value
130130
return
131131
elif label.direction == +1:
132-
idx = bisect_left(self._tmp_labels_lines, label.lineno)
133-
for line in self._tmp_labels_lines[idx:]:
134-
if label == self._tmp_labels[line].get(label.name):
135-
label.value = self._tmp_labels[line][label.name].value
132+
idx = bisect_left(self._tmp_labels_lines[fname], label.lineno)
133+
for line in self._tmp_labels_lines[fname][idx:]:
134+
if label == self._tmp_labels[(fname, line)].get(label.name):
135+
label.value = self._tmp_labels[(fname, line)][label.name].value
136136
return
137137

138138
def clear_temporary_labels(self):
139-
self._tmp_labels_lines = []
139+
self._tmp_labels_lines = defaultdict(list)
140140
self._tmp_labels = defaultdict(dict)
141-
self._tmp_pending_labels = []
141+
self._tmp_pending_labels = defaultdict(list)
142142

143143
def add_instruction(self, instr: Asm):
144144
"""This will insert an asm instruction at the current memory position
@@ -162,10 +162,11 @@ def dump(self):
162162
OUTPUT = []
163163
align = []
164164

165-
for label in self._tmp_pending_labels:
166-
self.resolve_temporary_label(label)
167-
if not label.defined:
168-
error(label.lineno, "Undefined temporary label '%s'" % label.name)
165+
for filename in self._tmp_pending_labels:
166+
for label in self._tmp_pending_labels[filename]:
167+
self.resolve_temporary_label(filename, label)
168+
if not label.defined:
169+
error(label.lineno, "Undefined temporary label '%s'" % label.name)
169170

170171
for label in self.global_labels.values():
171172
if not label.defined:
@@ -222,12 +223,17 @@ def declare_label(
222223
else:
223224
__DEBUG__(f"Declaring '{ex_label}' in {lineno}")
224225

226+
fname = gl.FILENAME
225227
if label.isdecimal(): # Temporary label?
226-
assert not self._tmp_labels_lines or self._tmp_labels_lines[-1] <= lineno, "Temporary label out of order"
227-
if not self._tmp_labels_lines or self._tmp_labels_lines[-1] != lineno:
228-
self._tmp_labels_lines.append(lineno)
229-
230-
self._tmp_labels[lineno][ex_label] = Label(ex_label, lineno, value, False, namespace, is_address=True)
228+
assert (
229+
not self._tmp_labels_lines[fname] or self._tmp_labels_lines[fname][-1] <= lineno
230+
), "Temporary label out of order"
231+
if not self._tmp_labels_lines[fname] or self._tmp_labels_lines[fname][-1] != lineno:
232+
self._tmp_labels_lines[fname].append(lineno)
233+
234+
self._tmp_labels[(fname, lineno)][ex_label] = Label(
235+
ex_label, lineno, value, False, namespace, is_address=True
236+
)
231237
return
232238

233239
if ex_label in self.local_labels[-1].keys():
@@ -240,13 +246,14 @@ def declare_label(
240246

241247
def get_label(self, label: str, lineno: int) -> Label:
242248
"""Returns a label in the current context or in the global one.
243-
If the label does not exists, creates a new one and returns it.
249+
If the label does not exist, creates a new one and returns it.
244250
"""
245251

246252
ex_label, namespace = Memory.id_name(label)
247253
result = Label(ex_label, lineno, namespace=namespace)
254+
248255
if result.is_temporary:
249-
self._tmp_pending_labels.append(result)
256+
self._tmp_pending_labels[gl.FILENAME].append(result)
250257
return result
251258

252259
for local_label in self.local_labels[::-1]:
@@ -260,7 +267,7 @@ def get_label(self, label: str, lineno: int) -> Label:
260267

261268
def set_label(self, label: str, lineno: int, local: bool = False) -> Label:
262269
"""Sets a label, lineno and local flag in the current scope
263-
(even if it exist in previous scopes). If the label exist in
270+
(even if it exists in previous scopes). If the label exist in
264271
the current scope, changes it flags.
265272
266273
The resulting label is returned.

tests/functional/tmp_label7.asm

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
3+
jp 1f
4+
nop
5+
1:
6+
7+
#line 1 "another_file.asm"
8+
1:
9+
10+
nop

tests/functional/tmp_label7.bin

5 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)