Skip to content

Commit 34f1588

Browse files
committed
Refactorize asm optimizer code
* Cleanup * Improve typing
1 parent e8aff64 commit 34f1588

1 file changed

Lines changed: 21 additions & 18 deletions

File tree

  • src/arch/zx48k/optimizer

src/arch/zx48k/optimizer/asm.py

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,30 @@
11
import re
22

3+
from typing import Dict
4+
from typing import Tuple
5+
from typing import Optional
6+
from typing import List
7+
38
from .patterns import RE_OUTC, RE_INDIR16
49
from .helpers import single_registers
510
from src.libzxbasm import z80
611

712
# Dict of patterns to normalized instructions. I.e. 'ld a, 5' -> 'LD A,N'
8-
Z80_PATTERN = {}
13+
Z80_PATTERN: Dict[re.Pattern, z80.Opcode] = {}
914

1015

11-
class Asm(object):
16+
class Asm:
1217
""" Defines an asm instruction
1318
"""
14-
def __init__(self, asm):
15-
assert isinstance(asm, str)
19+
def __init__(self, asm: str):
1620
asm = asm.strip()
1721
assert asm, "Empty instruction '{}'".format(asm)
18-
self.inst = Asm.inst(asm)
22+
self.inst = Asm.instruction(asm)
1923
self.oper = Asm.opers(asm)
2024
self.asm = '{} {}'.format(self.inst, ' '.join(asm.split(' ', 1)[1:])).strip()
2125
self.cond = Asm.condition(asm)
2226
self.output = Asm.result(asm)
23-
self._bytes = None
27+
self._bytes: Optional[Tuple[str]] = None
2428
self._max_tstates = None
2529
self.is_label = self.inst[-1] == ':'
2630

@@ -31,7 +35,7 @@ def _compute_bytes(self):
3135
self._max_tstates = opcode_data.T
3236
return
3337

34-
self._bytes = tuple()
38+
self._bytes = bytearray()
3539
self._max_tstates = 0
3640

3741
@property
@@ -58,19 +62,18 @@ def max_tstates(self):
5862
return self._max_tstates
5963

6064
@staticmethod
61-
def inst(asm):
65+
def instruction(asm: str) -> str:
6266
tmp = asm.strip(' \t\n').split(' ', 1)[0]
6367
return tmp.lower() if tmp.upper() in z80.Z80INSTR else tmp
6468

6569
@staticmethod
66-
def opers(inst):
70+
def opers(inst: str) -> List[str]:
6771
""" Returns operands of an ASM instruction.
6872
Even "indirect" operands, like SP if RET or CALL is used.
6973
"""
70-
i = inst.strip(' \t\n').split(' ', 1)
71-
I = i[0].lower() # Instruction
72-
i = ''.join(i[1:])
73-
op = [x.strip() for x in i.split(',')]
74+
car, cdr = (inst.strip(' \t\n') + ' ').split(' ', 1)
75+
I = car.lower() # Instruction
76+
op = [x.strip() for x in cdr.split(',')]
7477

7578
if I in {'call', 'jp', 'jr'} and len(op) > 1:
7679
op = op[1:] + ['f']
@@ -111,7 +114,7 @@ def opers(inst):
111114
op += ['sp']
112115

113116
elif I == 'out':
114-
if len(op) and RE_OUTC.match(op[0]):
117+
if op and RE_OUTC.match(op[0]):
115118
op[0] = 'c'
116119
else:
117120
op.pop(0)
@@ -122,8 +125,8 @@ def opers(inst):
122125
else:
123126
op.pop(1)
124127

125-
for i in range(len(op)):
126-
tmp = RE_INDIR16.match(op[i])
128+
for i, o in enumerate(op):
129+
tmp = RE_INDIR16.match(o)
127130
if tmp is not None:
128131
op[i] = '(' + op[i].strip()[1:-1].strip().lower() + ')' # ' ( dE ) ' => '(de)'
129132

@@ -138,7 +141,7 @@ def condition(asm):
138141
condition flag (it always execute) whilst RET C does.
139142
DJNZ has condition flag NZ
140143
"""
141-
i = Asm.inst(asm)
144+
i = Asm.instruction(asm)
142145

143146
if i not in {'call', 'jp', 'jr', 'ret', 'djnz'}:
144147
return None # This instruction always execute
@@ -162,7 +165,7 @@ def result(asm):
162165
""" Returns which 8-bit registers (and SP for INC SP, DEC SP, etc.) are used by an asm
163166
instruction to return a result.
164167
"""
165-
ins = Asm.inst(asm)
168+
ins = Asm.instruction(asm)
166169
op = Asm.opers(asm)
167170

168171
if ins in ('or', 'and') and op == ['a']:

0 commit comments

Comments
 (0)