Mercurial > lcfOS
comparison python/asm.py @ 236:8786811a5a59
Fix pcrel
author | Windel Bouwman |
---|---|
date | Mon, 15 Jul 2013 20:15:31 +0200 |
parents | ff40407c0240 |
children | 1c7c1e619be8 |
comparison
equal
deleted
inserted
replaced
235:ff40407c0240 | 236:8786811a5a59 |
---|---|
1 import re, argparse | 1 import re, 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, Label |
5 from asmnodes import ALabel, AInstruction, ABinop, AUnop, ASymbol, ANumber | 5 from asmnodes import ALabel, AInstruction, ABinop, AUnop, ASymbol, ANumber |
6 | 6 |
7 def tokenize(s): | 7 def tokenize(s): |
8 """ | 8 """ |
9 Tokenizer, generates an iterator that | 9 Tokenizer, generates an iterator that |
139 | 139 |
140 # Pre construct parser to save time: | 140 # Pre construct parser to save time: |
141 asmParser = Parser() | 141 asmParser = Parser() |
142 | 142 |
143 class Assembler: | 143 class Assembler: |
144 def __init__(self, target=None): | 144 def __init__(self, target=None, stream=None): |
145 self.target = target | 145 self.target = target |
146 self.stream = stream | |
146 self.restart() | 147 self.restart() |
147 self.p = asmParser | 148 self.p = asmParser |
148 | 149 |
149 # Top level interface: | 150 # Top level interface: |
150 def restart(self): | 151 def restart(self): |
151 self.output = [] | 152 self.stack = [] |
152 self.binout = bytearray() | |
153 self.current_section = '.text' | |
154 | 153 |
155 def emit(self, a): | 154 def emit(self, a): |
156 """ Emit a parsed instruction """ | 155 """ Emit a parsed instruction """ |
157 self.output.append(a) | 156 self.stack.append(a) |
158 # Determine the bit pattern from a lookup table: | |
159 # TODO | |
160 | 157 |
161 def parse_line(self, line): | 158 def parse_line(self, line): |
162 """ Parse line into asm AST """ | 159 """ Parse line into asm AST """ |
163 tokens = tokenize(line) | 160 tokens = tokenize(line) |
164 self.p.parse(tokens, self.emit) | 161 self.p.parse(tokens, self.emit) |
165 | 162 |
166 def assemble(self, asmsrc): | 163 def assemble(self, asmsrc): |
167 """ Assemble this source snippet """ | 164 """ Assemble this source snippet """ |
168 for line in asmsrc.split('\n'): | 165 for line in asmsrc.split('\n'): |
169 self.assemble_line(line) | 166 self.assemble_line(line) |
170 self.back_patch() | |
171 | 167 |
172 def assemble_line(self, line): | 168 def assemble_line(self, line): |
173 """ | 169 """ |
174 Assemble a single source line. | 170 Assemble a single source line. |
175 Do not take newlines into account | 171 Do not take newlines into account |
180 def assemble_aast(self): | 176 def assemble_aast(self): |
181 """ Assemble a parsed asm line """ | 177 """ Assemble a parsed asm line """ |
182 # TODO | 178 # TODO |
183 if not self.target: | 179 if not self.target: |
184 raise CompilerError('Cannot assemble without target') | 180 raise CompilerError('Cannot assemble without target') |
185 while self.output: | 181 while self.stack: |
186 vi = self.output.pop(0) | 182 vi = self.stack.pop(0) |
187 if type(vi) is AInstruction: | 183 if type(vi) is AInstruction: |
188 ri = self.target.mapInstruction(vi) | 184 mi = self.target.mapInstruction(vi) |
189 b = ri.encode() | 185 elif type(vi) is ALabel: |
190 assert type(b) is bytes | 186 mi = Label(vi.name) |
191 self.binout.extend(b) | 187 else: |
192 | 188 raise NotImplementedError('{}'.format(vi)) |
193 def back_patch(self): | 189 if self.stream: |
194 """ Fix references to earlier labels """ | 190 self.stream.emit(mi) |
195 pass | |
196 #self.output.backpatch() | |
197 | 191 |
198 | 192 |
199 if __name__ == '__main__': | 193 if __name__ == '__main__': |
200 # When run as main file, try to grab command line arguments: | 194 # When run as main file, try to grab command line arguments: |
201 parser = argparse.ArgumentParser(description="Assembler") | 195 parser = argparse.ArgumentParser(description="Assembler") |