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