kernel modules Wiedervereinigung
[scilab.git] / scilab / modules / ast / includes / symbol / variables.hxx
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2007-2008 - INRIA - Bruno JOFRET
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #ifndef __VARIABLES_HXX__
14 #define __VARIABLES_HXX__
15
16 #include <string>
17 #include <stack>
18 #include "symbol.hxx"
19 #include "internal.hxx"
20 #include "double.hxx"
21
22 namespace symbol
23 {
24 struct ScopedVariable
25 {
26     ScopedVariable(int _iLevel, types::InternalType* _pIT)
27         : m_iLevel(_iLevel), m_pIT(_pIT), m_globalVisible(false) {}
28
29     int m_iLevel;
30     bool m_globalVisible;
31     types::InternalType* m_pIT;
32 };
33
34 struct Variable
35 {
36     Variable(const Symbol& _name) : name(_name), m_Global(false), m_GlobalValue(NULL) {};
37     ~Variable()
38     {
39         while (!empty())
40         {
41             ScopedVariable * pSV = top();
42             types::InternalType * pIT = pSV->m_pIT;
43             pIT->DecreaseRef();
44             pIT->killMe();
45             pop();
46             delete pSV;
47         }
48
49         if (m_GlobalValue)
50         {
51             m_GlobalValue->DecreaseRef();
52             m_GlobalValue->killMe();
53         }
54     }
55
56     void put(types::InternalType* _pIT, int _iLevel)
57     {
58         if (isGlobal() && isGlobalVisible(_iLevel))
59         {
60             setGlobalValue(_pIT);
61             return;
62         }
63
64         if (empty() || top()->m_iLevel < _iLevel)
65         {
66             //create a new level
67             stack.push(new ScopedVariable(_iLevel, _pIT));
68             _pIT->IncreaseRef();
69         }
70         else
71         {
72             //update current level
73             types::InternalType* pIT = top()->m_pIT;
74             if (pIT != _pIT)
75             {
76                 pIT->DecreaseRef();
77                 pIT->killMe();
78                 top()->m_pIT = _pIT;
79                 _pIT->IncreaseRef();
80             }
81         }
82     }
83
84     inline types::InternalType* get() const
85     {
86         if (empty())
87         {
88             return NULL;
89         }
90
91         if (m_Global && top()->m_globalVisible)
92         {
93             return m_GlobalValue;
94         }
95         else
96         {
97             return top()->m_pIT;
98         }
99     }
100
101     inline bool empty() const
102     {
103         return stack.empty();
104     }
105
106     inline ScopedVariable* top() const
107     {
108         return stack.top();
109     }
110
111     inline void pop()
112     {
113         stack.pop();
114     }
115
116     inline Symbol name_get() const
117     {
118         return name;
119     }
120
121     //globals
122
123     inline void setGlobal(bool _bGlobal)
124     {
125         m_Global = _bGlobal;
126     }
127
128     inline bool isGlobal()
129     {
130         return m_Global;
131     }
132
133     inline bool isGlobalVisible(int _iLevel)
134     {
135         if (empty() == false)
136         {
137             if (top()->m_iLevel == _iLevel)
138             {
139                 return top()->m_globalVisible;
140             }
141         }
142
143         return false;
144     }
145
146     void setGlobalVisible(int _iLevel, bool _bVisible)
147     {
148         if (empty() || top()->m_iLevel != _iLevel)
149         {
150             stack.push(new ScopedVariable(_iLevel, types::Double::Empty()));
151         }
152
153
154         top()->m_globalVisible = _bVisible;
155     }
156
157     void setGlobalValue(types::InternalType* _pIT)
158     {
159         if (m_GlobalValue != _pIT)
160         {
161             if (m_GlobalValue)
162             {
163                 m_GlobalValue->DecreaseRef();
164                 m_GlobalValue->killMe();
165             }
166
167             m_GlobalValue = _pIT;
168             if (_pIT != NULL)
169             {
170                 _pIT->IncreaseRef();
171             }
172         }
173     }
174
175     inline types::InternalType* getGlobalValue()
176     {
177         return m_GlobalValue;
178     }
179
180 private :
181     Symbol name;
182     types::InternalType* m_GlobalValue;
183     bool m_Global;
184     typedef std::stack<ScopedVariable*> StackVar;
185     StackVar stack;
186 };
187
188 struct Variables
189 {
190     Variables() {};
191
192     Variable* getOrCreate(const Symbol& _key)
193     {
194         MapVars::const_iterator it = vars.find(_key);
195         if (it == vars.end())
196         {
197             //create an empty StackedValues
198             Variable* var = new Variable(_key);
199             vars[_key] = var;
200             return var;
201         }
202
203         return it->second;
204     }
205
206     void put(const Symbol& _key, types::InternalType* _pIT, int _iLevel)
207     {
208         Variable* var = getOrCreate(_key);
209         var->put(_pIT, _iLevel);
210     }
211
212     types::InternalType* get(const Symbol& _key, int _iLevel)
213     {
214         MapVars::const_iterator it = vars.find(_key);
215         if (it != vars.end() && it->second->empty() == false)
216         {
217             if (_iLevel == -1 || it->second->top()->m_iLevel == _iLevel)
218             {
219                 return it->second->get();
220             }
221         }
222
223         return NULL;
224     }
225
226     types::InternalType* get(Variable* _var, int _iLevel)
227     {
228         if (_var != NULL && _var->empty() == false)
229         {
230             if (_iLevel == -1 || _var->top()->m_iLevel == _iLevel)
231             {
232                 return _var->get();
233             }
234         }
235
236         return NULL;
237     }
238
239     types::InternalType* getAllButCurrentLevel(const Symbol& _key, int _iLevel)
240     {
241         MapVars::const_iterator it = vars.find(_key);
242         if (it != vars.end() && it->second->empty() == false)
243         {
244             if (it->second->top()->m_iLevel < _iLevel)
245             {
246                 return it->second->get();
247             }
248             else
249             {
250                 ScopedVariable* pSave = it->second->top();
251                 it->second->pop();
252                 types::InternalType* pIT = getAllButCurrentLevel(_key, _iLevel);
253                 it->second->put(pSave->m_pIT, pSave->m_iLevel);
254                 delete pSave;
255                 return pIT;
256             }
257         }
258
259         return NULL;
260     }
261
262     bool remove(Variable* _var, int _iLevel)
263     {
264         if (_var->empty() == false)
265         {
266             if (_var->top()->m_iLevel == _iLevel)
267             {
268                 ScopedVariable* pSave = _var->top();
269                 types::InternalType* pIT = pSave->m_pIT;
270                 pIT->DecreaseRef();
271                 pIT->killMe();
272                 _var->pop();
273                 delete pSave;
274             }
275         }
276
277         return true;
278     }
279
280     bool remove(const Symbol& _key, int _iLevel)
281     {
282         MapVars::iterator it = vars.find(_key);
283         if (it != vars.end())
284         {
285             Variable* pVar = it->second;
286             return remove(pVar, _iLevel);
287         }
288
289         return false;
290     }
291
292     std::list<std::wstring>* getMacrosName()
293     {
294         std::list<std::wstring>* plOut = new std::list<std::wstring>();
295         MapVars::const_iterator it = vars.begin();
296         for (; it != vars.end(); ++it)
297         {
298             if (it->second->empty() == false)
299             {
300                 types::InternalType* pIT = it->second->top()->m_pIT;
301                 if (pIT && (pIT->isMacro() || pIT->isMacroFile()))
302                 {
303                     plOut->push_back(it->first.name_get().c_str());
304                 }
305             }
306         }
307
308         return plOut;
309     }
310
311     std::list<std::wstring>* getVarsName()
312     {
313         std::list<std::wstring>* plOut = new std::list<std::wstring>();
314         MapVars::const_iterator it = vars.begin();
315         for (; it != vars.end(); ++it)
316         {
317             if (it->second->empty() == false)
318             {
319                 types::InternalType* pIT = it->second->top()->m_pIT;
320                 if (pIT &&
321                         pIT->isMacro() == false &&
322                         pIT->isMacroFile() == false &&
323                         pIT->isFunction() == false)
324                 {
325                     plOut->push_back(it->first.name_get().c_str());
326                 }
327             }
328         }
329
330         return plOut;
331     }
332
333     std::list<std::wstring>* getFunctionsName()
334     {
335         std::list<std::wstring>* plOut = new std::list<std::wstring>();
336         MapVars::const_iterator it = vars.begin();
337         for (; it != vars.end(); ++it)
338         {
339             if (it->second->empty() == false)
340             {
341                 types::InternalType* pIT = it->second->top()->m_pIT;
342                 if (pIT && pIT->isFunction())
343                 {
344                     plOut->push_back(it->first.name_get().c_str());
345                 }
346             }
347         }
348
349         return plOut;
350     }
351
352     std::list<Symbol>* getFunctionList(std::wstring _stModuleName, int _iLevel)
353     {
354         std::list<Symbol>* symb = new std::list<Symbol>();
355
356         MapVars::iterator it = vars.begin();
357         for (; it != vars.end() ; ++it)
358         {
359             if (it->second->empty())
360             {
361                 continue;
362             }
363
364             if ((it->second->top()->m_iLevel == _iLevel || _iLevel == 1) && it->second->top()->m_pIT->isCallable())
365             {
366                 types::Callable* pCall = it->second->top()->m_pIT->getAs<types::Callable>();
367                 if (_stModuleName == L"" || _stModuleName == pCall->getModule())
368                 {
369                     symb->push_back(it->first);
370                 }
371             }
372         }
373
374         return symb;
375     }
376
377     bool putInPreviousScope(Variable* _var, types::InternalType* _pIT, int _iLevel)
378     {
379         if (_var->empty())
380         {
381             _var->put(_pIT, _iLevel);
382         }
383         else if (_var->top()->m_iLevel > _iLevel)
384         {
385             ScopedVariable* pVar = _var->top();
386             _var->pop();
387             putInPreviousScope(_var, _pIT, _iLevel);
388             _var->put(pVar->m_pIT, pVar->m_iLevel);
389             delete pVar;
390         }
391         else
392         {
393             _var->put(_pIT, _iLevel);
394         }
395
396         return true;
397     }
398
399     //globals
400
401     void setGlobal(const Symbol& _key)
402     {
403         getOrCreate(_key)->setGlobal(true);
404     }
405
406     void setGlobalVisible(const Symbol& _key, bool _bVisible, int _iLevel)
407     {
408         Variable* pVar = getOrCreate(_key);
409         pVar->setGlobalVisible(_iLevel, _bVisible);
410         if (_bVisible)
411         {
412             pVar->setGlobal(true);
413         }
414     }
415
416     bool isGlobalVisible(const Symbol& _key, int _iLevel)
417     {
418         return getOrCreate(_key)->isGlobalVisible(_iLevel);
419     }
420
421     bool isGlobal(const Symbol& _key, int _iLevel)
422     {
423         return getOrCreate(_key)->isGlobal();
424     }
425
426     types::InternalType* getGlobalValue(const Symbol& _key)
427     {
428         return getOrCreate(_key)->getGlobalValue();
429     }
430
431     void removeGlobal(const Symbol& _key, int _iLevel)
432     {
433         Variable* pVar = getOrCreate(_key);
434         if (pVar->isGlobal())
435         {
436             pVar->setGlobal(false);
437             pVar->setGlobalValue(NULL);
438         }
439
440         remove(pVar, _iLevel);
441     }
442
443     void clearAll()
444     {
445         for (MapVars::iterator it = vars.begin(); it != vars.end() ; ++it)
446         {
447             delete it->second;
448         }
449     }
450
451 private:
452     typedef std::map<Symbol, Variable*> MapVars;
453     MapVars vars;
454 };
455 }
456
457 #endif // !__VARIABLES_HXX__