annotate python/libasm.py @ 159:5e1dd04cb61c

Added attempt to assembler
author Windel Bouwman
date Fri, 08 Mar 2013 17:16:22 +0100
parents
children 6b2bec5653f1
rev   line source
159
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
1 import collections, re
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
2
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
3 # Different instruction sets:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
4 class InstructionSet:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
5 pass
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
6
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
7 class X86(InstructionSet):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
8 pass
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
9
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
10 # Generic assembler:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
11
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
12 class SourceLocation:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
13 def __init__(self, x):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
14 self.pos = x
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
15
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
16 class SourceRange:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
17 def __init__(self, p1, p2):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
18 self.p1 = p1
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
19 self.p2 = p2
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
20
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
21 # Token is used in the lexical analyzer:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
22 Token = collections.namedtuple('Token', 'typ val row col')
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
23
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
24 keywords = ['global', 'db']
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
25
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
26 def tokenize(s):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
27 """
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
28 Tokenizer, generates an iterator that
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
29 returns tokens!
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
30
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
31 This GREAT example was taken from python re doc page!
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
32 """
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
33 tok_spec = [
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
34 ('REAL', r'\d+\.\d+'),
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
35 ('HEXNUMBER', r'0x[\da-fA-F]+'),
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
36 ('NUMBER', r'\d+'),
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
37 ('ID', r'[A-Za-z][A-Za-z\d_]*'),
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
38 ('NEWLINE', r'\n'),
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
39 ('SKIP', r'[ \t]'),
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
40 ('LEESTEKEN', r':=|[\.,=:;\-+*\[\]/\(\)]|>=|<=|<>|>|<'),
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
41 ('STRING', r"'.*?'")
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
42 ]
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
43 tok_re = '|'.join('(?P<%s>%s)' % pair for pair in tok_spec)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
44 print(tok_re)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
45 gettok = re.compile(tok_re).match
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
46 line = 1
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
47 pos = line_start = 0
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
48 mo = gettok(s)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
49 while mo is not None:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
50 typ = mo.lastgroup
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
51 val = mo.group(typ)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
52 if typ == 'NEWLINE':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
53 line_start = pos
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
54 line += 1
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
55 elif typ == 'COMMENTS':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
56 pass
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
57 elif typ != 'SKIP':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
58 if typ == 'ID':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
59 if val in keywords:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
60 typ = val
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
61 elif typ == 'LEESTEKEN':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
62 typ = val
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
63 elif typ == 'NUMBER':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
64 val = int(val)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
65 elif typ == 'HEXNUMBER':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
66 val = int(val[2:], 16)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
67 typ = 'NUMBER'
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
68 elif typ == 'REAL':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
69 val = float(val)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
70 elif typ == 'STRING':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
71 val = val[1:-1]
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
72 yield Token(typ, val, line, mo.start()-line_start)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
73 pos = mo.end()
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
74 mo = gettok(s, pos)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
75 if pos != len(s):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
76 col = pos - line_start
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
77 raise CompilerException('Unexpected character {0}'.format(s[pos]), line, col)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
78 yield Token('END', '', line, 0)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
79
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
80 class Lexer:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
81 def __init__(self, src):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
82 self.tokens = tokenize(src)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
83 self.curTok = self.tokens.__next__()
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
84 def eat(self):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
85 t = self.curTok
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
86 self.curTok = self.tokens.__next__()
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
87 return t
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
88 @property
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
89 def Peak(self):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
90 return self.curTok
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
91
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
92 class Parser:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
93 def __init__(self, lxr):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
94 self.lxr = lxr
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
95 def parse(self):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
96 t = self.lxr.eat()
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
97
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
98 while True:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
99 ins = self.parseLine()
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
100 print(ins)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
101 t = self.lxr.eat()
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
102 def parseLine(self):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
103 self.parseLabel()
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
104 if self.lxr.Peak == ';':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
105 self.eatComments()
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
106 def parseLabel(self):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
107 i = self.lxr.eat()
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
108
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
109 class Assembler:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
110 def assemble(self, asmsrc):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
111 print('assembling', asmsrc)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
112 lxr = Lexer(asmsrc)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
113 prsr = Parser(lxr)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
114 instructions = prsr.parse()
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
115 return instructions
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
116