comparison sema/ScopeBuilder.d @ 92:771ac63898e2 new_gen

A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
author Anders Johnsen <skabet@gmail.com>
date Mon, 05 May 2008 18:44:20 +0200
parents sema/SymbolTableBuilder.d@29f486ccc203
children 621cedba53ea
comparison
equal deleted inserted replaced
91:1a24e61eb104 92:771ac63898e2
1 module sema.ScopeBuilder;
2
3 import tango.io.Stdout,
4 tango.core.Array : find;
5
6 public
7 import sema.Scope;
8
9 import sema.Visitor,
10 basic.SmallArray;
11
12 class ForwardReference : Visitor!(void)
13 {
14 override void visit(Decl[] decls)
15 {
16 foreach (decl; decls)
17 visitDecl(decl);
18 }
19
20 override void visitFuncDecl(FuncDecl d)
21 {
22 visitExp(d.returnType);
23 visitExp(d.identifier);
24 foreach (arg; d.funcArgs)
25 visitDecl(arg);
26 foreach (stmt; d.statements)
27 visitStmt(stmt);
28
29 auto sym = d.env.find(d.identifier);
30 sym.type = d.type;
31 }
32
33 override void visitVarDecl(VarDecl d)
34 {
35 visitExp(d.varType);
36 visitExp(d.identifier);
37
38 if (d.init)
39 visitExp(d.init);
40
41 d.env.find(d.identifier).type = typeOf(d.varType, d.env);
42 }
43
44 override void visitStructDecl(StructDecl s)
45 {
46 DType[char[]] types;
47
48 auto st = s.env.types[s.identifier.get].asStruct;
49 foreach(varDecl ; s.vars)
50 st.addMember(typeOf(varDecl.varType, varDecl.env), varDecl.identifier.get);
51
52 super.visitStructDecl(s);
53 }
54
55 DType typeOf(Identifier id, Scope sc)
56 {
57 if(auto i = cast(PointerIdentifier)id)
58 return (typeOf(i.pointerOf, sc)).getPointerTo();
59 if(auto i = cast(ArrayIdentifier)id)
60 return typeOf(i.arrayOf, sc).getAsArray(i.size);
61 return sc.findType(id);
62 }
63 }
64
65 class ScopeBuilder : Visitor!(void)
66 {
67 this()
68 {
69 table ~= new Scope;
70 table[0].types["void"] = DType.Void;
71 table[0].types["bool"] = DType.Bool;
72 table[0].types["byte"] = DType.Byte;
73 table[0].types["ubyte"] = DType.UByte;
74 table[0].types["short"] = DType.Short;
75 table[0].types["ushort"] = DType.UShort;
76 table[0].types["int"] = DType.Int;
77 table[0].types["uint"] = DType.UInt;
78 table[0].types["long"] = DType.Long;
79 table[0].types["ulong"] = DType.ULong;
80 }
81
82 override void visit(Decl[] decls)
83 {
84 foreach (decl; decls)
85 visitDecl(decl);
86 auto fr = new ForwardReference();
87 fr.visit(decls);
88 }
89
90 override void visitDecl(Decl d)
91 {
92 d.env = current();
93 super.visitDecl(d);
94 }
95
96 override void visitStmt(Stmt s)
97 {
98 s.env = current();
99 s.stmtIndex = s.env.stmtIndex;
100 super.visitStmt(s);
101 }
102
103 override void visitExp(Exp e)
104 {
105 e.env = current();
106 e.stmtIndex = e.env.stmtIndex;
107 super.visitExp(e);
108 }
109
110 override void visitFuncDecl(FuncDecl d)
111 {
112 auto sym = current().add(d.identifier);
113 auto sc = push();
114
115 visitExp(d.returnType);
116 visitExp(d.identifier);
117 d.env = current();
118 sc.parentFunction = d;
119 foreach (arg; d.funcArgs)
120 visitDecl(arg);
121 foreach (stmt; d.statements)
122 {
123 sc.currentStmtIndex++;
124 visitStmt(stmt);
125 }
126 pop(sc);
127 }
128
129 override void visitVarDecl(VarDecl d)
130 {
131 if (d.init)
132 visitExp(d.init);
133
134 if (need_push > 0 && current().parentFunction !is null) {
135 push();
136 --need_push;
137 }
138
139 auto sc = current();
140 auto sym = sc.add(d.identifier);
141 d.env = sc;
142 visitExp(d.varType);
143 visitExp(d.identifier);
144 }
145
146 override void visitStructDecl(StructDecl s)
147 {
148 auto sc = current();
149 auto sym = sc.add(s.identifier);
150 s.env = sc;
151 auto type = new DStruct(s.identifier);
152
153 sc.types[s.identifier.get] = type;
154
155 sc = push();
156 super.visitStructDecl(s);
157 pop(sc);
158 }
159
160 override void visitDeclStmt(DeclStmt d)
161 {
162 ++need_push;
163 super.visitDeclStmt(d);
164 }
165 private uint need_push = 0;
166
167 override void visitIfStmt(IfStmt s)
168 {
169 s.env = current();
170 visitExp(s.cond);
171 auto sc = push();
172 visitStmt(s.then_body);
173 pop(sc);
174
175 if (s.else_body !is null)
176 {
177 sc = push();
178 visitStmt(s.else_body);
179 pop(sc);
180 }
181 }
182
183 override void visitWhileStmt(WhileStmt s)
184 {
185 s.env = current();
186 auto sc = push();
187 super.visitWhileStmt(s);
188 pop(sc);
189 }
190
191 override void visitCompoundStmt(CompoundStatement s)
192 {
193 s.env = current();
194 auto sc = push();
195 super.visitCompoundStmt(s);
196 pop(sc);
197 }
198
199 private:
200 Scope[] table;
201
202 Scope push()
203 {
204 auto sc = new Scope(current());
205 table ~= sc;
206 return sc;
207 }
208
209 Scope pop(Scope sc = null)
210 {
211 if (sc !is null)
212 {
213 table.length = table.find(sc);
214 return sc;
215 }
216
217 auto res = table[$ - 1];
218 table.length = table.length - 1;
219 return res;
220 }
221
222 Scope current()
223 {
224 return table[$ - 1];
225 }
226 }
227