-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathline_parser.py
More file actions
56 lines (50 loc) · 1.91 KB
/
Copy pathline_parser.py
File metadata and controls
56 lines (50 loc) · 1.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
from typing import List, Tuple, Optional
from planner import unit, util
def address_of(op: unit.Operand):
if op == unit.Operand.CONSTANT:
return unit.Operand.ADDRESS
if op == unit.Operand.ADDRESS:
return unit.Operand.DADDRESS
raise AssertionError("can't take address of %s" % op)
def parse_line(line: str) -> Tuple[Optional[str], Optional[List[Tuple[unit.Operand, unit.LazyLabel]]]]:
try:
comment_index = line.index("#")
line = line[:comment_index]
except ValueError:
# no comments
pass
line = line.strip()
if len(line) == 0:
return (None, None)
line = line + " "
first_space = line.index(" ")
instruction = line[:first_space].upper()
tokens = []
# Parsing operands
line = line[first_space:].strip()
operands = line.split(",")
for op in operands:
op = op.strip()
if len(op) == 0:
raise ValueError("no-length operand found in %s" % line)
optype = unit.Operand.CONSTANT
if op.startswith("[") and op.endswith("]"):
optype = address_of(optype)
op = op[1:-1].strip()
if op.startswith("[") and op.endswith("]"):
optype = address_of(optype)
op = op[1:-1].strip()
if op.startswith("R"):
if len(op) != 2 or op[1] not in "0123456789":
raise ValueError("Invalid mem-register {op} provided, only R0..R9 supported.")
optype = address_of(optype)
op = str(int(op[1:])*4)
try:
value = unit.LazyLabel(util.LABEL_CONSTANT, int(op, 0)) # automatically understand base-10 and base-16
except ValueError as e:
if util.is_valid_label(op):
value = unit.LazyLabel(op)
else:
raise ValueError(f"Invalid operand value '{str(e)}' in '{str(line)}'")
tokens.append((optype, value))
return (instruction, tokens)