annotate python/ppci/irutils.py @ 321:8c569fbe60e4

Load yacc and burg dynamic
author Windel Bouwman
date Sun, 19 Jan 2014 18:48:45 +0100
parents e84047f29c78
children 988f3fb861e4
rev   line source
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
1
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
2 """
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
3 Some utilities for ir-code.
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
4 """
309
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
5 import re
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
6 from . import ir
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
7
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
8 def dumpgv(m, outf):
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
9 print('digraph G ', file=outf)
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
10 print('{', file=outf)
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
11 for f in m.Functions:
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
12 print('{} [label="{}" shape=box3d]'.format(id(f), f), file=outf)
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
13 for bb in f.Blocks:
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
14 contents = str(bb) + '\n'
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
15 contents += '\n'.join([str(i) for i in bb.Instructions])
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
16 print('{0} [shape=note label="{1}"];'
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
17 .format(id(bb), contents), file=outf)
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
18 for successor in bb.Successors:
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
19 print('"{}" -> "{}"'.format(id(bb), id(successor)), file=outf)
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
20
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
21 print('"{}" -> "{}" [label="entry"]'
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
22 .format(id(f), id(f.entry)), file=outf)
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
23 print('}', file=outf)
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
24
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
25
309
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
26 class Writer:
312
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
27 def __init__(self, extra_indent=''):
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
28 self.extra_indent = extra_indent
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
29
309
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
30 def write(self, ir, f):
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
31 """ Write ir-code to file f """
312
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
32 print('{}{}'.format(self.extra_indent, ir), file=f)
309
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
33 for v in ir.Variables:
312
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
34 print('{}{}'.format(self.extra_indent, v), file=f)
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
35 for function in ir.Functions:
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
36 self.write_function(function, f)
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
37
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
38 def write_function(self, fn, f):
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
39 args = ','.join('i32 ' + str(a) for a in fn.arguments)
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
40 print('{}function i32 {}({})'.format(self.extra_indent, fn.name, args), file=f)
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
41 for bb in fn.Blocks:
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
42 print('{} {}'.format(self.extra_indent, bb), file=f)
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
43 for ins in bb.Instructions:
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
44 print('{} {}'.format(self.extra_indent, ins), file=f)
309
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
45
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
46
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
47 class IrParseException(Exception):
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
48 pass
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
49
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
50
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
51 class Reader:
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
52 def read(self, f):
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
53 """ Read ir code from file f """
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
54 # Read lines from the file:
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
55 lines = [line.rstrip() for line in f]
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
56
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
57 # Create a regular expression for the lexing part:
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
58 tok_spec = [
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
59 ('NUMBER', r'\d+'),
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
60 ('ID', r'[A-Za-z][A-Za-z\d_]*'),
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
61 ('SKIP2', r' '),
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
62 ('SKIP1', r' '),
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
63 ('OTHER', r'[\.,=:;\-+*\[\]/\(\)]|>|<|{|}|&|\^|\|')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
64 ]
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
65 tok_re = '|'.join('(?P<%s>%s)' % pair for pair in tok_spec)
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
66 gettok = re.compile(tok_re).match
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
67
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
68 def tokenize():
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
69 for line in lines:
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
70 if not line:
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
71 continue # Skip empty lines
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
72 mo = gettok(line)
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
73 first = True
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
74 while mo:
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
75 typ = mo.lastgroup
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
76 val = mo.group(typ)
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
77 if typ == 'ID':
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
78 if val in ['function', 'module']:
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
79 typ = val
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
80 yield (typ, val)
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
81 elif typ == 'OTHER':
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
82 typ = val
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
83 yield (typ, val)
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
84 elif typ in ['SKIP1', 'SKIP2']:
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
85 if first:
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
86 yield (typ, val)
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
87 elif typ == 'NUMBER':
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
88 yield (typ, int(val))
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
89 else:
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
90 raise NotImplementedError(str(typ))
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
91 first = False
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
92 pos = mo.end()
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
93 mo = gettok(line, pos)
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
94 if len(line) != pos:
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
95 raise IrParseException('Lex fault')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
96 yield ('eol', 'eol')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
97 yield ('eof', 'eof')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
98 self.tokens = tokenize()
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
99 self.token = self.tokens.__next__()
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
100
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
101 try:
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
102 module = self.parse_module()
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
103 return module
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
104 except IrParseException as e:
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
105 print(e)
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
106
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
107 def next_token(self):
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
108 t = self.token
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
109 if t[0] != 'eof':
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
110 self.token = self.tokens.__next__()
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
111 return t
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
112
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
113 @property
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
114 def Peak(self):
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
115 return self.token[0]
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
116
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
117 def Consume(self, typ):
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
118 if self.Peak == typ:
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
119 return self.next_token()
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
120 else:
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
121 raise IrParseException('Expected "{}" got "{}"'.format(typ, self.Peak))
318
e84047f29c78 Add burg and yacc initial attempts
Windel Bouwman
parents: 317
diff changeset
122
309
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
123 def parse_module(self):
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
124 """ Entry for recursive descent parser """
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
125 self.Consume('module')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
126 name = self.Consume('ID')[1]
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
127 module = ir.Module(name)
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
128 self.Consume('eol')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
129 while self.Peak != 'eof':
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
130 if self.Peak == 'function':
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
131 module.add_function(self.parse_function())
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
132 else:
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
133 raise IrParseException('Expected function got {}'.format(self.Peak))
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
134 return module
318
e84047f29c78 Add burg and yacc initial attempts
Windel Bouwman
parents: 317
diff changeset
135
309
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
136 def parse_function(self):
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
137 self.Consume('function')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
138 self.parse_type()
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
139 name = self.Consume('ID')[1]
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
140 function = ir.Function(name)
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
141 self.Consume('(')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
142 while self.Peak != ')':
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
143 self.parse_type()
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
144 self.Consume('ID')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
145 if self.Peak != ',':
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
146 break
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
147 else:
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
148 self.Consume(',')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
149 self.Consume(')')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
150 self.Consume('eol')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
151 while self.Peak == 'SKIP1':
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
152 function.add_block(self.parse_block())
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
153 return function
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
154
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
155 def parse_type(self):
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
156 self.Consume('ID')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
157
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
158 def parse_block(self):
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
159 self.Consume('SKIP1')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
160 name = self.Consume('ID')[1]
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
161 block = ir.Block(name)
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
162 self.Consume(':')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
163 self.Consume('eol')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
164 while self.Peak == 'SKIP2':
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
165 self.parse_statement()
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
166 return block
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
167
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
168 def parse_statement(self):
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
169 self.Consume('SKIP2')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
170 while self.Peak != 'eol':
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
171 # raise NotImplementedError()
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
172 self.next_token()
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
173 self.Consume('eol')
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
174
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
175
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
176 # Constructing IR:
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
177
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
178 class NamedClassGenerator:
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
179 def __init__(self, prefix, cls):
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
180 self.prefix = prefix
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
181 self.cls = cls
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
182
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
183 def NumGen():
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
184 a = 0
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
185 while True:
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
186 yield a
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
187 a = a + 1
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
188 self.nums = NumGen()
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
189
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
190 def gen(self, prefix=None):
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
191 if not prefix:
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
192 prefix = self.prefix
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
193 return self.cls('{0}{1}'.format(prefix, self.nums.__next__()))
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
194
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
195
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
196 class Builder:
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
197 """ Base class for ir code generators """
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
198 def __init__(self):
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
199 self.prepare()
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
200
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
201 def prepare(self):
312
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
202 self.newTemp = NamedClassGenerator('reg', ir.Temp).gen
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
203 self.newBlock2 = NamedClassGenerator('block', ir.Block).gen
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
204 self.bb = None
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
205 self.m = None
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
206 self.fn = None
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
207 self.loc = None
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
208
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
209 # Helpers:
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
210 def setModule(self, m):
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
211 self.m = m
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
212
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
213 def newFunction(self, name):
312
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
214 f = ir.Function(name)
309
68b01c8abf8a Added start of ir read and write
Windel Bouwman
parents: 307
diff changeset
215 self.m.add_function(f)
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
216 return f
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
217
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
218 def newBlock(self):
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
219 assert self.fn
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
220 b = self.newBlock2()
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
221 b.function = self.fn
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
222 return b
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
223
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
224 def setFunction(self, f):
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
225 self.fn = f
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
226 self.bb = f.entry if f else None
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
227
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
228 def setBlock(self, b):
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
229 self.bb = b
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
230
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
231 def setLoc(self, l):
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
232 self.loc = l
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
233
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
234 def emit(self, i):
312
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
235 assert isinstance(i, ir.Statement)
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
236 i.debugLoc = self.loc
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
237 if not self.bb:
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
238 raise Exception('No basic block')
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents:
diff changeset
239 self.bb.addInstruction(i)
312
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
240
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
241
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
242 class Verifier:
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
243 def verify(self, module):
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
244 """ Verifies a module for some sanity """
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
245 assert isinstance(module, ir.Module)
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
246 for f in module.Functions:
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
247 self.verify_function(f)
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
248
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
249 def verify_function(self, function):
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
250 for b in function.Blocks:
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
251 self.verify_block_termination(b)
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
252
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
253 # Now we can build a dominator tree
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
254 for b in function.Blocks:
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
255 self.verify_block(b)
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
256
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
257 def verify_block_termination(self, block):
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
258 assert not block.Empty
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
259 assert block.LastInstruction.IsTerminator
317
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 312
diff changeset
260 for i in block.Instructions[:-1]:
e30a77ae359b Added glue blocks
Windel Bouwman
parents: 312
diff changeset
261 assert not isinstance(i, ir.LastStatement)
318
e84047f29c78 Add burg and yacc initial attempts
Windel Bouwman
parents: 317
diff changeset
262
312
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
263 def verify_block(self, block):
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
264 for instruction in block.Instructions:
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
265 self.verify_instruction(instruction)
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
266
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
267 def verify_instruction(self, instruction):
2c9768114877 Added cool logging formatter
Windel Bouwman
parents: 309
diff changeset
268 pass