Mercurial > projects > dang
annotate sema/SymbolTableBuilder.d @ 14:a51bdf15a33d
Better scopes.
---
int x = 1 + y; // <- should not see y in scope yet
int y;
---
This is done py pushing the scope when a DeclStmt is encountered, and
making sure things that containts statements pop the correct number of
times.
author | Anders Halager <halager@gmail.com> |
---|---|
date | Fri, 18 Apr 2008 15:25:10 +0200 |
parents | 642c6a998fd9 |
children | e331e4e816e4 |
rev | line source |
---|---|
1 | 1 module sema.SymbolTableBuilder; |
2 | |
14 | 3 import tango.io.Stdout, |
4 tango.core.Array : find; | |
1 | 5 |
6 public import sema.SymbolTable; | |
7 | |
8 import sema.Visitor; | |
9 | |
10 class SymbolTableBuilder : Visitor!(void) | |
11 { | |
12 this() | |
13 { | |
14 table ~= new Scope; | |
15 } | |
16 | |
17 override void visit(Decl[] decls) | |
18 { | |
19 foreach (decl; decls) | |
20 visitDecl(decl); | |
21 } | |
22 | |
23 override void visitDecl(Decl d) | |
24 { | |
25 d.env = current(); | |
26 super.visitDecl(d); | |
27 } | |
28 | |
29 override void visitStmt(Stmt s) | |
30 { | |
31 s.env = current(); | |
32 super.visitStmt(s); | |
33 } | |
34 | |
35 override void visitExp(Exp e) | |
36 { | |
37 e.env = current(); | |
38 super.visitExp(e); | |
39 } | |
40 | |
41 override void visitFuncDecl(FuncDecl d) | |
42 { | |
43 auto sym = current().add(d.identifier); | |
44 sym.type = d.type; | |
2
ae5bbe4e7fd6
Lots of stuff, here are the git comments:
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
45 visitExp(d.type); |
ae5bbe4e7fd6
Lots of stuff, here are the git comments:
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
46 visitExp(d.identifier); |
1 | 47 d.env = current(); |
14 | 48 auto sc = push(); |
49 sc.parentFunction = sym; | |
2
ae5bbe4e7fd6
Lots of stuff, here are the git comments:
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
50 foreach (arg; d.funcArgs) |
ae5bbe4e7fd6
Lots of stuff, here are the git comments:
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
51 visitDecl(arg); |
ae5bbe4e7fd6
Lots of stuff, here are the git comments:
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
52 foreach (stmt; d.statements) |
ae5bbe4e7fd6
Lots of stuff, here are the git comments:
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
53 visitStmt(stmt); |
14 | 54 pop(sc); |
1 | 55 } |
56 | |
57 override void visitVarDecl(VarDecl d) | |
58 { | |
59 auto sc = current(); | |
60 auto sym = sc.add(d.identifier); | |
61 sym.type = d.type; | |
62 super.visitVarDecl(d); | |
63 } | |
64 | |
14 | 65 override void visitDeclStmt(DeclStmt d) |
66 { | |
67 super.visitDeclStmt(d); | |
68 push(); | |
69 } | |
70 | |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
2
diff
changeset
|
71 override void visitIfStmt(IfStmt s) |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
2
diff
changeset
|
72 { |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
2
diff
changeset
|
73 s.env = current(); |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
2
diff
changeset
|
74 visitExp(s.cond); |
14 | 75 auto sc = push(); |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
2
diff
changeset
|
76 foreach (stmt; s.then_body) |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
2
diff
changeset
|
77 visitStmt(stmt); |
14 | 78 pop(sc); |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
2
diff
changeset
|
79 |
14 | 80 sc = push(); |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
2
diff
changeset
|
81 foreach (stmt; s.else_body) |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
2
diff
changeset
|
82 visitStmt(stmt); |
14 | 83 pop(sc); |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
2
diff
changeset
|
84 } |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
2
diff
changeset
|
85 |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
2
diff
changeset
|
86 override void visitWhileStmt(WhileStmt s) |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
2
diff
changeset
|
87 { |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
2
diff
changeset
|
88 s.env = current(); |
14 | 89 auto sc = push(); |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
2
diff
changeset
|
90 super.visitWhileStmt(s); |
14 | 91 pop(sc); |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
2
diff
changeset
|
92 } |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
2
diff
changeset
|
93 |
1 | 94 private: |
95 Scope[] table; | |
96 | |
14 | 97 Scope push() |
1 | 98 { |
14 | 99 auto sc = new Scope(current()); |
100 table ~= sc; | |
101 return sc; | |
1 | 102 } |
103 | |
14 | 104 Scope pop(Scope sc = null) |
1 | 105 { |
14 | 106 if (sc !is null) |
107 { | |
108 table.length = table.find(sc); | |
109 return sc; | |
110 } | |
111 | |
1 | 112 auto res = table[$ - 1]; |
113 table.length = table.length - 1; | |
114 return res; | |
115 } | |
116 | |
117 Scope current() | |
118 { | |
119 return table[$ - 1]; | |
120 } | |
121 } | |
122 |