Remove dependency on re module.
Chris Pressey
7 years ago
5 | 5 | # This source code is in the public domain. |
6 | 6 | # |
7 | 7 | |
8 | import re | |
9 | 8 | import sys |
10 | 9 | |
11 | 10 | |
190 | 189 | |
191 | 190 | |
192 | 191 | class Reference(object): # abstract |
193 | pass | |
192 | def get_register_number(self): | |
193 | raise NotImplementedError | |
194 | 194 | |
195 | 195 | |
196 | 196 | class ImmediateReference(Reference): |
202 | 202 | def __init__(self, number): |
203 | 203 | self.number = number |
204 | 204 | |
205 | def get_register_number(self): | |
206 | return self.number | |
207 | ||
205 | 208 | |
206 | 209 | class IndirectRegisterReference(Reference): |
207 | def __init__(self, regref): | |
208 | self.regref = regref | |
210 | def __init__(self, ref): | |
211 | assert isinstance(ref, Reference) | |
212 | self.ref = ref | |
213 | ||
214 | def get_register_number(self): | |
215 | return self.ref.get_register_number() | |
209 | 216 | |
210 | 217 | |
211 | 218 | class Scanner(object): |
224 | 231 | while self.line and self.line[0].isdigit(): |
225 | 232 | number = number * 10 + (ord(self.line[0]) - ord('0')) |
226 | 233 | self.line = self.line[1:] |
234 | self.line = self.line.lstrip() | |
227 | 235 | return number |
228 | 236 | |
229 | 237 | def scan_reference(self): |
259 | 267 | scanner.expect('MOV') |
260 | 268 | line = scanner.line |
261 | 269 | |
262 | # lhs = scanner.scan_reference() | |
263 | ||
264 | m = re.match(r'^R(\d+)\s*,\s*(\d+)\s*(\;.*)?$', line) | |
265 | if m is not None: | |
270 | dest = scanner.scan_reference() | |
271 | scanner.expect(',') | |
272 | source = scanner.scan_reference() | |
273 | ||
274 | if scanner.line and scanner.line[0] != ';': | |
275 | raise SyntaxError("Expected EOL or comment") | |
276 | ||
277 | assert not isinstance(dest, ImmediateReference) | |
278 | ||
279 | if isinstance(source, ImmediateReference): | |
280 | assert isinstance(dest, DirectRegisterReference) | |
281 | ||
266 | 282 | self.source_is_immediate = True |
267 | dest_reg = m.group(1) | |
268 | src_imm = m.group(2) | |
269 | self.destination_register = long(dest_reg) | |
270 | self.source_register = long(src_imm) | |
283 | self.destination_register = dest.get_register_number() | |
284 | self.source_register = source.number | |
271 | 285 | return True |
272 | 286 | |
273 | # We actually implement a syntactic superset of ZOWIE here -- the | |
274 | # closing bracket is just sugar which may be omitted or included | |
275 | # without changing the meaning (only the opening bracket counts!) | |
276 | m = re.match(r'^R(\[R)?(\d+)\]?\s*,\s*R(\[R)?(\d+)\]?' | |
277 | r'\s*(\;.*)?$', line) | |
278 | if m is not None: | |
279 | dest_ind = m.group(1) | |
280 | dest_reg = m.group(2) | |
281 | src_ind = m.group(3) | |
282 | src_reg = m.group(4) | |
283 | if dest_ind == '[R': | |
284 | self.destination_is_indirect = True | |
285 | self.destination_register = long(dest_reg) | |
286 | if src_ind == '[R': | |
287 | self.source_is_indirect = True | |
288 | self.source_register = long(src_reg) | |
289 | return True | |
290 | ||
291 | raise SyntaxError("Could not parse line '%s'" % line) | |
287 | if isinstance(dest, IndirectRegisterReference): | |
288 | self.destination_is_indirect = True | |
289 | self.destination_register = dest.get_register_number() | |
290 | ||
291 | if isinstance(source, IndirectRegisterReference): | |
292 | self.source_is_indirect = True | |
293 | self.source_register = source.get_register_number() | |
294 | ||
295 | return True | |
292 | 296 | |
293 | 297 | def apply(self, state): |
294 | 298 | if self.source_is_indirect: |