Mercurial > projects > dang
annotate sema/Visitor.d @ 45:9bc660cbdbec new_gen
If statements are back
Also fixed a bug in the codegen preventing return in the else branch, now
it is optional.
Also found an issue with the way we are generating our llvm from ifs - it
doesn't mean anything but the code looks ugly.
if (cond_1)
if (cond_2)
statement;
return 0;
Becomes:
br cond_1, then, merge
then:
br cond_2 then2, merge2
merge:
ret 0
then2:
statements
merge2:
br merge
This is because we use appendBasicBlock on the function
author | Anders Halager <halager@gmail.com> |
---|---|
date | Wed, 23 Apr 2008 16:43:42 +0200 |
parents | 495188f9078e |
children | 90fb4fdfefdd |
rev | line source |
---|---|
1 | 1 module sema.Visitor; |
2 | |
3 import tango.io.Stdout; | |
4 | |
5 public | |
6 import ast.Decl, | |
7 ast.Stmt, | |
8 ast.Exp; | |
9 | |
10 import lexer.Token; | |
11 | |
12 class Visitor(FinalT = int, DeclT = FinalT, StmtT = DeclT, ExpT = StmtT) | |
13 { | |
14 public: | |
15 FinalT visit(Decl[] decls) | |
16 { | |
17 foreach (decl; decls) | |
18 visitDecl(decl); | |
19 static if (is(FinalT == void)) | |
20 return; | |
21 else | |
22 return FinalT.init; | |
23 } | |
24 | |
25 DeclT visitDecl(Decl decl) | |
26 { | |
27 switch(decl.declType) | |
28 { | |
29 case DeclType.FuncDecl: | |
30 return visitFuncDecl(cast(FuncDecl)decl); | |
31 case DeclType.VarDecl: | |
32 return visitVarDecl(cast(VarDecl)decl); | |
22 | 33 case DeclType.StructDecl: |
34 return visitStructDecl(cast(StructDecl)decl); | |
1 | 35 default: |
36 throw new Exception("Unknown declaration type"); | |
37 } | |
38 } | |
39 | |
40 StmtT visitStmt(Stmt stmt) | |
41 { | |
42 switch(stmt.stmtType) | |
43 { | |
44 case StmtType.Return: | |
45 return visitReturnStmt(cast(ReturnStmt)stmt); | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
46 case StmtType.Compound: |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
47 return visitCompoundStmt(cast(CompoundStatement)stmt); |
1 | 48 case StmtType.Decl: |
49 return visitDeclStmt(cast(DeclStmt)stmt); | |
50 case StmtType.Exp: | |
51 return visitExpStmt(cast(ExpStmt)stmt); | |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
52 case StmtType.If: |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
53 return visitIfStmt(cast(IfStmt)stmt); |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
54 case StmtType.While: |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
55 return visitWhileStmt(cast(WhileStmt)stmt); |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
56 case StmtType.Switch: |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
57 return visitSwitchStmt(cast(SwitchStmt)stmt); |
1 | 58 default: |
59 throw new Exception("Unknown statement type"); | |
60 } | |
61 } | |
62 | |
63 ExpT visitExp(Exp exp) | |
64 { | |
65 switch(exp.expType) | |
66 { | |
67 case ExpType.Binary: | |
68 return visitBinaryExp(cast(BinaryExp)exp); | |
69 case ExpType.IntegerLit: | |
70 return visitIntegerLit(cast(IntegerLit)exp); | |
71 case ExpType.Negate: | |
72 return visitNegateExp(cast(NegateExp)exp); | |
73 case ExpType.AssignExp: | |
74 return visitAssignExp(cast(AssignExp)exp); | |
75 case ExpType.CallExp: | |
76 return visitCallExp(cast(CallExp)exp); | |
77 case ExpType.Identifier: | |
78 return visitIdentifier(cast(Identifier)exp); | |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
79 case ExpType.MemberLookup: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
80 return visitMemberLookup(cast(MemberLookup)exp); |
1 | 81 default: |
82 throw new Exception("Unknown expression type"); | |
83 } | |
84 } | |
85 | |
86 // Declarations: | |
87 DeclT visitVarDecl(VarDecl d) | |
88 { | |
89 visitExp(d.type); | |
90 visitExp(d.identifier); | |
91 if (d.init) | |
92 visitExp(d.init); | |
93 | |
94 static if (is(DeclT == void)) | |
95 return; | |
96 else | |
97 return DeclT.init; | |
98 } | |
99 | |
100 DeclT visitFuncDecl(FuncDecl f) | |
101 { | |
102 visitExp(f.type); | |
103 visitExp(f.identifier); | |
104 foreach (arg; f.funcArgs) | |
105 visitDecl(arg); | |
106 foreach (stmt; f.statements) | |
107 visitStmt(stmt); | |
108 | |
109 static if (is(DeclT == void)) | |
110 return; | |
111 else | |
112 return DeclT.init; | |
113 } | |
114 | |
22 | 115 DeclT visitStructDecl(StructDecl s) |
116 { | |
117 visitExp(s.identifier); | |
118 | |
119 foreach (arg; s.vars) | |
120 visitDecl(arg); | |
121 | |
122 static if (is(DeclT == void)) | |
123 return; | |
124 else | |
125 return DeclT.init; | |
126 } | |
127 | |
1 | 128 // Statements: |
129 StmtT visitReturnStmt(ReturnStmt s) | |
130 { | |
37 | 131 if (s.exp) |
132 visitExp(s.exp); | |
1 | 133 static if (is(StmtT == void)) |
134 return; | |
135 else | |
136 return StmtT.init; | |
137 } | |
138 | |
139 StmtT visitDeclStmt(DeclStmt d) | |
140 { | |
141 visitDecl(d.decl); | |
142 static if (is(StmtT == void)) | |
143 return; | |
144 else | |
145 return StmtT.init; | |
146 } | |
147 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
148 StmtT visitCompoundStmt(CompoundStatement c) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
149 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
150 foreach (stmt; c.statements) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
151 visitStmt(stmt); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
152 static if (is(StmtT == void)) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
153 return; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
154 else |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
155 return StmtT.init; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
156 } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
157 |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
158 StmtT visitIfStmt(IfStmt s) |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
159 { |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
160 visitExp(s.cond); |
45 | 161 visitStmt(s.then_body); |
162 if (s.else_body !is null) | |
163 visitStmt(s.else_body); | |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
164 static if (is(StmtT == void)) |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
165 return; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
166 else |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
167 return StmtT.init; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
168 } |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
169 |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
170 StmtT visitWhileStmt(WhileStmt s) |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
171 { |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
172 visitExp(s.cond); |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
173 foreach (stmt; s.stmts) |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
174 visitStmt(stmt); |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
175 static if (is(StmtT == void)) |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
176 return; |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
177 else |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
178 return StmtT.init; |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
179 } |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
180 |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
181 StmtT visitSwitchStmt(SwitchStmt s) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
182 { |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
183 visitExp(s.cond); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
184 foreach(stmt; s.defaultBlock) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
185 visitStmt(stmt); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
186 foreach (c; s.cases) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
187 { |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
188 foreach(lit; c.values) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
189 visitIntegerLit(lit); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
190 foreach(stmt; c.stmts) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
191 visitStmt(stmt); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
192 } |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
193 static if (is(StmtT == void)) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
194 return; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
195 else |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
196 return StmtT.init; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
197 } |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
198 |
1 | 199 StmtT visitExpStmt(ExpStmt s) |
200 { | |
201 visitExp(s.exp); | |
202 static if (is(StmtT == void)) | |
203 return; | |
204 else | |
205 return StmtT.init; | |
206 } | |
207 | |
208 // Expressions: | |
209 ExpT visitAssignExp(AssignExp exp) | |
210 { | |
211 visitExp(exp.identifier); | |
212 visitExp(exp.exp); | |
213 static if (is(ExpT == void)) | |
214 return; | |
215 else | |
216 return ExpT.init; | |
217 } | |
218 | |
219 ExpT visitBinaryExp(BinaryExp exp) | |
220 { | |
221 visitExp(exp.left); | |
222 visitExp(exp.right); | |
223 static if (is(ExpT == void)) | |
224 return; | |
225 else | |
226 return ExpT.init; | |
227 } | |
228 | |
229 ExpT visitCallExp(CallExp exp) | |
230 { | |
231 visitExp(exp.exp); | |
232 foreach (arg; exp.args) | |
233 visitExp(arg); | |
234 static if (is(ExpT == void)) | |
235 return; | |
236 else | |
237 return ExpT.init; | |
238 } | |
239 | |
240 ExpT visitNegateExp(NegateExp exp) | |
241 { | |
242 visitExp(exp.exp); | |
243 static if (is(ExpT == void)) | |
244 return; | |
245 else | |
246 return ExpT.init; | |
247 } | |
248 | |
249 ExpT visitIntegerLit(IntegerLit exp) | |
250 { | |
251 static if (is(ExpT == void)) | |
252 return; | |
253 else | |
254 return ExpT.init; | |
255 } | |
256 | |
257 ExpT visitIdentifier(Identifier exp) | |
258 { | |
259 static if (is(ExpT == void)) | |
260 return; | |
261 else | |
262 return ExpT.init; | |
263 } | |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
264 |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
265 ExpT visitMemberLookup(MemberLookup mem) |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
266 { |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
267 visitExp(mem.target); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
268 visitExp(mem.child); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
269 |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
270 static if (is(ExpT == void)) |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
271 return; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
272 else |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
273 return ExpT.init; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
274 } |
1 | 275 } |
276 |