changeset 196:ec2b423cdbea

Merge asm and asmlib files
author Windel Bouwman
date Sat, 01 Jun 2013 11:55:49 +0200
parents 37ac6c016e0f
children 4a1ca1271241
files python/asm.py python/libasm.py python/testasm.py
diffstat 3 files changed, 44 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/python/asm.py	Fri May 31 21:06:44 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-#!/usr/bin/python
-
-# Assembler
-
-import sys, argparse
-import pdb
-
-import libasm
-
-parser = argparse.ArgumentParser(description="Assembler")
-pdb.set_trace()
-parser.add_argument('sourcefile', type=argparse.FileType('r'), help='the source file to assemble')
-args = parser.parse_args()
-
-
-a = libasm.Assembler()
-obj = a.assemble(args.sourcefile.read())
-
-print('object:', obj)
-
--- a/python/libasm.py	Fri May 31 21:06:44 2013 +0200
+++ b/python/libasm.py	Sat Jun 01 11:55:49 2013 +0200
@@ -1,6 +1,8 @@
 import re
 import pyyacc
 from ppci import Token, CompilerError, SourceLocation
+import sys, argparse
+
 
 # Different instruction sets:
 class InstructionSet:
@@ -98,8 +100,10 @@
 
 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):
@@ -138,6 +142,7 @@
         g.add_production('asmline', ['label', 'instruction'])
         g.add_production('asmline', ['instruction'])
         g.add_production('asmline', ['label'])
+        g.add_production('asmline', [])
         g.add_production('label', ['ID', ':'], self.p_label)
         g.add_production('instruction', ['opcode', 'operands'], self.p_ins_1)
         g.add_production('instruction', ['opcode'], self.p_ins_2)
@@ -186,33 +191,47 @@
         n = int(n)
         return ANumber(n)
 
-    # Top level:
+    # Top level interface:
     def emit(self, a):
+        """ Emit a parsed instruction """
         self.output.append(a)
+        # Determine the bit pattern from a lookup table:
+        # TODO
+
 
     def parse_line(self, line):
         """ Parse line into asm AST """
         tokens = tokenize(line)
         self.p.parse(tokens)
-        aast = 1 # TODO
-        return aast
 
     def assemble(self, asmsrc):
-        lxr = Lexer(asmsrc)
-        prsr = Parser(lxr)
-        instructions = prsr.parse()
-        return instructions
+        """ Assemble this source snippet """
+        for line in asmsrc.split('\n'):
+            self.assemble_line(line)
+        self.back_patch()
 
-    def assembleLine(self, line):
+    def assemble_line(self, line):
         """ 
             Assemble a single source line. 
             Do not take newlines into account 
         """
-        aast = self.parseLine(line)
-        self.assemble_aast(aast)
+        self.parse_line(line)
+        self.assemble_aast()
 
     def assemble_aast(self, at):
         """ Assemble a parsed asm line """
         pass
 
+    def back_patch(self):
+        """ Fix references to earlier labels """
+        pass
 
+
+if __name__ == '__main__':
+    # When run as main file, try to grab command line arguments:
+    parser = argparse.ArgumentParser(description="Assembler")
+    parser.add_argument('sourcefile', type=argparse.FileType('r'), help='the source file to assemble')
+    args = parser.parse_args()
+    a = Assembler()
+    obj = a.assemble(args.sourcefile.read())
+
--- a/python/testasm.py	Fri May 31 21:06:44 2013 +0200
+++ b/python/testasm.py	Sat Jun 01 11:55:49 2013 +0200
@@ -77,10 +77,23 @@
         output = []
         output.append(ALabel('lab1'))
         self.assertSequenceEqual(output, a.output)
+
+    def testParse6(self):
+        # A line can be empty
+        a = libasm.Assembler()
+        a.parse_line('')
     
     def testX86(self):
-        # TODO
-        pass
+        testsrc = """
+        begin:
+        mov rax, rbx
+        xor rcx, rbx
+        inc rcx
+        """
+        a = libasm.Assembler()
+        a.assemble(testsrc)
+        # Compare with nasm output:
+        nasmbytes = [0x48, 0x89, 0xd8, 0x48, 0x31, 0xd9, 0x48, 0xff, 0xc1]
 
 if __name__ == '__main__':
     unittest.main()