Mercurial > lcfOS
diff 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 |
line wrap: on
line diff
--- a/python/asm.py Fri Jun 07 18:59:57 2013 +0200 +++ b/python/asm.py Sun Jun 09 16:06:49 2013 +0200 @@ -2,6 +2,7 @@ import pyyacc from ppci import Token, CompilerError, SourceLocation from target import Target +from asmnodes import ALabel, AInstruction, ABinop, AUnop, ASymbol, ANumber def tokenize(s): """ @@ -65,64 +66,11 @@ def Peak(self): return self.curTok -class ANode: - def __eq__(self, other): - return self.__repr__() == other.__repr__() - -class ALabel(ANode): - def __init__(self, name): - self.name = name - def __repr__(self): - return '{0}:'.format(self.name) - -class AInstruction(ANode): - def __init__(self, opcode, operands): - self.opcode = opcode - self.operands = operands - def __repr__(self): - ops = ', '.join(map(str, self.operands)) - return '{0} {1}'.format(self.opcode, ops) - -class AExpression(ANode): - def __add__(self, other): - assert isinstance(other, AExpression) - return ABinop('+', self, other) - def __mul__(self, other): - assert isinstance(other, AExpression) - return ABinop('*', self, other) - -class ABinop(AExpression): - def __init__(self, op, arg1, arg2): - self.op = op - self.arg1 = arg1 - self.arg2 = arg2 - def __repr__(self): - return '{0} {1} {2}'.format(self.op, self.arg1, self.arg2) - -class AUnop(AExpression): - def __init__(self, op, arg): - self.op = op - self.arg = arg - def __repr__(self): - return '{0} {1}'.format(self.op, self.arg) - -class ASymbol(AExpression): - def __init__(self, name): - self.name = name - def __repr__(self): - return self.name - -class ANumber(AExpression): - def __init__(self, n): - assert type(n) is int - self.n = n - def __repr__(self): - return '{0}'.format(self.n) class Assembler: def __init__(self, target=None): self.target = target - self.output = [] + self.restart() # Construct a parser given a grammar: ident = lambda x: x # Identity helper function g = pyyacc.Grammar(['ID', 'NUMBER', ',', '[', ']', ':', '+', '-', '*', pyyacc.EPS, 'COMMENT']) @@ -149,8 +97,8 @@ g.add_production('mulop', ['*'], ident) g.add_production('term', ['factor'], ident) g.add_production('term', ['term', 'mulop', 'factor'], self.p_binop) - g.add_production('factor', ['ID'], self.p_symbol) - g.add_production('factor', ['NUMBER'], self.p_number) + g.add_production('factor', ['ID'], lambda name: ASymbol(name)) + g.add_production('factor', ['NUMBER'], lambda num: ANumber(int(num))) g.start_symbol = 'asmline' self.p = g.genParser() @@ -173,15 +121,12 @@ self.emit(lab) def p_binop(self, exp1, op, exp2): return ABinop(op, exp1, exp2) - def p_symbol(self, name): - return ASymbol(name) - def p_number(self, n): - n = int(n) - return ANumber(n) # Top level interface: def restart(self): - pass + self.output = [] + self.binout = bytearray() + self.current_section = '.text' def emit(self, a): """ Emit a parsed instruction """ @@ -189,7 +134,6 @@ # Determine the bit pattern from a lookup table: # TODO - def parse_line(self, line): """ Parse line into asm AST """ tokens = tokenize(line) @@ -215,8 +159,11 @@ if not self.target: raise CompilerError('Cannot assemble without target') while self.output: - i = self.output.pop(0) - self.target.createInstruction(i) + vi = self.output.pop(0) + ri = self.target.mapInstruction(vi) + b = ri.encode() + assert type(b) is bytes + self.binout.extend(b) def back_patch(self): """ Fix references to earlier labels """