comparison trunk/src/dil/semantic/Pass2.d @ 684:10b314bf37e3

Added module dil.semantic.Pass2.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Mon, 21 Jan 2008 18:40:55 +0100
parents
children d33895f679eb
comparison
equal deleted inserted replaced
683:1ae72234db26 684:10b314bf37e3
1 /++
2 Author: Aziz Köksal
3 License: GPL3
4 +/
5 module dil.semantic.Pass2;
6
7 import dil.ast.DefaultVisitor;
8 import dil.ast.Node,
9 dil.ast.Declarations,
10 dil.ast.Expressions,
11 dil.ast.Statements,
12 dil.ast.Types,
13 dil.ast.Parameters;
14 import dil.lexer.Identifier;
15 import dil.semantic.Symbol,
16 dil.semantic.Symbols,
17 dil.semantic.Types,
18 dil.semantic.Scope,
19 dil.semantic.Module,
20 dil.semantic.Analysis;
21 import dil.parser.Parser;
22 import dil.Location;
23 import dil.Information;
24 import dil.Messages;
25 import dil.Enums;
26 import dil.CompilerInfo;
27 import common;
28
29 class SemanticPass2 : DefaultVisitor
30 {
31 Scope scop; /// The current scope.
32 Module modul; /// The module to be semantically checked.
33
34 this(Module modul)
35 {
36 this.modul = modul;
37 }
38
39 /// Start semantic analysis.
40 void start()
41 {
42 assert(modul.root !is null);
43 // Create module scope.
44 scop = new Scope();
45 scop.symbol = modul; // Set this module as the scope's symbol.
46 scop.infoMan = modul.infoMan;
47 visit(modul.root);
48 }
49
50 void enterScope(ScopeSymbol s)
51 {
52 scop = scop.enter(s);
53 }
54
55 void exitScope()
56 {
57 scop = scop.exit();
58 }
59
60 void error(Token* token, char[] formatMsg, ...)
61 {
62 auto location = token.getErrorLocation();
63 auto msg = Format(_arguments, _argptr, formatMsg);
64 modul.infoMan ~= new SemanticError(location, msg);
65 }
66
67 private alias Declaration D;
68 private alias Expression E;
69 private alias Statement S;
70 private alias TypeNode T;
71
72 override
73 {
74 D visit(CompoundDeclaration d)
75 {
76 return super.visit(d);
77 }
78
79 D visit(MixinDeclaration md)
80 {
81 /+
82 if (type)
83 return this.expr;
84 // TODO:
85 auto expr = this.expr.semantic(scop);
86 expr = expr.evaluate();
87 if (expr is null)
88 return this;
89 auto strExpr = TryCast!(StringExpression)(expr);
90 if (strExpr is null)
91 error(scop, MSG.MixinArgumentMustBeString);
92 else
93 {
94 auto loc = this.begin.getErrorLocation();
95 auto filePath = loc.filePath;
96 auto parser = new_ExpressionParser(strExpr.getString(), filePath, scop.infoMan);
97 expr = parser.parse();
98 expr = expr.semantic(scop);
99 }
100 this.expr = expr;
101 this.type = expr.type;
102 return expr;
103 +/
104 return md;
105 }
106
107 T visit(PointerType t)
108 {
109 t.type = visitT(t.next).type.ptrTo();
110 return t;
111 }
112
113 T visit(IntegralType t)
114 {
115 // A table mapping the kind of a token to its corresponding semantic Type.
116 TypeBasic[TOK] tok2Type = [
117 TOK.Char : Types.Char, TOK.Wchar : Types.Wchar, TOK.Dchar : Types.Dchar, TOK.Bool : Types.Bool,
118 TOK.Byte : Types.Byte, TOK.Ubyte : Types.Ubyte, TOK.Short : Types.Short, TOK.Ushort : Types.Ushort,
119 TOK.Int : Types.Int, TOK.Uint : Types.Uint, TOK.Long : Types.Long, TOK.Ulong : Types.Ulong,
120 TOK.Cent : Types.Cent, TOK.Ucent : Types.Ucent,
121 TOK.Float : Types.Float, TOK.Double : Types.Double, TOK.Real : Types.Real,
122 TOK.Ifloat : Types.Ifloat, TOK.Idouble : Types.Idouble, TOK.Ireal : Types.Ireal,
123 TOK.Cfloat : Types.Cfloat, TOK.Cdouble : Types.Cdouble, TOK.Creal : Types.Creal, TOK.Void : Types.Void
124 ];
125 t.type = tok2Type[t.tok];
126 return t;
127 }
128
129 E visit(ParenExpression e)
130 {
131 if (!e.type)
132 {
133 e.next = visitE(e.next);
134 e.type = e.next.type;
135 }
136 return e;
137 }
138
139 E visit(CommaExpression e)
140 {
141 if (!e.type)
142 {
143 e.left = visitE(e.left);
144 e.right = visitE(e.right);
145 e.type = e.right.type;
146 }
147 return e;
148 }
149
150 E visit(OrOrExpression)
151 { return null; }
152
153 E visit(AndAndExpression)
154 { return null; }
155
156 E visit(SpecialTokenExpression e)
157 {
158 if (e.type)
159 return e.value;
160 switch (e.specialToken.kind)
161 {
162 case TOK.LINE, TOK.VERSION:
163 e.value = new IntExpression(e.specialToken.uint_, Types.Uint);
164 break;
165 case TOK.FILE, TOK.DATE, TOK.TIME, TOK.TIMESTAMP, TOK.VENDOR:
166 e.value = new StringExpression(e.specialToken.str);
167 break;
168 default:
169 assert(0);
170 }
171 e.type = e.value.type;
172 return e.value;
173 }
174
175 E visit(DollarExpression e)
176 {
177 if (e.type)
178 return e;
179 e.type = Types.Size_t;
180 // if (!inArraySubscript)
181 // error("$ can only be in an array subscript.");
182 return e;
183 }
184
185 E visit(NullExpression e)
186 {
187 if (!e.type)
188 e.type = Types.Void_ptr;
189 return e;
190 }
191
192 E visit(BoolExpression e)
193 {
194 if (e.type)
195 return e;
196 e.value = new IntExpression(e.toBool(), Types.Bool);
197 e.type = Types.Bool;
198 return e;
199 }
200
201 E visit(IntExpression e)
202 {
203 if (e.type)
204 return e;
205
206 if (e.number & 0x8000_0000_0000_0000)
207 e.type = Types.Ulong; // 0xFFFF_FFFF_FFFF_FFFF
208 else if (e.number & 0xFFFF_FFFF_0000_0000)
209 e.type = Types.Long; // 0x7FFF_FFFF_FFFF_FFFF
210 else if (e.number & 0x8000_0000)
211 e.type = Types.Uint; // 0xFFFF_FFFF
212 else
213 e.type = Types.Int; // 0x7FFF_FFFF
214 return e;
215 }
216
217 E visit(RealExpression e)
218 {
219 if (e.type)
220 e.type = Types.Double;
221 return e;
222 }
223
224 E visit(ComplexExpression e)
225 {
226 if (!e.type)
227 e.type = Types.Cdouble;
228 return e;
229 }
230
231 E visit(CharExpression e)
232 {
233 if (e.type)
234 return e;
235 if (e.character <= 0xFF)
236 e.type = Types.Char;
237 else if (e.character <= 0xFFFF)
238 e.type = Types.Wchar;
239 else
240 e.type = Types.Dchar;
241 return e;
242 }
243
244 E visit(StringExpression e)
245 {
246 return e;
247 }
248
249 E visit(MixinExpression me)
250 {
251 if (me.type)
252 return me.expr;
253 auto expr = visitE(me.expr);
254 // TODO: expr = expr.evaluate();
255 if (expr is null)
256 return me;
257 auto stringExpr = expr.Is!(StringExpression);
258 if (stringExpr is null)
259 error(me.begin, MSG.MixinArgumentMustBeString);
260 else
261 {
262 auto loc = me.begin.getErrorLocation();
263 auto filePath = loc.filePath;
264 auto parser = new Parser(stringExpr.getString(), filePath, scop.infoMan);
265 expr = parser.start2();
266 expr = visitE(expr); // Check expression.
267 }
268 me.expr = expr;
269 me.type = expr.type;
270 return me.expr;
271 }
272
273 E visit(ImportExpression e)
274 {
275 return e;
276 }
277 }
278 }