Typo fixes
[scilab.git] / scilab / modules / ast / includes / ast / runvisitor.hxx
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2010-2010 - DIGITEO - Antoine ELIAS
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15
16 #ifndef AST_RUNVISITOR_HXX
17 #define AST_RUNVISITOR_HXX
18
19 #include "context.hxx"
20 #include "all.hxx"
21 #include "types.hxx"
22 #include "double.hxx"
23 #include "bool.hxx"
24 #include "polynom.hxx"
25 #include "colon.hxx"
26 #include "string.hxx"
27 #include "void.hxx"
28 #include "configvariable.hxx"
29 #include "overload.hxx"
30 #include "scilabWrite.hxx"
31 #include "variables.hxx"
32
33 extern "C" {
34 #include "more.h"
35 #include "sci_malloc.h"
36 }
37
38 namespace ast
39 {
40 class EXTERN_AST RunVisitor : public ConstVisitor
41 {
42 public:
43     RunVisitor()
44     {
45         _expected_result = -1;
46         _resultVect.push_back(nullptr);
47         _result = nullptr;
48         m_bSingleResult = true;
49         m_pAns = symbol::Context::getInstance()->getOrCreate(symbol::Symbol(L"ans"));
50     }
51
52     ~RunVisitor()
53     {
54         clearResult();
55     }
56
57     void clearResultButFirst()
58     {
59         if (!isSingleResult() && _resultVect.size() > 1)
60         {
61             for (std::vector<types::InternalType*>::iterator rv = _resultVect.begin() + 1, end = _resultVect.end(); rv != end; ++rv)
62             {
63                 if (*rv != nullptr)
64                 {
65                     (*rv)->killMe();
66                     *rv = nullptr;
67                 }
68             }
69         }
70     }
71
72     void clearResult()
73     {
74         if (isSingleResult())
75         {
76             if (_result != nullptr)
77             {
78                 //                    std::cout << "before single delete : " << _result << std::endl;
79                 _result->killMe();
80                 //                    std::cout << "after single delete" << std::endl;
81             }
82         }
83         else
84         {
85             for (std::vector<types::InternalType*>::iterator rv = _resultVect.begin(); rv != _resultVect.end(); rv++)
86             {
87                 if (*rv != nullptr)
88                 {
89                     (*rv)->killMe();
90                 }
91             }
92         }
93         _resultVect.clear();
94         m_bSingleResult = true;
95         _result = nullptr;
96     }
97
98 public:
99     int getExpectedSize(void)
100     {
101         return _expected_result;
102     }
103
104     void setExpectedSize(int _iSize)
105     {
106         _expected_result = _iSize;
107     }
108
109     int getResultSize(void)
110     {
111         if (isSingleResult())
112         {
113             if (_result == nullptr)
114             {
115                 return 0;
116             }
117             else
118             {
119                 return 1;
120             }
121         }
122         else
123         {
124             return static_cast<int>(_resultVect.size());
125         }
126     }
127
128     inline types::InternalType* getResult(void)
129     {
130         if (isSingleResult())
131         {
132             return _result;
133         }
134         else
135         {
136             return _resultVect[0];
137         }
138     }
139
140     types::InternalType* getResult(int _iPos)
141     {
142         if (isSingleResult() && _iPos == 0)
143         {
144             return _result;
145         }
146
147         if (_iPos >= static_cast<int>(_resultVect.size()))
148         {
149             return nullptr;
150         }
151         return _resultVect[_iPos];
152     }
153
154     std::vector<types::InternalType*>* getResultList()
155     {
156         // TODO: this function is not used but it could lead to a memleak
157         // (in the first case the vector is allocated and so must be freed)
158         if (getResultSize() == 1)
159         {
160             std::vector<types::InternalType*>* pList = new std::vector<types::InternalType*>;
161             pList->push_back(_result);
162             return pList;
163         }
164         else
165         {
166             return &_resultVect;
167         }
168     }
169
170     void setResult(int _iPos, const types::InternalType *gtVal)
171     {
172         m_bSingleResult = false;
173         if (_iPos >= static_cast<int>(_resultVect.size()))
174         {
175             _resultVect.resize(_iPos + 1, nullptr);
176         }
177
178         _resultVect[_iPos] = const_cast<types::InternalType *>(gtVal);
179     }
180
181     inline void setResult(const types::InternalType *gtVal)
182     {
183         m_bSingleResult = true;
184         _result = const_cast<types::InternalType *>(gtVal);
185     }
186
187     inline void setResult(const types::typed_list & out)
188     {
189         if (out.size() == 0)
190         {
191             setResult(nullptr);
192         }
193         else if (out.size() == 1)
194         {
195             setResult(out[0]);
196         }
197         else
198         {
199             m_bSingleResult = false;
200             _resultVect.clear();
201             for (types::typed_list::const_iterator it = out.begin(); it != out.end(); ++it)
202             {
203                 _resultVect.push_back(*it);
204             }
205         }
206     }
207
208     inline bool isSingleResult()
209     {
210         return m_bSingleResult;
211     }
212
213     void cleanIn(const types::typed_list & in, const types::typed_list & out)
214     {
215         // Check if in contains entries which are in out too.
216         // When an entry is in in and not in out, then in is killed.
217         if (!in.empty())
218         {
219             for (types::typed_list::const_iterator o = out.begin(); o != out.end(); ++o)
220             {
221                 if (*o)
222                 {
223                     (*o)->IncreaseRef();
224                 }
225             }
226
227             for (types::typed_list::const_iterator i = in.begin(); i != in.end(); ++i)
228             {
229                 if (*i)
230                 {
231                     (*i)->DecreaseRef();
232                     (*i)->killMe();
233                 }
234             }
235
236             for (types::typed_list::const_iterator o = out.begin(); o != out.end(); ++o)
237             {
238                 if (*o)
239                 {
240                     (*o)->DecreaseRef();
241                 }
242             }
243         }
244     }
245
246     inline void cleanInOut(const types::typed_list & in, const types::typed_list & out)
247     {
248         cleanIn(in, out);
249         cleanOut(out);
250     }
251
252     void cleanOut(const types::typed_list & out)
253     {
254         if (!out.empty())
255         {
256             for (types::typed_list::const_iterator o = out.begin(); o != out.end(); ++o)
257             {
258                 if (*o)
259                 {
260                     (*o)->killMe();
261                 }
262             }
263         }
264     }
265
266     void cleanOpt(const types::optional_list & opt, const types::typed_list & out)
267     {
268         if (!opt.empty())
269         {
270             for (types::typed_list::const_iterator o = out.begin(); o != out.end(); ++o)
271             {
272                 if (*o)
273                 {
274                     (*o)->IncreaseRef();
275                 }
276             }
277
278             for (types::optional_list::const_iterator o = opt.begin(); o != opt.end(); ++o)
279             {
280                 if (o->second)
281                 {
282                     //decreasef ref after increaseref in callexp
283                     o->second->DecreaseRef();
284                     o->second->killMe();
285                 }
286             }
287
288             for (types::typed_list::const_iterator o = out.begin(); o != out.end(); ++o)
289             {
290                 if (*o)
291                 {
292                     (*o)->DecreaseRef();
293                 }
294             }
295         }
296     }
297
298     /*-------------.
299     | Attributes.  |
300     `-------------*/
301 protected:
302     std::vector<types::InternalType*>    _resultVect;
303     types::InternalType*    _result;
304     bool m_bSingleResult;
305     int _expected_result;
306     symbol::Variable* m_pAns;
307 };
308
309 template <class T>
310 class EXTERN_AST RunVisitorT : public RunVisitor
311 {
312 public :
313     RunVisitorT() : RunVisitor()
314     {
315     }
316
317     types::typed_list* GetArgumentList(exps_t const & _plstArg)
318     {
319         types::typed_list* pArgs = new types::typed_list();
320         for (exps_t::const_iterator it = _plstArg.begin() ; it != _plstArg.end() ; ++it)
321         {
322             (*it)->accept(*this);
323             if (getResultSize() > 1)
324             {
325                 const int size = getResultSize();
326                 for (int i = 0 ; i < size; i++)
327                 {
328                     pArgs->push_back(getResult(i));
329                 }
330             }
331             else
332             {
333                 if (getResult())
334                 {
335                     pArgs->push_back(getResult());
336                 }
337                 //else optional argument skipped
338             }
339         }
340         //to be sure, delete operation does not delete result
341         setResult(nullptr);
342         return pArgs;
343     }
344
345 public :
346     //process in another node
347     void visitprivate(const MatrixLineExp &/*e*/) {}
348     void visitprivate(const CommentExp &/*e*/) {}
349     void visitprivate(const ArrayListVar &/*e*/) {}
350     void visitprivate(const CaseExp &/*e*/) {}
351     void visitprivate(const AssignListExp  &/*e*/) {}
352
353     void visitprivate(const CellExp &e);
354     void visitprivate(const FieldExp &e);
355     void visitprivate(const IfExp &e);
356     void visitprivate(const WhileExp &e);
357     void visitprivate(const ForExp  &e);
358     void visitprivate(const ReturnExp &e);
359     void visitprivate(const SelectExp &e);
360     void visitprivate(const SeqExp  &e);
361     void visitprivate(const NotExp &e);
362     void visitprivate(const TransposeExp &e);
363     void visitprivate(const FunctionDec &e);
364     void visitprivate(const ListExp &e);
365     void visitprivate(const AssignExp &e);
366     void visitprivate(const OpExp &e);
367     void visitprivate(const LogicalOpExp &e);
368     void visitprivate(const MatrixExp &e);
369     void visitprivate(const CallExp &e);
370     void visitprivate(const CellCallExp &e);
371     void visitprivate(const OptimizedExp &e);
372     void visitprivate(const MemfillExp &e);
373     void visitprivate(const DAXPYExp &e);
374     void visitprivate(const IntSelectExp &e);
375     void visitprivate(const StringSelectExp &e);
376     void visitprivate(const TryCatchExp &e);
377
378     void visitprivate(const StringExp & e);
379     void visitprivate(const DoubleExp & e);
380     void visitprivate(const BoolExp & e);
381     void visitprivate(const NilExp & e);
382     void visitprivate(const SimpleVar & e);
383     void visitprivate(const ColonVar & e);
384     void visitprivate(const DollarVar & e);
385     void visitprivate(const BreakExp & e);
386     void visitprivate(const ContinueExp & e);
387     void visitprivate(const ArrayListExp & e);
388     void visitprivate(const VarDec & e);
389
390     types::InternalType* callOverloadOpExp(OpExp::Oper _oper, types::InternalType* _paramL, types::InternalType* _paramR);
391     types::InternalType* callOverloadMatrixExp(const std::wstring& strType, types::InternalType* _paramL, types::InternalType* _paramR);
392 };
393 }
394
395 #endif // !AST_RUNVISITOR_HXX