annotate python/libasm.py @ 194:b01429a5d695

Fixed test
author Windel Bouwman
date Wed, 29 May 2013 22:36:37 +0200
parents f091e7d70996
children 37ac6c016e0f
rev   line source
191
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
1 import re
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
2 import pyyacc
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
3 from ppci import Token, CompilerError, SourceLocation
159
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
4
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
5 # Different instruction sets:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
6 class InstructionSet:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
7 pass
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
8
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
9 class X86(InstructionSet):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
10 pass
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
11
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
12 # Generic assembler:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
13 keywords = ['global', 'db']
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
14
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
15 def tokenize(s):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
16 """
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
17 Tokenizer, generates an iterator that
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
18 returns tokens!
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
19
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
20 This GREAT example was taken from python re doc page!
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
21 """
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
22 tok_spec = [
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
23 ('REAL', r'\d+\.\d+'),
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
24 ('HEXNUMBER', r'0x[\da-fA-F]+'),
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
25 ('NUMBER', r'\d+'),
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
26 ('ID', r'[A-Za-z][A-Za-z\d_]*'),
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
27 ('SKIP', r'[ \t]'),
191
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
28 ('LEESTEKEN', r':=|[\.,=:\-+*\[\]/\(\)]|>=|<=|<>|>|<'),
159
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
29 ('STRING', r"'.*?'")
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
30 ]
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
31 tok_re = '|'.join('(?P<%s>%s)' % pair for pair in tok_spec)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
32 gettok = re.compile(tok_re).match
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
33 line = 1
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
34 pos = line_start = 0
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
35 mo = gettok(s)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
36 while mo is not None:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
37 typ = mo.lastgroup
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
38 val = mo.group(typ)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
39 if typ == 'NEWLINE':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
40 line_start = pos
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
41 line += 1
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
42 elif typ == 'COMMENTS':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
43 pass
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
44 elif typ != 'SKIP':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
45 if typ == 'ID':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
46 if val in keywords:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
47 typ = val
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
48 elif typ == 'LEESTEKEN':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
49 typ = val
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
50 elif typ == 'NUMBER':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
51 val = int(val)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
52 elif typ == 'HEXNUMBER':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
53 val = int(val[2:], 16)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
54 typ = 'NUMBER'
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
55 elif typ == 'REAL':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
56 val = float(val)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
57 elif typ == 'STRING':
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
58 val = val[1:-1]
191
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
59 col = mo.start() - line_start
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
60 loc = SourceLocation(line, col, 0) # TODO retrieve length?
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
61 yield Token(typ, val, loc)
159
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
62 pos = mo.end()
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
63 mo = gettok(s, pos)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
64 if pos != len(s):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
65 col = pos - line_start
191
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
66 loc = SourceLocation(line, col, 0)
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
67 raise CompilerError('Unexpected character {0}'.format(s[pos]), loc)
159
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
68
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
69 class Lexer:
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
70 def __init__(self, src):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
71 self.tokens = tokenize(src)
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
72 self.curTok = self.tokens.__next__()
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
73 def eat(self):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
74 t = self.curTok
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
75 self.curTok = self.tokens.__next__()
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
76 return t
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
77 @property
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
78 def Peak(self):
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
79 return self.curTok
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
80
191
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
81 class Assembler:
194
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
82 def handle_ins(self, id0):
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
83 self.ins = id0
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
84 def p_label(self, lname, cn):
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
85 self.label = lname
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
86
191
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
87 def __init__(self):
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
88 # Construct a parser given a grammar:
193
f091e7d70996 Added even more checks
Windel Bouwman
parents: 191
diff changeset
89 g = pyyacc.Grammar(['ID', 'NUMBER', ',', '[', ']', ':', '+', '-', pyyacc.EPS])
159
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
90
191
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
91 g.add_production('asmline', ['label', 'instruction', 'operands'])
194
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
92 g.add_production('asmline', ['instruction', 'operands'])
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
93 g.add_production('label', ['ID', ':'], self.p_label)
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
94 g.add_production('instruction', ['ID'], self.handle_ins)
191
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
95 g.add_production('operands', ['operand'])
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
96 g.add_production('operands', ['operands', ',', 'operand'])
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
97 g.add_production('operand', ['expression'])
193
f091e7d70996 Added even more checks
Windel Bouwman
parents: 191
diff changeset
98 g.add_production('operand', ['[', 'expression', ']'])
f091e7d70996 Added even more checks
Windel Bouwman
parents: 191
diff changeset
99 g.add_production('expression', ['term'])
f091e7d70996 Added even more checks
Windel Bouwman
parents: 191
diff changeset
100 g.add_production('expression', ['expression', 'addop', 'term'])
f091e7d70996 Added even more checks
Windel Bouwman
parents: 191
diff changeset
101 g.add_production('addop', ['-'])
f091e7d70996 Added even more checks
Windel Bouwman
parents: 191
diff changeset
102 g.add_production('addop', ['+'])
f091e7d70996 Added even more checks
Windel Bouwman
parents: 191
diff changeset
103 g.add_production('term', ['factor'])
f091e7d70996 Added even more checks
Windel Bouwman
parents: 191
diff changeset
104 g.add_production('factor', ['ID'])
f091e7d70996 Added even more checks
Windel Bouwman
parents: 191
diff changeset
105 g.add_production('factor', ['NUMBER'])
191
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
106 # TODO: expand grammar
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
107 g.start_symbol = 'asmline'
159
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
108
191
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
109 self.p = g.genParser()
194
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
110 def parse_line(self, line):
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
111 """ Parse line into asm AST """
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
112 tokens = tokenize(line)
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
113 self.p.parse(tokens)
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
114 aast = 1 # TODO
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
115 return aast
191
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
116
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
117 def assemble(self, asmsrc):
194
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
118 lxr = Lexer(asmsrc)
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
119 prsr = Parser(lxr)
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
120 instructions = prsr.parse()
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
121 return instructions
159
5e1dd04cb61c Added attempt to assembler
Windel Bouwman
parents:
diff changeset
122
191
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
123 def assembleLine(self, line):
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
124 """
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
125 Assemble a single source line.
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
126 Do not take newlines into account
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
127 """
194
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
128 aast = self.parseLine(line)
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
129 self.assemble_aast(aast)
191
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
130
194
b01429a5d695 Fixed test
Windel Bouwman
parents: 193
diff changeset
131 def assemble_aast(self, at):
191
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
132 """ Assemble a parsed asm line """
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
133 pass
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
134
6b2bec5653f1 Added assembler testset
Windel Bouwman
parents: 159
diff changeset
135