fix 'some' memory leaks @startup
[scilab.git] / scilab / modules / ast / src / cpp / ast / runvisitor.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2014 - Scilab Enterprises - Antoine ELIAS
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 //for Visual Leak Detector
14 //#define DEBUG_VLD
15 #if defined(DEBUG_VLD)
16 #include <vld.h>
17 #endif
18
19 #include <string>
20
21 #include "runvisitor.hxx"
22 #include "execvisitor.hxx"
23 #include "stepvisitor.hxx"
24 #include "timedvisitor.hxx"
25 #include "shortcutvisitor.hxx"
26 #include "printvisitor.hxx"
27 #include "mutevisitor.hxx"
28
29 #include "visitor_common.hxx"
30
31 #include "context.hxx"
32 #include "generic_operations.hxx"
33 #include "types_or.hxx"
34 #include "types_and.hxx"
35 #include "localization.hxx"
36
37 #include "macrofile.hxx"
38 #include "macro.hxx"
39
40 extern "C"
41 {
42 #include "sciprint.h"
43 #include "os_string.h"
44 #include "elem_common.h"
45 }
46
47 namespace ast
48 {
49 template <class T>
50 void RunVisitorT<T>::visitprivate(const CellExp &e)
51 {
52     exps_t::const_iterator row;
53     exps_t::const_iterator col;
54     int iColMax = 0;
55
56     exps_t lines = e.getLines();
57     //check dimmension
58     for (row = lines.begin() ; row != lines.end() ; ++row )
59     {
60         exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
61         if (iColMax == 0)
62         {
63             iColMax = static_cast<int>(cols.size());
64         }
65
66         if (iColMax != static_cast<int>(cols.size()))
67         {
68             std::wostringstream os;
69             os << _W("inconsistent row/column dimensions\n");
70             //os << ((Location)(*row)->getLocation()).getLocationString() << std::endl;
71             throw ScilabError(os.str(), 999, (*row)->getLocation());
72         }
73     }
74
75     //alloc result cell
76     types::Cell *pC = new types::Cell(static_cast<int>(lines.size()), iColMax);
77
78     int i = 0;
79     int j = 0;
80
81     //insert items in cell
82     for (i = 0, row = lines.begin() ; row != lines.end() ; ++row, ++i)
83     {
84         exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
85         for (j = 0, col = cols.begin() ; col != cols.end() ; ++col, ++j)
86         {
87             (*col)->accept(*this);
88             InternalType *pIT = getResult();
89             if (pIT->isImplicitList())
90             {
91                 InternalType * _pIT = pIT->getAs<ImplicitList>()->extractFullMatrix();
92                 pC->set(i, j, _pIT);
93                 _pIT->killMe();
94             }
95             else
96             {
97                 pC->set(i, j, pIT);
98             }
99             clearResult();
100         }
101     }
102
103     //return new cell
104     setResult(pC);
105 }
106
107 template <class T>
108 void RunVisitorT<T>::visitprivate(const FieldExp &e)
109 {
110     /*
111       a.b
112     */
113
114     if (!e.getTail()->isSimpleVar())
115     {
116         wchar_t szError[bsiz];
117         os_swprintf(szError, bsiz, _W("/!\\ Unmanaged FieldExp.\n").c_str());
118         throw ScilabError(szError, 999, e.getLocation());
119     }
120
121     try
122     {
123         e.getHead()->accept(*this);
124     }
125     catch (const ScilabError& error)
126     {
127         throw error;
128     }
129
130     if (getResult() == NULL)
131     {
132         wchar_t szError[bsiz];
133         os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
134         throw ScilabError(szError, 999, e.getLocation());
135     }
136
137     // TODO: handle case where getSize() > 1
138     // l=list(struct("toto","coucou"),struct("toto","hello"),1,2);[a,b]=l(1:2).toto
139     //
140     if (getResultSize() > 1)
141     {
142         clearResult();
143         wchar_t szError[bsiz];
144         os_swprintf(szError, bsiz, _W("Not yet implemented in Scilab.\n").c_str());
145         throw ScilabError(szError, 999, e.getLocation());
146     }
147
148     SimpleVar * psvRightMember = static_cast<SimpleVar *>(const_cast<Exp *>(e.getTail()));
149     std::wstring wstField = psvRightMember->getSymbol().getName();
150     InternalType * pValue = getResult();
151     InternalType * pReturn = NULL;
152     bool ok = false;
153
154     try
155     {
156         if (pValue->isGenericType())
157         {
158             ok = pValue->getAs<GenericType>()->extract(wstField, pReturn);
159         }
160     }
161     catch (std::wstring & err)
162     {
163         pValue->killMe();
164         throw ScilabError(err.c_str(), 999, e.getTail()->getLocation());
165     }
166
167     if (ok)
168     {
169         if (pReturn == NULL)
170         {
171             std::wostringstream os;
172             os << _W("Invalid index.\n");
173             throw ScilabError(os.str(), 999, e.getLocation());
174         }
175
176         setResult(pReturn);
177         if (pValue->isDeletable())
178         {
179             if (pValue->isContainer())
180             {
181                 // prevent delete of pReturn in case where
182                 // extract not return a clone
183                 pReturn->IncreaseRef();
184                 pValue->killMe();
185                 pReturn->DecreaseRef();
186             }
187             else
188             {
189                 pValue->killMe();
190             }
191         }
192     }
193     else if (pValue->isFieldExtractionOverloadable())
194     {
195         types::typed_list in;
196         types::typed_list out;
197
198         String* pS = new String(wstField.c_str());
199
200         //TODO: in the case where overload is a macro there is no need to incref in
201         // because args will be put in context, removed and killed if required.
202         // But if the overload is a function... it is another story...
203
204         pS->IncreaseRef();
205         pValue->IncreaseRef();
206
207         in.push_back(pS);
208         in.push_back(pValue);
209         Callable::ReturnValue Ret = Callable::Error;
210         std::wstring stType = pValue->getShortTypeStr();
211
212         try
213         {
214             Ret = Overload::call(L"%" + stType + L"_e", in, 1, out, this);
215         }
216         catch (ast::ScilabError &/*se*/)
217         {
218             try
219             {
220                 //to compatibility with scilab 5 code.
221                 //tlist/mlist name are truncated to 8 first character
222                 if (stType.size() > 8)
223                 {
224                     Ret = Overload::call(L"%" + stType.substr(0, 8) + L"_e", in, 1, out, this);
225                 }
226             }
227             catch (ast::ScilabError & se)
228             {
229                 // TList or Mlist
230                 if (pValue->isList())
231                 {
232                     Ret = Overload::call(L"%l_e", in, 1, out, this);
233                 }
234                 else
235                 {
236                     throw se;
237                 }
238             }
239         }
240
241         if (Ret != Callable::OK)
242         {
243             cleanInOut(in, out);
244             throw ScilabError();
245         }
246
247         setResult(out);
248         cleanIn(in, out);
249     }
250     else
251     {
252         pValue->killMe();
253         wchar_t szError[bsiz];
254         os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
255         throw ScilabError(szError, 999, e.getLocation());
256     }
257 }
258
259 template <class T>
260 void RunVisitorT<T>::visitprivate(const IfExp  &e)
261 {
262     //Create local exec visitor
263     ShortCutVisitor SCTest;
264     bool bTestStatus = false;
265
266     //condition
267     e.getTest().accept(SCTest);
268     e.getTest().accept(*this);
269
270     bTestStatus = getResult()->isTrue();
271     clearResult();
272     if (bTestStatus == true)
273     {
274         //condition == true
275         if (e.isBreakable())
276         {
277             const_cast<IfExp*>(&e)->resetBreak();
278             const_cast<Exp*>(&e.getThen())->setBreakable();
279         }
280
281         if (e.isContinuable())
282         {
283             const_cast<IfExp*>(&e)->resetContinue();
284             const_cast<Exp*>(&e.getThen())->setContinuable();
285         }
286
287         if (e.isReturnable())
288         {
289             const_cast<IfExp*>(&e)->resetReturn();
290             const_cast<Exp*>(&e.getThen())->setReturnable();
291         }
292
293         e.getThen().accept(*this);
294     }
295     else
296     {
297         //condition == false
298
299         if (e.hasElse())
300         {
301             if (e.isBreakable())
302             {
303                 const_cast<Exp*>(&e.getElse())->setBreakable();
304             }
305
306             if (e.isContinuable())
307             {
308                 const_cast<IfExp*>(&e)->resetContinue();
309                 const_cast<Exp*>(&e.getElse())->setContinuable();
310             }
311
312             if (e.isReturnable())
313             {
314                 const_cast<Exp*>(&e.getElse())->setReturnable();
315             }
316
317             e.getElse().accept(*this);
318         }
319     }
320
321     if (e.isBreakable()
322             && ( (&e.getElse())->isBreak()
323                  || (&e.getThen())->isBreak() ))
324     {
325         const_cast<IfExp*>(&e)->setBreak();
326         const_cast<Exp*>(&e.getElse())->resetBreak();
327         const_cast<Exp*>(&e.getThen())->resetBreak();
328     }
329
330     if (e.isContinuable()
331             && ( (&e.getElse())->isContinue()
332                  || (&e.getThen())->isContinue() ))
333     {
334         const_cast<IfExp*>(&e)->setContinue();
335         const_cast<Exp*>(&e.getElse())->resetContinue();
336         const_cast<Exp*>(&e.getThen())->resetContinue();
337     }
338
339     if (e.isReturnable()
340             && ( (&e.getElse())->isReturn()
341                  || (&e.getThen())->isReturn() ))
342     {
343         const_cast<IfExp*>(&e)->setReturn();
344         const_cast<Exp*>(&e.getElse())->resetReturn();
345         const_cast<Exp*>(&e.getThen())->resetReturn();
346     }
347 }
348
349 template <class T>
350 void RunVisitorT<T>::visitprivate(const WhileExp  &e)
351 {
352     //allow break and continue operations
353     const_cast<Exp*>(&e.getBody())->setBreakable();
354     const_cast<Exp*>(&e.getBody())->setContinuable();
355     //allow return operation
356     if (e.isReturnable())
357     {
358         const_cast<Exp*>(&(e.getBody()))->setReturnable();
359     }
360
361     //condition
362     e.getTest().accept(*this);
363     while (getResult()->isTrue())
364     {
365         e.getBody().accept(*this);
366         if (e.getBody().isBreak())
367         {
368             const_cast<Exp*>(&(e.getBody()))->resetBreak();
369             break;
370         }
371
372         if (e.getBody().isReturn())
373         {
374             const_cast<WhileExp*>(&e)->setReturn();
375             const_cast<Exp*>(&(e.getBody()))->resetReturn();
376             break;
377         }
378
379         if (e.getBody().isContinue())
380         {
381             const_cast<WhileExp*>(&e)->setContinue();
382             const_cast<Exp*>(&(e.getBody()))->resetContinue();
383             e.getTest().accept(*this);
384             continue;
385         }
386
387         //clear old result value before evaluate new one
388         if (getResult() != NULL)
389         {
390             getResult()->killMe();
391         }
392
393         e.getTest().accept(*this);
394     }
395
396     //clear result of condition or result of body
397     clearResult();
398 }
399
400 template <class T>
401 void RunVisitorT<T>::visitprivate(const ForExp  &e)
402 {
403     e.getVardec().accept(*this);
404     InternalType* pIT = getResult();
405     //allow break and continue operations
406     const_cast<Exp&>(e.getBody()).setBreakable();
407     const_cast<Exp&>(e.getBody()).setContinuable();
408
409     //allow return operation
410     if (e.isReturnable())
411     {
412         const_cast<Exp&>(e.getBody()).resetReturn();
413         const_cast<Exp&>(e.getBody()).setReturnable();
414     }
415
416     if (pIT->isImplicitList())
417     {
418         ImplicitList* pVar = pIT->getAs<ImplicitList>();
419         for (int i = 0; i < pVar->getSize(); ++i)
420         {
421             //TODO : maybe it would be interesting here to reuse the same InternalType (to avoid delete/new)
422             InternalType * pIL = pVar->extractValue(i);
423             symbol::Context::getInstance()->put(e.getVardec().getAs<VarDec>()->getStack(), pIL);
424
425             e.getBody().accept(*this);
426             if (e.getBody().isBreak())
427             {
428                 const_cast<Exp&>(e.getBody()).resetBreak();
429                 break;
430             }
431
432             if (e.getBody().isContinue())
433             {
434                 const_cast<Exp&>(e.getBody()).resetContinue();
435                 continue;
436             }
437
438             if (e.getBody().isReturn())
439             {
440                 const_cast<ForExp&>(e).setReturn();
441                 const_cast<Exp&>(e.getBody()).resetReturn();
442                 break;
443             }
444         }
445     }
446     else if (pIT->isList())
447     {
448         List* pL = pIT->getAs<List>();
449         const int size = pL->getSize();
450         for (int i = 0; i < size; ++i)
451         {
452             InternalType* pNew = pL->get(i);
453             symbol::Context::getInstance()->put(e.getVardec().getAs<VarDec>()->getStack(), pNew);
454
455             e.getBody().accept(*this);
456             if (e.getBody().isBreak())
457             {
458                 const_cast<Exp*>(&(e.getBody()))->resetBreak();
459                 break;
460             }
461
462             if (e.getBody().isContinue())
463             {
464                 const_cast<Exp*>(&(e.getBody()))->resetContinue();
465                 continue;
466             }
467
468             if (e.getBody().isReturn())
469             {
470                 const_cast<ForExp*>(&e)->setReturn();
471                 const_cast<Exp&>(e.getBody()).resetReturn();
472                 break;
473             }
474         }
475     }
476     else if (pIT->isGenericType())
477     {
478         //Matrix i = [1,3,2,6] or other type
479         GenericType* pVar = pIT->getAs<GenericType>();
480         if (pVar->getDims() > 2)
481         {
482             pIT->DecreaseRef();
483             pIT->killMe();
484             throw ScilabError(_W("for expression can only manage 1 or 2 dimensions variables\n"), 999, e.getVardec().getLocation());
485         }
486
487         for (int i = 0; i < pVar->getCols(); i++)
488         {
489             GenericType* pNew = pVar->getColumnValues(i);
490             if (pNew == NULL)
491             {
492                 pIT->DecreaseRef();
493                 pIT->killMe();
494                 throw ScilabError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
495             }
496
497             symbol::Context::getInstance()->put(e.getVardec().getAs<VarDec>()->getStack(), pNew);
498
499             e.getBody().accept(*this);
500             if (e.getBody().isBreak())
501             {
502                 const_cast<Exp*>(&(e.getBody()))->resetBreak();
503                 break;
504             }
505
506             if (e.getBody().isContinue())
507             {
508                 const_cast<Exp*>(&(e.getBody()))->resetContinue();
509                 continue;
510             }
511
512             if (e.getBody().isReturn())
513             {
514                 const_cast<ForExp*>(&e)->setReturn();
515                 const_cast<Exp&>(e.getBody()).resetReturn();
516                 break;
517             }
518         }
519     }
520     else
521     {
522         pIT->DecreaseRef();
523         pIT->killMe();
524         throw ScilabError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
525     }
526
527     pIT->DecreaseRef();
528     pIT->killMe();
529
530     setResult(NULL);
531 }
532
533 template <class T>
534 void RunVisitorT<T>::visitprivate(const ReturnExp &e)
535 {
536     if (e.isGlobal())
537     {
538         if (ConfigVariable::getPauseLevel() != 0 && symbol::Context::getInstance()->getScopeLevel() == ConfigVariable::getActivePauseLevel())
539         {
540             //return or resume
541             ThreadId* pThreadId = ConfigVariable::getLastPausedThread();
542             if (pThreadId == NULL)
543             {
544                 //no paused thread, so just go leave
545                 return;
546             }
547
548             //force exit without prompt of current thread ( via Aborted status )
549             ThreadId* pMe = ConfigVariable::getThread(__GetCurrentThreadKey());
550             pMe->setStatus(ThreadId::Aborted);
551
552             //resume previous execution thread
553             pThreadId->resume();
554
555             return;
556         }
557         else
558         {
559             const_cast<ReturnExp*>(&e)->setReturn();
560         }
561     }
562     else
563     {
564         //return(x)
565
566         //in case of CallExp, we can return only one values
567         int iSaveExpectedSize = getExpectedSize();
568         setExpectedSize(1);
569         e.getExp().accept(*this);
570         setExpectedSize(iSaveExpectedSize);
571         const_cast<ReturnExp*>(&e)->setReturn();
572     }
573 }
574
575 template <class T>
576 void RunVisitorT<T>::visitprivate(const SelectExp &e)
577 {
578     // FIXME : exec select ... case ... else ... end
579     e.getSelect()->accept(*this);
580     bool bCase = false;
581
582
583     InternalType* pIT = getResult();
584     setResult(NULL);
585     if (pIT)
586     {
587         //find good case
588         exps_t::iterator it;
589         exps_t* cases = e.getCases();
590         for (it = cases->begin(); it != cases->end() ; it++)
591         {
592             CaseExp* pCase = (*it)->getAs<CaseExp>();
593             pCase->getTest()->accept(*this);
594             InternalType *pITCase = getResult();
595             setResult(NULL);
596             if (pITCase)
597             {
598                 if (pITCase->isContainer()) //WARNING ONLY FOR CELL
599                 {
600                     //check each item
601                 }
602                 else if (*pITCase == *pIT)
603                 {
604                     if (e.isBreakable())
605                     {
606                         const_cast<SelectExp*>(&e)->resetBreak();
607                         pCase->getBody()->setBreakable();
608                     }
609
610                     if (e.isContinuable())
611                     {
612                         const_cast<SelectExp*>(&e)->resetContinue();
613                         pCase->getBody()->setContinuable();
614                     }
615
616                     if (e.isReturnable())
617                     {
618                         const_cast<SelectExp*>(&e)->resetReturn();
619                         pCase->getBody()->setReturnable();
620                     }
621
622                     //the good one
623                     pCase->getBody()->accept(*this);
624
625                     if (e.isBreakable() && pCase->getBody()->isBreak())
626                     {
627                         const_cast<SelectExp*>(&e)->setBreak();
628                         pCase->getBody()->resetBreak();
629                     }
630
631                     if (e.isContinuable() && pCase->getBody()->isContinue())
632                     {
633                         const_cast<SelectExp*>(&e)->setContinue();
634                         pCase->getBody()->resetContinue();
635                     }
636
637                     if (e.isReturnable() && pCase->getBody()->isReturn())
638                     {
639                         const_cast<SelectExp*>(&e)->setReturn();
640                         pCase->getBody()->resetReturn();
641                     }
642
643                     bCase = true;
644                     break;
645                 }
646             }
647         }
648
649         delete cases;
650     }
651
652     if (bCase == false && e.getDefaultCase() != NULL)
653     {
654         if (e.isBreakable())
655         {
656             const_cast<SelectExp*>(&e)->resetBreak();
657             e.getDefaultCase()->setBreakable();
658         }
659
660         if (e.isContinuable())
661         {
662             const_cast<SelectExp*>(&e)->resetContinue();
663             e.getDefaultCase()->setContinuable();
664         }
665
666         if (e.isReturnable())
667         {
668             const_cast<SelectExp*>(&e)->resetReturn();
669             e.getDefaultCase()->setReturnable();
670         }
671
672         //default case
673         e.getDefaultCase()->accept(*this);
674
675         if (e.isBreakable() && e.getDefaultCase()->isBreak())
676         {
677             const_cast<SelectExp*>(&e)->setBreak();
678             e.getDefaultCase()->resetBreak();
679         }
680
681         if (e.isContinuable() && e.getDefaultCase()->isContinue())
682         {
683             const_cast<SelectExp*>(&e)->setContinue();
684             e.getDefaultCase()->resetContinue();
685         }
686
687         if (e.isReturnable() && e.getDefaultCase()->isReturn())
688         {
689             const_cast<SelectExp*>(&e)->setReturn();
690             e.getDefaultCase()->resetReturn();
691         }
692     }
693
694     clearResult();
695
696     pIT->killMe();
697 }
698
699 template <class T>
700 void RunVisitorT<T>::visitprivate(const SeqExp  &e)
701 {
702     //T execMe;
703     exps_t::const_iterator itExp;
704     exps_t exps = e.getExps();
705
706     for (itExp = exps.begin (); itExp != exps.end (); ++itExp)
707     {
708         if (e.isBreakable())
709         {
710             (*itExp)->resetBreak();
711             (*itExp)->setBreakable();
712         }
713
714         if (e.isContinuable())
715         {
716             (*itExp)->resetContinue();
717             (*itExp)->setContinuable();
718         }
719
720         if (e.isReturnable())
721         {
722             (*itExp)->setReturnable();
723         }
724
725         try
726         {
727             //reset default values
728             setResult(NULL);
729             setExpectedSize(-1);
730             (*itExp)->accept(*this);
731             InternalType * pIT = getResult();
732
733             if (pIT != NULL)
734             {
735                 bool bImplicitCall = false;
736                 if (pIT->isCallable()) //to manage call without ()
737                 {
738                     Callable *pCall = pIT->getAs<Callable>();
739                     typed_list out;
740                     typed_list in;
741                     optional_list opt;
742
743                     try
744                     {
745                         //in this case of calling, we can return only one values
746                         int iSaveExpectedSize = getExpectedSize();
747                         setExpectedSize(1);
748                         Function::ReturnValue Ret = pCall->call(in, opt, getExpectedSize(), out, this);
749                         setExpectedSize(iSaveExpectedSize);
750
751                         if (Ret == Callable::OK)
752                         {
753                             if (out.size() == 0)
754                             {
755                                 setResult(NULL);
756                             }
757                             else
758                             {
759                                 setResult(out[0]);
760                             }
761                             bImplicitCall = true;
762                         }
763                         else if (Ret == Callable::Error)
764                         {
765                             if (ConfigVariable::getLastErrorFunction() == L"")
766                             {
767                                 ConfigVariable::setLastErrorFunction(pCall->getName());
768                                 ConfigVariable::setLastErrorLine(e.getLocation().first_line);
769                                 throw ScilabError();
770                             }
771
772                             if (pCall->isMacro() || pCall->isMacroFile())
773                             {
774                                 wchar_t szError[bsiz];
775                                 os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), (*itExp)->getLocation().first_line, pCall->getName().c_str());
776                                 throw ScilabMessage(szError);
777                             }
778                             else
779                             {
780                                 throw ScilabMessage();
781                             }
782                         }
783                     }
784                     catch (ScilabMessage sm)
785                     {
786                         wostringstream os;
787                         PrintVisitor printMe(os);
788                         (*itExp)->accept(printMe);
789                         //os << std::endl << std::endl;
790                         if (ConfigVariable::getLastErrorFunction() == L"")
791                         {
792                             ConfigVariable::setLastErrorFunction(pCall->getName());
793                         }
794
795                         if (pCall->isMacro() || pCall->isMacroFile())
796                         {
797                             wchar_t szError[bsiz];
798                             os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), sm.GetErrorLocation().first_line, pCall->getName().c_str());
799                             throw ScilabMessage(szError + os.str());
800                         }
801                         else
802                         {
803                             sm.SetErrorMessage(sm.GetErrorMessage() + os.str());
804                             throw sm;
805                         }
806                     }
807                 }
808
809                 //don't output Simplevar and empty result
810                 if (getResult() != NULL && (!(*itExp)->isSimpleVar() || bImplicitCall))
811                 {
812                     //symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), *execMe.getResult());
813                     InternalType* pITAns = getResult();
814                     symbol::Context::getInstance()->put(m_pAns, pITAns);
815                     if ((*itExp)->isVerbose() && ConfigVariable::isPromptShow())
816                     {
817                         //TODO manage multiple returns
818                         scilabWriteW(L" ans  =\n\n");
819                         std::wostringstream ostrName;
820                         ostrName << L"ans";
821                         VariableToString(pITAns, ostrName.str().c_str());
822                     }
823                 }
824
825                 pIT->killMe();
826             }
827
828             if ((&e)->isBreakable() && (*itExp)->isBreak())
829             {
830                 const_cast<SeqExp *>(&e)->setBreak();
831                 break;
832             }
833
834             if ((&e)->isContinuable() && (*itExp)->isContinue())
835             {
836                 const_cast<SeqExp *>(&e)->setContinue();
837                 break;
838             }
839
840             if ((&e)->isReturnable() && (*itExp)->isReturn())
841             {
842                 const_cast<SeqExp *>(&e)->setReturn();
843                 (*itExp)->resetReturn();
844                 break;
845             }
846         }
847         catch (const ScilabMessage& sm)
848         {
849             scilabErrorW(sm.GetErrorMessage().c_str());
850
851             CallExp* pCall = dynamic_cast<CallExp*>(*itExp);
852             if (pCall != NULL)
853             {
854                 //to print call expression only of it is a macro
855                 pCall->getName().accept(*this);
856
857                 if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
858                 {
859                     wostringstream os;
860                     PrintVisitor printMe(os);
861                     pCall->accept(printMe);
862                     //os << std::endl << std::endl;
863                     if (ConfigVariable::getLastErrorFunction() == L"")
864                     {
865                         ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
866                     }
867                     throw ScilabMessage(os.str(), 0, (*itExp)->getLocation());
868                 }
869             }
870
871             throw ScilabMessage((*itExp)->getLocation());
872         }
873         catch (const ScilabError& se)
874         {
875             // check on error number because error message can be empty.
876             if (ConfigVariable::getLastErrorNumber() == 0)
877             {
878                 ConfigVariable::setLastErrorMessage(se.GetErrorMessage());
879                 ConfigVariable::setLastErrorNumber(se.GetErrorNumber());
880                 ConfigVariable::setLastErrorLine(se.GetErrorLocation().first_line);
881                 ConfigVariable::setLastErrorFunction(wstring(L""));
882             }
883
884             CallExp* pCall = dynamic_cast<CallExp*>(*itExp);
885             if (pCall != NULL)
886             {
887                 //to print call expression only of it is a macro
888                 try
889                 {
890                     pCall->getName().accept(*this);
891                     if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
892                     {
893                         wostringstream os;
894                         PrintVisitor printMe(os);
895                         pCall->accept(printMe);
896                         //os << std::endl << std::endl;
897                         ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
898                         scilabErrorW(se.GetErrorMessage().c_str());
899                         throw ScilabMessage(os.str(), 999, (*itExp)->getLocation());
900                     }
901                 }
902                 catch (ScilabError se2)
903                 {
904                     //just to catch exception, do nothing
905                 }
906             }
907
908             scilabErrorW(se.GetErrorMessage().c_str());
909             scilabErrorW(L"\n");
910             throw ScilabMessage((*itExp)->getLocation());
911         }
912
913         // If something other than NULL is given to setResult, then that would imply
914         // to make a cleanup in visit(ForExp) for example (e.getBody().accept(*this);)
915         setResult(NULL);
916     }
917 }
918
919 template <class T>
920 void RunVisitorT<T>::visitprivate(const NotExp &e)
921 {
922     /*
923       @ or ~ !
924     */
925     e.getExp().accept(*this);
926
927     InternalType * pValue = getResult();
928     InternalType * pReturn = NULL;
929     if (pValue->neg(pReturn))
930     {
931         if (pValue != pReturn)
932         {
933             pValue->killMe();
934         }
935
936         setResult(pReturn);
937     }
938     else
939     {
940         // neg returned false so the negation is not possible so we call the overload (%foo_5)
941         types::typed_list in;
942         types::typed_list out;
943
944         pValue->IncreaseRef();
945         in.push_back(pValue);
946
947         Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_5", in, 1, out, this);
948
949         if (Ret != Callable::OK)
950         {
951             cleanInOut(in, out);
952             throw ScilabError();
953         }
954
955         setResult(out);
956         cleanIn(in, out);
957     }
958 }
959
960 template <class T>
961 void RunVisitorT<T>::visitprivate(const TransposeExp &e)
962 {
963     e.getExp().accept(*this);
964
965     if (getResultSize() != 1)
966     {
967         clearResult();
968         wchar_t szError[bsiz];
969         os_swprintf(szError, bsiz, _W("%ls: Can not transpose multiple elements.\n").c_str(), L"Transpose");
970         throw ScilabError(szError, 999, e.getLocation());
971     }
972
973     InternalType * pValue = getResult();
974     InternalType * pReturn = NULL;
975     const bool bConjug = e.getConjugate() == TransposeExp::_Conjugate_;
976
977     if ((bConjug && pValue->adjoint(pReturn)) || (!bConjug && pValue->transpose(pReturn)))
978     {
979         if (pValue != pReturn)
980         {
981             pValue->killMe();
982         }
983
984         setResult(pReturn);
985
986         return;
987     }
988     else
989     {
990         // transpose returned false so the negation is not possible so we call the overload (%foo_t or %foo_0)
991         types::typed_list in;
992         types::typed_list out;
993
994         pValue->IncreaseRef();
995         in.push_back(pValue);
996
997         Callable::ReturnValue Ret;
998         if (bConjug)
999         {
1000             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_t", in, 1, out, this);
1001         }
1002         else
1003         {
1004             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_0", in, 1, out, this);
1005         }
1006
1007         if (Ret != Callable::OK)
1008         {
1009             cleanInOut(in, out);
1010             throw ScilabError();
1011         }
1012
1013         setResult(out);
1014         cleanIn(in, out);
1015     }
1016 }
1017
1018 template <class T>
1019 void RunVisitorT<T>::visitprivate(const FunctionDec & e)
1020 {
1021
1022     /*
1023       function foo
1024       endfunction
1025     */
1026
1027     // funcprot(0) : do nothing
1028     // funcprot(1) && warning(on) : warning
1029     //get input parameters list
1030     std::list<symbol::Variable*> *pVarList = new std::list<symbol::Variable*>();
1031     const ArrayListVar* pListVar = e.getArgs().getAs<ArrayListVar>();
1032     exps_t vars = pListVar->getVars();
1033     for (exps_t::const_iterator it = vars.begin(), end = vars.end(); it != end; ++it)
1034     {
1035         pVarList->push_back((*it)->getAs<SimpleVar>()->getStack());
1036     }
1037
1038     //get output parameters list
1039     std::list<symbol::Variable*> *pRetList = new std::list<symbol::Variable*>();
1040     const ArrayListVar *pListRet = e.getReturns().getAs<ArrayListVar>();
1041     exps_t rets = pListRet->getVars();
1042     for (exps_t::const_iterator it = rets.begin(), end = rets.end(); it != end; ++it)
1043     {
1044         pRetList->push_back((*it)->getAs<SimpleVar>()->getStack());
1045     }
1046
1047     types::Macro *pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList,
1048                                             const_cast<SeqExp&>(static_cast<const SeqExp&>(e.getBody())), L"script");
1049     pMacro->setFirstLine(e.getLocation().first_line);
1050
1051     bool bEquals = false;
1052     int iFuncProt = ConfigVariable::getFuncprot();
1053     if (iFuncProt != 0)
1054     {
1055         types::InternalType* pITFunc = symbol::Context::getInstance()->get(((FunctionDec&)e).getStack());
1056         if (pITFunc && pITFunc->isCallable())
1057         {
1058             if (pITFunc->isMacroFile())
1059             {
1060                 types::MacroFile* pMF = pITFunc->getAs<types::MacroFile>();
1061                 bEquals = *pMF->getMacro() == *pMacro;
1062             }
1063             else if (pITFunc->isMacro())
1064             {
1065                 types::Macro* pM = pITFunc->getAs<types::Macro>();
1066                 bEquals = *pM == *pMacro;
1067             }
1068         }
1069         else
1070         {
1071             bEquals = true; //avoid msg but keep assignation
1072         }
1073     }
1074
1075     if (bEquals == false && iFuncProt == 1 && ConfigVariable::getWarningMode())
1076     {
1077         wchar_t pwstFuncName[1024];
1078         os_swprintf(pwstFuncName, 1024, L"%-24ls", e.getSymbol().getName().c_str());
1079         char* pstFuncName = wide_string_to_UTF8(pwstFuncName);
1080
1081         sciprint(_("Warning : redefining function: %s. Use funcprot(0) to avoid this message"), pstFuncName);
1082         sciprint("\n");
1083         FREE(pstFuncName);
1084     }
1085     else if (bEquals == false && iFuncProt == 2)
1086     {
1087         char pstError[1024];
1088         char* pstFuncName = wide_string_to_UTF8(e.getSymbol().getName().c_str());
1089         os_sprintf(pstError, _("It is not possible to redefine the %s primitive this way (see clearfun).\n"), pstFuncName);
1090         wchar_t* pwstError = to_wide_string(pstError);
1091         std::wstring wstError(pwstError);
1092         FREE(pstFuncName);
1093         FREE(pwstError);
1094         throw ScilabError(wstError, 999, e.getLocation());
1095     }
1096
1097     symbol::Context::getInstance()->addMacro(pMacro);
1098
1099 }
1100
1101 template <class T>
1102 void RunVisitorT<T>::visitprivate(const ListExp &e)
1103 {
1104     e.getStart().accept(*this);
1105     GenericType* pITStart = static_cast<GenericType*>(getResult());
1106     if ((pITStart->getSize() != 1 || (pITStart->isDouble() && pITStart->getAs<Double>()->isComplex())) &&
1107             pITStart->isList() == false) // list case => call overload
1108     {
1109         pITStart->killMe();
1110         wchar_t szError[bsiz];
1111         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 1);
1112         throw ScilabError(szError, 999, e.getLocation());
1113     }
1114     InternalType * piStart = pITStart;
1115
1116     e.getStep().accept(*this);
1117     GenericType* pITStep = static_cast<GenericType*>(getResult());
1118     if ((pITStep->getSize() != 1 || (pITStep->isDouble() && pITStep->getAs<Double>()->isComplex())) &&
1119             pITStep->isList() == false) // list case => call overload
1120     {
1121         pITStart->killMe();
1122         pITStep->killMe();
1123         wchar_t szError[bsiz];
1124         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2);
1125         throw ScilabError(szError, 999, e.getLocation());
1126     }
1127     InternalType* piStep = pITStep;
1128
1129     e.getEnd().accept(*this);
1130     GenericType* pITEnd = static_cast<GenericType*>(getResult());
1131     if ((pITEnd->getSize() != 1 || (pITEnd->isDouble() && pITEnd->getAs<Double>()->isComplex())) &&
1132             pITEnd->isList() == false) // list case => call overload
1133     {
1134         pITStart->killMe();
1135         pITStep->killMe();
1136         pITEnd->killMe();
1137         wchar_t szError[bsiz];
1138         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 3);
1139         throw ScilabError(szError, 999, e.getLocation());
1140     }
1141     InternalType* piEnd = pITEnd;
1142
1143     //check compatibility
1144     // double : double : double or poly : poly : poly and mix like double : double : poly
1145     if ((piStart->isPoly() || piStart->isDouble()) &&
1146             (piStep->isPoly()  || piStep->isDouble())  &&
1147             (piEnd->isPoly()   || piEnd->isDouble()))
1148     {
1149         // No need to kill piStart, ... because Implicit list ctor will incref them
1150         setResult(new ImplicitList(piStart, piStep, piEnd));
1151         return;
1152     }
1153
1154     // int : double or int : int
1155     if ( piStart->isInt()   &&
1156             (piStep->isDouble() || piStep->isInt()) &&
1157             piEnd->isInt())
1158     {
1159         // check for same int type int8, int 16 ...
1160         if (piStart->getType() == piEnd->getType()  &&
1161                 (piStart->getType() == piStep->getType() ||
1162                  piStep->isDouble()))
1163         {
1164             // No need to kill piStart, ... because Implicit list ctor will incref them
1165             setResult(new ImplicitList(piStart, piStep, piEnd));
1166             return;
1167         }
1168     }
1169
1170     // Call Overload
1171     Callable::ReturnValue Ret;
1172     types::typed_list in;
1173     types::typed_list out;
1174
1175     piStart->IncreaseRef();
1176     piStep->IncreaseRef();
1177     piEnd->IncreaseRef();
1178
1179     in.push_back(piStart);
1180     if (e.hasExplicitStep())
1181     {
1182         // 1:2:4
1183         //call overload %typeStart_b_typeEnd
1184         in.push_back(piStep);
1185         in.push_back(piEnd);
1186         Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piStep->getShortTypeStr(), in, 1, out, this, true);
1187     }
1188     else
1189     {
1190         // 1:2
1191         //call overload %typeStart_b_typeStep
1192         in.push_back(piEnd);
1193         Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piEnd->getShortTypeStr(), in, 1, out, this, true);
1194     }
1195
1196     if (Ret != Callable::OK)
1197     {
1198         cleanInOut(in, out);
1199         throw ScilabError();
1200     }
1201
1202     setResult(out);
1203     cleanIn(in, out);
1204 }
1205
1206 template <class T>
1207 void RunVisitorT<T>::visitprivate(const OptimizedExp &e)
1208 {
1209 }
1210
1211 template <class T>
1212 void RunVisitorT<T>::visitprivate(const DAXPYExp &e)
1213 {
1214     InternalType* pIT = NULL;
1215     Double* ad = NULL;
1216     int ar = 0;
1217     int ac = 0;
1218
1219     Double* xd = NULL;
1220     int xr = 0;
1221     int xc = 0;
1222
1223     Double* yd = NULL;
1224     int yr = 0;
1225     int yc = 0;
1226
1227     //check types and dimensions
1228
1229     //y must be double
1230     const Exp &ye = e.getY();
1231     ye.accept(*this);
1232     pIT = getResult();
1233     if (pIT->isDouble())
1234     {
1235         yd = pIT->getAs<Double>();
1236         if (yd->getDims() == 2 && yd->isComplex() == false)
1237         {
1238             yr = yd->getRows();
1239             yc = yd->getCols();
1240         }
1241         else
1242         {
1243             yd->killMe();
1244             e.getOriginal()->accept(*this);
1245             return;
1246         }
1247     }
1248     else
1249     {
1250         pIT->killMe();
1251         e.getOriginal()->accept(*this);
1252         return;
1253     }
1254
1255     //x
1256     const Exp &xe = e.getX();
1257     xe.accept(*this);
1258     pIT = getResult();
1259
1260     if (pIT->isDouble())
1261     {
1262         xd = pIT->getAs<Double>();
1263         if (xd->isScalar() && xd->isComplex() == false)
1264         {
1265             // x become a
1266             ad = xd;
1267             ar = 1;
1268             ac = 1;
1269         }
1270         else if (xd->getDims() == 2 && xd->isComplex() == false)
1271         {
1272             xr = xd->getRows();
1273             xc = xd->getCols();
1274         }
1275         else
1276         {
1277             yd->killMe();
1278             xd->killMe();
1279             e.getOriginal()->accept(*this);
1280             return;
1281         }
1282     }
1283     else
1284     {
1285         pIT->killMe();
1286         yd->killMe();
1287         e.getOriginal()->accept(*this);
1288         return;
1289     }
1290
1291     const Exp &ae = e.getA();
1292     ae.accept(*this);
1293     pIT = getResult();
1294
1295     if (pIT->isDouble())
1296     {
1297         if (ad)
1298         {
1299             xd = pIT->getAs<Double>();
1300             //X is scalar it become A
1301             //now use A as X
1302             if (xd->getDims() == 2 && xd->isComplex() == false)
1303             {
1304                 xr = xd->getRows();
1305                 xc = xd->getCols();
1306             }
1307             else
1308             {
1309                 yd->killMe();
1310                 xd->killMe();
1311                 ad->killMe();
1312                 e.getOriginal()->accept(*this);
1313                 return;
1314             }
1315         }
1316         else
1317         {
1318             //a is a and it must be scalar
1319             ad = pIT->getAs<Double>();
1320             if (ad->isScalar() && ad->isComplex() == false)
1321             {
1322                 ar = 1;
1323                 ac = 1;
1324             }
1325             else
1326             {
1327                 yd->killMe();
1328                 xd->killMe();
1329                 ad->killMe();
1330                 e.getOriginal()->accept(*this);
1331                 return;
1332             }
1333         }
1334     }
1335     else
1336     {
1337         pIT->killMe();
1338         yd->killMe();
1339         xd->killMe();
1340         e.getOriginal()->accept(*this);
1341         return;
1342     }
1343
1344     if (ad && xd && yd)
1345     {
1346         if ( ac == 1 &&
1347                 ar == 1 &&
1348                 xr == yr &&
1349                 xc == yc)
1350         {
1351             //go !
1352             int one = 1;
1353             int size = xc * xr;
1354             Double* od = (Double*)yd->clone();
1355             C2F(daxpy)(&size, ad->get(), xd->get(), &one, od->get(), &one);
1356             setResult(od);
1357             yd->killMe();
1358             xd->killMe();
1359             ad->killMe();
1360             return;
1361         }
1362     }
1363
1364     if (yd)
1365     {
1366         yd->killMe();
1367     }
1368
1369     if (xd)
1370     {
1371         xd->killMe();
1372     }
1373
1374     if (ad)
1375     {
1376         ad->killMe();
1377     }
1378
1379     e.getOriginal()->accept(*this);
1380     return;
1381 }
1382
1383 } /* namespace ast */
1384
1385 #include "run_CallExp.hpp"
1386 #include "run_MatrixExp.hpp"
1387 #include "run_OpExp.hpp"
1388 #include "run_AssignExp.hpp"
1389
1390 template EXTERN_AST class ast::RunVisitorT<ast::ExecVisitor>;
1391 template EXTERN_AST class ast::RunVisitorT<ast::StepVisitor>;
1392 template EXTERN_AST class ast::RunVisitorT<ast::TimedVisitor>;