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 """