Mercurial > projects > dang
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 |