Mercurial > lcfOS
comparison python/asm.py @ 199:a690473b79e2
Added msp430 target
author | Windel Bouwman |
---|---|
date | Fri, 07 Jun 2013 18:59:57 +0200 |
parents | 33d50727a23c |
children | 5e391d9a3381 |
comparison
equal
deleted
inserted
replaced
198:33d50727a23c | 199:a690473b79e2 |
---|---|
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 | 4 from target import Target |
5 | |
6 # Generic assembler: | |
7 keywords = ['global', 'db'] | |
8 | 5 |
9 def tokenize(s): | 6 def tokenize(s): |
10 """ | 7 """ |
11 Tokenizer, generates an iterator that | 8 Tokenizer, generates an iterator that |
12 returns tokens! | 9 returns tokens! |
32 typ = mo.lastgroup | 29 typ = mo.lastgroup |
33 val = mo.group(typ) | 30 val = mo.group(typ) |
34 if typ == 'NEWLINE': | 31 if typ == 'NEWLINE': |
35 line_start = pos | 32 line_start = pos |
36 line += 1 | 33 line += 1 |
37 elif typ == 'COMMENTS': | |
38 pass | |
39 elif typ != 'SKIP': | 34 elif typ != 'SKIP': |
40 if typ == 'ID': | 35 if typ == 'LEESTEKEN': |
41 if val in keywords: | |
42 typ = val | |
43 elif typ == 'LEESTEKEN': | |
44 typ = val | 36 typ = val |
45 elif typ == 'NUMBER': | 37 elif typ == 'NUMBER': |
46 val = int(val) | 38 val = int(val) |
47 elif typ == 'HEXNUMBER': | 39 elif typ == 'HEXNUMBER': |
48 val = int(val[2:], 16) | 40 val = int(val[2:], 16) |
120 def __repr__(self): | 112 def __repr__(self): |
121 return self.name | 113 return self.name |
122 | 114 |
123 class ANumber(AExpression): | 115 class ANumber(AExpression): |
124 def __init__(self, n): | 116 def __init__(self, n): |
117 assert type(n) is int | |
125 self.n = n | 118 self.n = n |
126 def __repr__(self): | 119 def __repr__(self): |
127 return '{0}'.format(self.n) | 120 return '{0}'.format(self.n) |
128 | 121 |
129 class Assembler: | 122 class Assembler: |
130 def __init__(self): | 123 def __init__(self, target=None): |
124 self.target = target | |
131 self.output = [] | 125 self.output = [] |
132 # Construct a parser given a grammar: | 126 # Construct a parser given a grammar: |
133 ident = lambda x: x # Identity helper function | 127 ident = lambda x: x # Identity helper function |
134 g = pyyacc.Grammar(['ID', 'NUMBER', ',', '[', ']', ':', '+', '-', '*', pyyacc.EPS, 'COMMENT']) | 128 g = pyyacc.Grammar(['ID', 'NUMBER', ',', '[', ']', ':', '+', '-', '*', pyyacc.EPS, 'COMMENT']) |
135 g.add_production('asmline', ['asmline2']) | 129 g.add_production('asmline', ['asmline2']) |
172 assert type(ops) is list | 166 assert type(ops) is list |
173 ops.append(op2) | 167 ops.append(op2) |
174 return ops | 168 return ops |
175 def p_mem_op(self, brace_open, exp, brace_close): | 169 def p_mem_op(self, brace_open, exp, brace_close): |
176 return AUnop('[]', exp) | 170 return AUnop('[]', exp) |
177 def handle_ins(self, id0, operands): | |
178 ins = AInstruction(id0) | |
179 self.emit(ins) | |
180 def p_label(self, lname, cn): | 171 def p_label(self, lname, cn): |
181 lab = ALabel(lname) | 172 lab = ALabel(lname) |
182 self.emit(lab) | 173 self.emit(lab) |
183 def p_binop(self, exp1, op, exp2): | 174 def p_binop(self, exp1, op, exp2): |
184 return ABinop(op, exp1, exp2) | 175 return ABinop(op, exp1, exp2) |
187 def p_number(self, n): | 178 def p_number(self, n): |
188 n = int(n) | 179 n = int(n) |
189 return ANumber(n) | 180 return ANumber(n) |
190 | 181 |
191 # Top level interface: | 182 # Top level interface: |
183 def restart(self): | |
184 pass | |
185 | |
192 def emit(self, a): | 186 def emit(self, a): |
193 """ Emit a parsed instruction """ | 187 """ Emit a parsed instruction """ |
194 self.output.append(a) | 188 self.output.append(a) |
195 # Determine the bit pattern from a lookup table: | 189 # Determine the bit pattern from a lookup table: |
196 # TODO | 190 # TODO |
215 self.parse_line(line) | 209 self.parse_line(line) |
216 self.assemble_aast() | 210 self.assemble_aast() |
217 | 211 |
218 def assemble_aast(self): | 212 def assemble_aast(self): |
219 """ Assemble a parsed asm line """ | 213 """ Assemble a parsed asm line """ |
220 pass | 214 # TODO |
215 if not self.target: | |
216 raise CompilerError('Cannot assemble without target') | |
217 while self.output: | |
218 i = self.output.pop(0) | |
219 self.target.createInstruction(i) | |
221 | 220 |
222 def back_patch(self): | 221 def back_patch(self): |
223 """ Fix references to earlier labels """ | 222 """ Fix references to earlier labels """ |
224 pass | 223 pass |
225 | 224 |