crokus 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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