Skip to content

Commit efbb565

Browse files
authored
Merge pull request #420 from boriel/feature/refactorize_code
Feature/refactorize code
2 parents e378c94 + 34f1588 commit efbb565

3 files changed

Lines changed: 39 additions & 39 deletions

File tree

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']:

src/libzxbasm/asm.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@
22
# -*- coding: utf-8 -*-
33
# vim: ts=4:et:sw=4
44

5-
from src.libzxbasm.z80 import Opcode, Z80SET
5+
from src.libzxbasm.z80 import Z80SET
66
from src.api.errors import Error
77
import re
88

99
# Reg. Exp. for counting N args in an asm mnemonic
1010
ARGre = re.compile(r'\bN+\b')
1111

12-
Z80_re = {} # Reg. Expr dictionary to cache them
13-
1412
Z80_8REGS = ('A', 'B', 'C', 'D', 'E', 'H', 'L',
1513
'IXh', 'IYh', 'IXl', 'IYl', 'I', 'R')
1614

@@ -20,17 +18,17 @@
2018
}
2119

2220

23-
def num2bytes(x, bytes):
21+
def num2bytes(x, bytes_):
2422
""" Returns x converted to a little-endian t-uple of bytes.
2523
E.g. num2bytes(255, 4) = (255, 0, 0, 0)
2624
"""
2725
if not isinstance(x, int): # If it is another "thing", just return ZEROs
28-
return tuple([0] * bytes)
26+
return tuple([0] * bytes_)
2927

30-
x = x & ((2 << (bytes * 8)) - 1) # mask the initial value
28+
x = x & ((2 << (bytes_ * 8)) - 1) # mask the initial value
3129
result = ()
3230

33-
for i in range(bytes):
31+
for i in range(bytes_):
3432
result += (x & 0xFF,)
3533
x >>= 8
3634

@@ -70,10 +68,9 @@ def __init__(self, current_size, asm):
7068
self.asm = asm
7169

7270

73-
class AsmInstruction(Opcode):
71+
class AsmInstruction:
7472
""" Derives from Opcode. This one checks for opcode validity.
7573
"""
76-
7774
def __init__(self, asm, arg=None):
7875
""" Parses the given asm instruction and validates
7976
it against the Z80SET table. Raises InvalidMnemonicError
@@ -98,10 +95,11 @@ def __init__(self, asm, arg=None):
9895
self.comments = ''
9996

10097
asm = asm[0]
101-
if asm.upper() not in Z80SET.keys():
102-
raise InvalidMnemonicError(asm)
10398

10499
self.mnemo = asm.upper()
100+
if self.mnemo not in Z80SET.keys():
101+
raise InvalidMnemonicError(asm)
102+
105103
Z80 = Z80SET[self.mnemo]
106104

107105
self.asm = asm
@@ -125,7 +123,7 @@ def argval(self):
125123

126124
return self.arg
127125

128-
def bytes(self):
126+
def bytes(self) -> bytearray:
129127
""" Returns a t-uple with instruction bytes (integers)
130128
"""
131129
result = []
@@ -147,7 +145,7 @@ def bytes(self):
147145
if len(result) != self.size:
148146
raise InternalMismatchSizeError(len(result), self)
149147

150-
return result
148+
return bytearray(result)
151149

152150
def __str__(self):
153151
return self.asm

src/libzxbasm/z80.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@
22
# -*- coding: utf-8 -*-
33
# vim:ts=4:et:
44

5+
from typing import NamedTuple
56

6-
class Opcode:
7-
""" Describes opcodes and other info.
8-
"""
9-
def __init__(self, asm: str, time: int, size: int, opcode: str):
10-
self.asm = asm
11-
self.T = time
12-
self.size = size
13-
self.opcode = opcode
7+
8+
class Opcode(NamedTuple):
9+
asm: str
10+
T: int
11+
size: int
12+
opcode: str
1413

1514

1615
Z80SET = {

0 commit comments

Comments
 (0)