crokus 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,109 @@
1
+ module Crokus
2
+
3
+ class TACBuilder < Transformer
4
+
5
+ OP_ASSIGN=Token.new([:assign,"=",[0,0]])
6
+
7
+ def visitFunction func,args=nil
8
+ puts " |--> tac builder for '#{func.name}'"
9
+ build func.cfg
10
+ end
11
+
12
+ def build cfg
13
+ bb0=cfg.starter
14
+ @tmp_id=0
15
+ @visited=[]
16
+ visit_rec(bb0)
17
+ cfg.name="tac_#{cfg.name}"
18
+ cfg.print
19
+ end
20
+
21
+ def new_tmp
22
+ tok=Token.create "$"+@tmp_id.to_s
23
+ @tmp_id+=1
24
+ tok
25
+ end
26
+
27
+ def visit_rec bb
28
+ @visited << bb
29
+ @current=bb
30
+ @new_stmts=[]
31
+ @post_stmts=[]
32
+ bb.stmts.each do |stmt|
33
+ @new_stmts << stmt.accept(self)
34
+ end
35
+ bb.stmts=@new_stmts
36
+ bb.stmts << @post_stmts
37
+ bb.stmts.flatten!
38
+ bb.succs.each do |bb|
39
+ unless @visited.include? bb
40
+ visit_rec(bb)
41
+ end
42
+ end
43
+ end
44
+
45
+ def visitAssign assign,args=nil
46
+ assign_1= super(assign)
47
+ if assign_1.lhs.is_a? Indexed
48
+ if (rhs=assign_1.rhs).is_a? Indexed
49
+ rhs=rhs.accept(self)
50
+ tmp=new_tmp()
51
+ @new_stmts << Assign.new(tmp,OP_ASSIGN,rhs)
52
+ assign_1.rhs=tmp
53
+ end
54
+ end
55
+ unless assign.op.kind==:assign
56
+ rhs=assign_1.rhs
57
+ rhs.accept(self)
58
+ tmp=new_tmp()
59
+ @new_stmts << Assign.new(tmp,OP_ASSIGN,rhs)
60
+ assign_1.rhs=tmp
61
+ end
62
+ assign_1
63
+ end
64
+
65
+ def visitITE ite,args=nil
66
+ ret=ITE.new(ite.cond,ite.trueBranch,ite.falseBranch)
67
+ if ite.cond.is_a?(Binary)
68
+ cond=ite.cond.accept(self)
69
+ tmp=new_tmp()
70
+ @new_stmts << Assign.new(tmp,OP_ASSIGN,cond)
71
+ ret.cond=tmp
72
+ end
73
+ ret
74
+ end
75
+
76
+ def visitBinary bin,args=nil
77
+ ret=Binary.new(bin.lhs,bin.op,bin.rhs)
78
+ ret.lhs=bin.lhs.accept(self)
79
+ if bin.lhs.respond_to? :lhs #Binary,Indexed,etc
80
+ #lhs=bin.lhs.accept(self)
81
+ tmp=new_tmp()
82
+ @new_stmts << Assign.new(tmp,OP_ASSIGN,lhs)
83
+ ret.lhs=tmp
84
+ end
85
+ ret.rhs=bin.rhs.accept(self)
86
+ if bin.rhs.respond_to? :lhs #Binary,Indexed,etc
87
+ # rhs=bin.rhs.accept()
88
+ tmp=new_tmp()
89
+ @new_stmts << Assign.new(tmp,OP_ASSIGN,rhs)
90
+ ret.rhs=tmp
91
+ end
92
+ return ret
93
+ end
94
+
95
+ def visitIndexed idx,args=nil
96
+ lhs=idx.lhs.accept(self)
97
+ ret=Indexed.new(lhs,idx.rhs)
98
+ if idx.rhs.respond_to? :lhs # WARNING : Indexed! Pointed! etc
99
+ lhs=idx.rhs.accept(self)
100
+ tmp=new_tmp()
101
+ @new_stmts << Assign.new(tmp,OP_ASSIGN,lhs)
102
+ ret.rhs=tmp
103
+ end
104
+ return ret
105
+ end
106
+
107
+
108
+ end
109
+ end
@@ -0,0 +1,43 @@
1
+ class Token
2
+ attr_accessor :kind,:val,:pos
3
+ def initialize tab
4
+ @kind,@val,@pos=*tab
5
+ end
6
+
7
+ def is_a? kind
8
+ case kind
9
+ when Symbol
10
+ return @kind==kind
11
+ when Array
12
+ for sym in kind
13
+ return true if @kind==sym
14
+ end
15
+ return false
16
+ else
17
+ raise "wrong type during lookahead"
18
+ end
19
+ end
20
+
21
+ def accept visitor,arg=nil
22
+ visitor.visitToken(self,arg)
23
+ end
24
+
25
+ def self.create str
26
+ Token.new [:id,str,[0,0]]
27
+ end
28
+
29
+ def to_s
30
+ val
31
+ end
32
+
33
+ def inspect
34
+ "(#{kind},#{val},#{pos})"
35
+ end
36
+
37
+ alias :str :val
38
+ end
39
+
40
+ ONE = Token.new [:int_lit,'1',['na','na']]
41
+ ZERO = Token.new [:int_lit,'0',['na','na']]
42
+ DUMMY= Token.new [:id ,'' ,['na','na']]
43
+ EQUAL= Token.new [:eq ,'==' ,['na','na']]
@@ -0,0 +1,304 @@
1
+
2
+ require_relative 'code'
3
+
4
+ module Crokus
5
+
6
+ # here we transform an AST into another AST.
7
+ # we don't use Marshalling.
8
+
9
+ class Transformer
10
+
11
+ attr_accessor :code
12
+
13
+ def initialize
14
+ @ind=-2
15
+ @verbose=true
16
+ @verbose=false
17
+ end
18
+
19
+ def transform ast
20
+ ast.accept(self)
21
+ end
22
+
23
+ alias :visit :transform
24
+
25
+ def visitDesignUnit du,args=nil
26
+ list=du.list.collect{|e| e.accept(self)}
27
+ DesignUnit.new(list)
28
+ end
29
+
30
+ def visitDecl decl,args=nil
31
+ type=decl.type.accept(self)
32
+ var=decl.var.accept(self) if decl.var
33
+ init=decl.init.accept(self) if decl.init
34
+ Decl.new(type,var,init)
35
+ end
36
+
37
+ def visitInclude incl,args=nil
38
+ name=incl.name.accept(self)
39
+ env=incl.env
40
+ Include.new(name,env)
41
+ end
42
+
43
+ def visitDefine define,args=nil
44
+ name=define.name.accept(self)
45
+ expr=define.expr.accept(self)
46
+ Define.new(name,expr)
47
+ end
48
+
49
+ def visitTypedef typdef,args=nil
50
+ type=typdef.type.accept(self)
51
+ name=typdef.name.accept(self)
52
+ Typedef.new(type,name)
53
+ end
54
+
55
+ def visitType type,args=nil
56
+ precisions=type.precisions.collect{|prc| prc.accept(self)}
57
+ name=type.name.accept(self)
58
+ ret=Type.new(name)
59
+ ret.precisions=precisions
60
+ ret
61
+ end
62
+
63
+ def visitPointerTo pto,args=nil
64
+ type=pto.type.accept(self)
65
+ PointerTo.new(type)
66
+ end
67
+
68
+ def visitArrayOf aof,args=nil
69
+ type=aof.type.accept(self)
70
+ size=aof.size.accept(self) if aof.size
71
+ ArrayOf.new(type,size)
72
+ end
73
+
74
+ def visitStruct struct,args=nil
75
+ name=struct.name.accept(self) if struct.name
76
+ decls=struct.decls.collect{|decl| decl.accept(self)}
77
+ Struct.new(name,decls)
78
+ end
79
+
80
+ def visitCasting cast,args=nil
81
+ type=cast.type.accept(self)
82
+ modifier=cast.modifier.accept(self)
83
+ Casting.new(type,modifier)
84
+ end
85
+
86
+ def visitCastedExpr cexpr,args=nil
87
+ type=cexpr.type.accept(self)
88
+ expr=cexpr.expr.accept(self)
89
+ CastedExpr.new(type,expr)
90
+ end
91
+
92
+ #......... end of types..........
93
+
94
+ def visitFunction func,args=nil
95
+ type=func.type.accept(self)
96
+ name=func.name.accept(self)
97
+ args=func.args.collect{|arg| arg.accept(self)}
98
+ body=func.body.accept(self)
99
+ Function.new(name,type,args,body)
100
+ end
101
+
102
+ def visitFunctionProto func,args=nil
103
+ type=func.type.accept(self)
104
+ name=func.name.accept(self)
105
+ args=func.args.collect{|arg| arg.accept(self)}
106
+ FunctionProto.new(name,type,args)
107
+ end
108
+
109
+ def visitFormalArg formalArg,args=nil
110
+ name=formalArg.name.accept(self) if formalArg.name # e.g : main(void)
111
+ type=formalArg.type.accept(self)
112
+ FormalArg.new(type,name)
113
+ end
114
+
115
+ #...........stmts...............
116
+ def visitCommaStmt comma,args=nil
117
+ lhs=comma.lhs.accept(self)
118
+ rhs=comma.rhs.accept(self)
119
+ CommaStmt.new(lhs,rhs)
120
+ end
121
+
122
+ def visitAssign assign,args=nil
123
+ lhs=assign.lhs.accept(self)
124
+ op=assign.op.accept(self)
125
+ rhs=assign.rhs.accept(self)
126
+ Assign.new(lhs,op,rhs)
127
+ end
128
+
129
+ def visitPostFixAccu accu,args=nil
130
+ lhs=accu.lhs.accept(self) if accu.lhs #++i
131
+ op=accu.op.accept(self)
132
+ PostFixAccu.new(lhs,op)
133
+ end
134
+
135
+ def visitPreFixAccu accu,args=nil
136
+ lhs=accu.lhs.accept(self) if accu.lhs #++i
137
+ op=accu.op.accept(self)
138
+ PreFixAccu.new(lhs,op)
139
+ end
140
+
141
+ def visitFunCall fcall,args=nil
142
+ name=fcall.name.accept(self)
143
+ args=fcall.args.collect{|arg| arg.accept(self)}
144
+ FunCall.new(name,args)
145
+ end
146
+
147
+ def visitFor for_,args=nil
148
+ init=for_.init.collect{|stmt| stmt.accept(self)}
149
+ cond=for_.cond.accept(self)
150
+ increment=for_.increment.accept(self)
151
+ body=for_.body.accept(self)
152
+ For.new(init,cond,increment,body)
153
+ end
154
+
155
+ def visitReturn ret,args=nil
156
+ expr=ret.expr.accept(self) if ret.expr
157
+ Return.new(expr)
158
+ end
159
+
160
+ def visitIf if_,args=nil
161
+ cond=if_.cond.accept(self)
162
+ body=if_.body.accept(self)
163
+ else_=if_.else.accept(self) if if_.else
164
+ If.new(cond,body,else_)
165
+ end
166
+
167
+ def visitElse else_,args=nil
168
+ body=else_.body.accept(self)
169
+ Else.new(body)
170
+ end
171
+
172
+ def visitSwitch sw_,args=nil
173
+ expr =sw_.expr.accept(self)
174
+ cases=sw_.cases.collect{|case_| case_.accept(self)}
175
+ Switch.new(expr,cases)
176
+ end
177
+
178
+ def visitCase case_,args=nil
179
+ expr=case_.expr.accept(self)
180
+ body=case_.body.accept(self)
181
+ Case.new(expr,body)
182
+ end
183
+
184
+ def visitWhile while_,args=nil
185
+ cond=while_.cond.accept(self)
186
+ body=while_.body.accept(self)
187
+ While.new(cond,body)
188
+ end
189
+
190
+ def visitDoWhile while_,args=nil
191
+ cond=while_.cond.accept(self)
192
+ body=while_.body.each{|stmt| stmt.accept(self)}
193
+ DoWhile.new(cond,body)
194
+ end
195
+
196
+ def visitBreak brk,args=nil
197
+ Break.new
198
+ end
199
+
200
+ def visitContinue cont,args=nil
201
+ Continue.new
202
+ end
203
+
204
+ def visitLabelledStmt label,args=nil
205
+ stmt=label.stmt.accept(self)
206
+ LabelledStmt.new(stmt)
207
+ end
208
+
209
+ def visitGoto goto,args=nil
210
+ label=goto.label.accept(self)
211
+ Goto.new(label)
212
+ end
213
+ #..........expresions..........
214
+ def visitIdent ident,args=nil
215
+ tok=ident.tok.accept(self)
216
+ Ident.new(tok)
217
+ end
218
+
219
+ def visitIntLit lit,args=nil
220
+ tok=lit.tok.accept(self)
221
+ IntLit.new(tok)
222
+ end
223
+
224
+ def visitStrLit lit,args=nil
225
+ tok=lit.tok.accept(self)
226
+ StrLit.new(tok)
227
+ end
228
+
229
+ def visitCharLit lit,args=nil
230
+ tok=lit.tok.accept(self)
231
+ CharLit.new(tok)
232
+ end
233
+
234
+ def visitFloatLit lit,args=nil
235
+ tok=lit.tok.accept(self)
236
+ FloatLit.new(tok)
237
+ end
238
+
239
+ def visitBinary expr,args=nil
240
+ lhs=expr.lhs.accept(self)
241
+ op=expr.op.accept(self)
242
+ rhs=expr.rhs.accept(self)
243
+ Binary.new(lhs,op,rhs)
244
+ end
245
+
246
+ def visitUnary unary,args=nil
247
+ op=unary.op.accept(self)
248
+ rhs=unary.rhs.accept(self)
249
+ Unary.new(op,rhs,unary.postfix)
250
+ end
251
+
252
+ def visitParenth par,args=nil
253
+ e=par.expr.accept(self)
254
+ Parenth.new(e)
255
+ end
256
+
257
+ def visitArrow arrow,args=nil
258
+ lhs=arrow.lhs.accept(self)
259
+ rhs=arrow.rhs.accept(self)
260
+ Arrow.new(lhs,rhs)
261
+ end
262
+
263
+ def visitIndexed index,args=nil
264
+ lhs=index.lhs.accept(self)
265
+ rhs=index.rhs.accept(self)
266
+ Indexed.new(lhs,rhs)
267
+ end
268
+
269
+ def visitArrayOrStructInit init,args=nil
270
+ elements=init.elements.map{|e| e.accept(self)}
271
+ ArrayOrStructInit.new(elements)
272
+ end
273
+
274
+ def visitAddressOf ao,args=nil
275
+ e=ao.expr.accept(self)
276
+ AddressOf.new(e)
277
+ end
278
+
279
+ def visitDotted dotted,args=nil
280
+ lhs=dotted.lhs.accept(self)
281
+ rhs=dotted.rhs.accept(self)
282
+ Dotted.new(lhs,rhs)
283
+ end
284
+
285
+ def visitSizeof sizeof,args=nil
286
+ type=sizeof.type.accept(self)
287
+ Sizeof.new(type)
288
+ end
289
+
290
+ def visitDeref deref,args=nil
291
+ e=deref.expr.accept(self)
292
+ Deref.new(e)
293
+ end
294
+
295
+ def visitBody body,args=nil
296
+ stmts=body.stmts.map{|stmt| stmt.accept(self)}
297
+ Body.new(stmts)
298
+ end
299
+
300
+ def visitToken tok,args=nil
301
+ Token.new [tok.kind,tok.val,tok.pos]
302
+ end
303
+ end #class Visitor
304
+ end #module