0
|
1
|
|
2 /* Digital Mars DMDScript source code.
|
|
3 * Copyright (c) 2000-2002 by Chromium Communications
|
|
4 * D version Copyright (c) 2004-2007 by Digital Mars
|
|
5 * All Rights Reserved
|
|
6 * written by Walter Bright
|
|
7 * www.digitalmars.com
|
|
8 * Use at your own risk. There is no warranty, express or implied.
|
|
9 * License for redistribution is by the GNU General Public License in gpl.txt.
|
|
10 *
|
|
11 * A binary, non-exclusive license for commercial use can be
|
|
12 * purchased from www.digitalmars.com/dscript/buy.html.
|
|
13 *
|
|
14 * DMDScript is implemented in the D Programming Language,
|
|
15 * www.digitalmars.com/d/
|
|
16 *
|
|
17 * For a C++ implementation of DMDScript, including COM support,
|
|
18 * see www.digitalmars.com/dscript/cppscript.html.
|
|
19 */
|
|
20
|
|
21
|
|
22 module dmdscript.scopex;
|
|
23
|
|
24 import dmdscript.script;
|
|
25 import dmdscript.program;
|
|
26 import dmdscript.symbol;
|
|
27 import dmdscript.functiondefinition;
|
|
28 import dmdscript.identifier;
|
|
29 import dmdscript.statement;
|
|
30
|
|
31 struct Scope
|
|
32 {
|
|
33 Scope* enclosing; // enclosing Scope
|
|
34
|
|
35 char[] src; // source text
|
|
36 Program program; // Root module
|
|
37 ScopeSymbol *scopesym; // current symbol
|
|
38 FunctionDefinition funcdef; // what function we're in
|
|
39 SymbolTable **plabtab; // pointer to label symbol table
|
|
40 uint nestDepth; // static nesting level
|
|
41
|
|
42 ScopeStatement scopeContext; // nesting of scope statements
|
|
43 Statement continueTarget;
|
|
44 Statement breakTarget;
|
|
45 SwitchStatement switchTarget;
|
|
46
|
|
47 ErrInfo errinfo; // semantic() puts error messages here
|
|
48
|
|
49 void zero()
|
|
50 {
|
|
51 enclosing = null;
|
|
52
|
|
53 src = null;
|
|
54 program = null;
|
|
55 scopesym = null;
|
|
56 funcdef = null;
|
|
57 plabtab = null;
|
|
58 nestDepth = 0;
|
|
59
|
|
60 scopeContext = null;
|
|
61 continueTarget = null;
|
|
62 breakTarget = null;
|
|
63 switchTarget = null;
|
|
64 }
|
|
65
|
|
66 void ctor(Scope* enclosing)
|
|
67 {
|
|
68 zero();
|
|
69 this.program = enclosing.program;
|
|
70 this.funcdef = enclosing.funcdef;
|
|
71 this.plabtab = enclosing.plabtab;
|
|
72 this.nestDepth = enclosing.nestDepth;
|
|
73 this.enclosing = enclosing;
|
|
74 }
|
|
75
|
|
76 void ctor(Program program, FunctionDefinition fd)
|
|
77 { // Create root scope
|
|
78
|
|
79 zero();
|
|
80 this.program = program;
|
|
81 this.funcdef = fd;
|
|
82 this.plabtab = &fd.labtab;
|
|
83 }
|
|
84
|
|
85 void ctor(FunctionDefinition fd)
|
|
86 { // Create scope for anonymous function fd
|
|
87
|
|
88 zero();
|
|
89 this.funcdef = fd;
|
|
90 this.plabtab = &fd.labtab;
|
|
91 }
|
|
92
|
|
93 void dtor()
|
|
94 {
|
|
95 // Help garbage collector
|
|
96 zero();
|
|
97 }
|
|
98
|
|
99 Scope* push()
|
|
100 { Scope* s;
|
|
101
|
|
102 s = new Scope;
|
|
103 s.ctor(this);
|
|
104 return s;
|
|
105 }
|
|
106
|
|
107 Scope* push(FunctionDefinition fd)
|
|
108 { Scope* s;
|
|
109
|
|
110 s = push();
|
|
111 s.funcdef = fd;
|
|
112 s.plabtab = &fd.labtab;
|
|
113 return s;
|
|
114 }
|
|
115
|
|
116 void pop()
|
|
117 {
|
|
118 if (enclosing && !enclosing.errinfo.message)
|
|
119 enclosing.errinfo = errinfo;
|
|
120 zero(); // aid GC
|
|
121 }
|
|
122
|
|
123
|
|
124 Symbol search(Identifier *ident)
|
|
125 { Symbol s;
|
|
126 Scope* sc;
|
|
127
|
|
128 //writef("Scope.search(%p, '%s')\n", this, ident.toString());
|
|
129 for (sc = this; sc; sc = sc.enclosing)
|
|
130 {
|
|
131 s = sc.scopesym.search(ident);
|
|
132 if (s)
|
|
133 return s;
|
|
134 }
|
|
135
|
|
136 assert(0);
|
|
137 //error("Symbol '%s' is not defined", ident.toString());
|
|
138 return null;
|
|
139 }
|
|
140
|
|
141 Symbol insert(Symbol s)
|
|
142 {
|
|
143 if (!scopesym.symtab)
|
|
144 scopesym.symtab = new SymbolTable();
|
|
145 return scopesym.symtab.insert(s);
|
|
146 }
|
|
147
|
|
148 LabelSymbol searchLabel(Identifier *ident)
|
|
149 {
|
|
150 SymbolTable *st;
|
|
151 LabelSymbol ls;
|
|
152
|
|
153 //writef("Scope::searchLabel('%ls')\n", ident.toDchars());
|
|
154 assert(plabtab);
|
|
155 st = *plabtab;
|
|
156 if (!st)
|
|
157 {
|
|
158 st = new SymbolTable();
|
|
159 *plabtab = st;
|
|
160 }
|
|
161 ls = cast(LabelSymbol )st.lookup(ident);
|
|
162 return ls;
|
|
163 }
|
|
164
|
|
165 LabelSymbol insertLabel(LabelSymbol ls)
|
|
166 {
|
|
167 SymbolTable *st;
|
|
168
|
|
169 //writef("Scope::insertLabel('%s')\n", ls.toString());
|
|
170 assert(plabtab);
|
|
171 st = *plabtab;
|
|
172 if (!st)
|
|
173 {
|
|
174 st = new SymbolTable();
|
|
175 *plabtab = st;
|
|
176 }
|
|
177 ls = cast(LabelSymbol )st.insert(ls);
|
|
178 return ls;
|
|
179 }
|
|
180
|
|
181 tchar[] getSource()
|
|
182 { Scope* sc;
|
|
183
|
|
184 for (sc = this; sc; sc = sc.enclosing)
|
|
185 {
|
|
186 if (sc.src)
|
|
187 return sc.src;
|
|
188 }
|
|
189
|
|
190 return null;
|
|
191 }
|
|
192 }
|
|
193
|