comparison python/asm.py @ 200:5e391d9a3381

Split off asm nodes
author Windel Bouwman
date Sun, 09 Jun 2013 16:06:49 +0200
parents a690473b79e2
children ca1ea402f6a1
comparison
equal deleted inserted replaced
199:a690473b79e2 200:5e391d9a3381
1 import re, sys, argparse 1 import re, sys, argparse
2 import pyyacc 2 import pyyacc
3 from ppci import Token, CompilerError, SourceLocation 3 from ppci import Token, CompilerError, SourceLocation
4 from target import Target 4 from target import Target
5 from asmnodes import ALabel, AInstruction, ABinop, AUnop, ASymbol, ANumber
5 6
6 def tokenize(s): 7 def tokenize(s):
7 """ 8 """
8 Tokenizer, generates an iterator that 9 Tokenizer, generates an iterator that
9 returns tokens! 10 returns tokens!
63 return t 64 return t
64 @property 65 @property
65 def Peak(self): 66 def Peak(self):
66 return self.curTok 67 return self.curTok
67 68
68 class ANode:
69 def __eq__(self, other):
70 return self.__repr__() == other.__repr__()
71
72 class ALabel(ANode):
73 def __init__(self, name):
74 self.name = name
75 def __repr__(self):
76 return '{0}:'.format(self.name)
77
78 class AInstruction(ANode):
79 def __init__(self, opcode, operands):
80 self.opcode = opcode
81 self.operands = operands
82 def __repr__(self):
83 ops = ', '.join(map(str, self.operands))
84 return '{0} {1}'.format(self.opcode, ops)
85
86 class AExpression(ANode):
87 def __add__(self, other):
88 assert isinstance(other, AExpression)
89 return ABinop('+', self, other)
90 def __mul__(self, other):
91 assert isinstance(other, AExpression)
92 return ABinop('*', self, other)
93
94 class ABinop(AExpression):
95 def __init__(self, op, arg1, arg2):
96 self.op = op
97 self.arg1 = arg1
98 self.arg2 = arg2
99 def __repr__(self):
100 return '{0} {1} {2}'.format(self.op, self.arg1, self.arg2)
101
102 class AUnop(AExpression):
103 def __init__(self, op, arg):
104 self.op = op
105 self.arg = arg
106 def __repr__(self):
107 return '{0} {1}'.format(self.op, self.arg)
108
109 class ASymbol(AExpression):
110 def __init__(self, name):
111 self.name = name
112 def __repr__(self):
113 return self.name
114
115 class ANumber(AExpression):
116 def __init__(self, n):
117 assert type(n) is int
118 self.n = n
119 def __repr__(self):
120 return '{0}'.format(self.n)
121 69
122 class Assembler: 70 class Assembler:
123 def __init__(self, target=None): 71 def __init__(self, target=None):
124 self.target = target 72 self.target = target
125 self.output = [] 73 self.restart()
126 # Construct a parser given a grammar: 74 # Construct a parser given a grammar:
127 ident = lambda x: x # Identity helper function 75 ident = lambda x: x # Identity helper function
128 g = pyyacc.Grammar(['ID', 'NUMBER', ',', '[', ']', ':', '+', '-', '*', pyyacc.EPS, 'COMMENT']) 76 g = pyyacc.Grammar(['ID', 'NUMBER', ',', '[', ']', ':', '+', '-', '*', pyyacc.EPS, 'COMMENT'])
129 g.add_production('asmline', ['asmline2']) 77 g.add_production('asmline', ['asmline2'])
130 g.add_production('asmline', ['asmline2', 'COMMENT']) 78 g.add_production('asmline', ['asmline2', 'COMMENT'])
147 g.add_production('addop', ['-'], ident) 95 g.add_production('addop', ['-'], ident)
148 g.add_production('addop', ['+'], ident) 96 g.add_production('addop', ['+'], ident)
149 g.add_production('mulop', ['*'], ident) 97 g.add_production('mulop', ['*'], ident)
150 g.add_production('term', ['factor'], ident) 98 g.add_production('term', ['factor'], ident)
151 g.add_production('term', ['term', 'mulop', 'factor'], self.p_binop) 99 g.add_production('term', ['term', 'mulop', 'factor'], self.p_binop)
152 g.add_production('factor', ['ID'], self.p_symbol) 100 g.add_production('factor', ['ID'], lambda name: ASymbol(name))
153 g.add_production('factor', ['NUMBER'], self.p_number) 101 g.add_production('factor', ['NUMBER'], lambda num: ANumber(int(num)))
154 g.start_symbol = 'asmline' 102 g.start_symbol = 'asmline'
155 self.p = g.genParser() 103 self.p = g.genParser()
156 104
157 # Parser handlers: 105 # Parser handlers:
158 def p_ins_1(self, opc, ops): 106 def p_ins_1(self, opc, ops):
171 def p_label(self, lname, cn): 119 def p_label(self, lname, cn):
172 lab = ALabel(lname) 120 lab = ALabel(lname)
173 self.emit(lab) 121 self.emit(lab)
174 def p_binop(self, exp1, op, exp2): 122 def p_binop(self, exp1, op, exp2):
175 return ABinop(op, exp1, exp2) 123 return ABinop(op, exp1, exp2)
176 def p_symbol(self, name):
177 return ASymbol(name)
178 def p_number(self, n):
179 n = int(n)
180 return ANumber(n)
181 124
182 # Top level interface: 125 # Top level interface:
183 def restart(self): 126 def restart(self):
184 pass 127 self.output = []
128 self.binout = bytearray()
129 self.current_section = '.text'
185 130
186 def emit(self, a): 131 def emit(self, a):
187 """ Emit a parsed instruction """ 132 """ Emit a parsed instruction """
188 self.output.append(a) 133 self.output.append(a)
189 # Determine the bit pattern from a lookup table: 134 # Determine the bit pattern from a lookup table:
190 # TODO 135 # TODO
191
192 136
193 def parse_line(self, line): 137 def parse_line(self, line):
194 """ Parse line into asm AST """ 138 """ Parse line into asm AST """
195 tokens = tokenize(line) 139 tokens = tokenize(line)
196 self.p.parse(tokens) 140 self.p.parse(tokens)
213 """ Assemble a parsed asm line """ 157 """ Assemble a parsed asm line """
214 # TODO 158 # TODO
215 if not self.target: 159 if not self.target:
216 raise CompilerError('Cannot assemble without target') 160 raise CompilerError('Cannot assemble without target')
217 while self.output: 161 while self.output:
218 i = self.output.pop(0) 162 vi = self.output.pop(0)
219 self.target.createInstruction(i) 163 ri = self.target.mapInstruction(vi)
164 b = ri.encode()
165 assert type(b) is bytes
166 self.binout.extend(b)
220 167
221 def back_patch(self): 168 def back_patch(self):
222 """ Fix references to earlier labels """ 169 """ Fix references to earlier labels """
223 pass 170 pass
224 171