-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsubleq_parser.py
More file actions
74 lines (65 loc) · 2.52 KB
/
subleq_parser.py
File metadata and controls
74 lines (65 loc) · 2.52 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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# Subleq Parser
# Copyright (C) 2013 Chris Lloyd
# Released under GNU General Public License
# See LICENSE for more details.
# https://github.com/cjrl
# lloyd.chris@verizon.net
class SubleqParser:
tokens = []
label_table = {}
def parse(self,string):
string = self.expand_literals(string)
string = string.replace('\n',';')
string = string.replace('#',';#')
string = string.replace(':',': ')
string = string.replace('.','. ')
self.tokens = [token.split() for token in string.split(';') if not '#' in token and token.strip()]
self.parse_labels()
self.expand_instructions()
self.update_labels()
self.tokens = [token for token in sum(self.tokens,[]) if not token is '.']
self.resolve_labels()
return [int(token) for token in self.tokens]
def resolve_labels(self):
for i, token in enumerate(self.tokens):
if token in self.label_table:
self.tokens[i] = self.label_table[token]
if token is '?':
self.tokens[i] = i+1
def update_labels(self):
for i, label in enumerate(self.label_table):
self.label_table[label] = self.get_label_index(label)
def get_label_index(self,label):
index = 0
address, x = self.label_table[label]
for i in range(address):
index += len(self.tokens[i])
if '.' in self.tokens[i][0]:
index -= 1
if '.' in self.tokens[address][0]:
return index + x - 1
return index
def expand_instructions(self):
for token_index, token in enumerate(self.tokens):
if not token[0] is '.':
oprands = [token[0],token[0],-1]
for i, oprand in enumerate(token):
oprands[i] = oprand
self.tokens[token_index] = oprands
def parse_labels(self):
for token_index, token in enumerate(self.tokens):
for oprand_index, oprand in enumerate(token):
if ':' in oprand:
token.remove(oprand)
self.label_table[oprand[:-1]] = (token_index,oprand_index)
def expand_literals(self,string):
in_literal = False
expanded_string = ""
for char in string:
if char is '"' or char is "'":
in_literal ^=True
elif in_literal:
expanded_string += str(ord(char)) + ' '
else:
expanded_string += char
return expanded_string