update mode management
[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 in debug compilation mode
14 //#define DEBUG_VLD
15 #if defined(DEBUG_VLD) && defined(_DEBUG)
16 #include <vld.h>
17 #endif
18
19 #include <string>
20
21 #include "execvisitor.hxx"
22 #include "stepvisitor.hxx"
23 #include "timedvisitor.hxx"
24 #include "shortcutvisitor.hxx"
25 #include "printvisitor.hxx"
26 //#include "AnalysisVisitor.hxx"
27 #include "debuggervisitor.hxx"
28 #include "debugmanager.hxx"
29
30 #include "visitor_common.hxx"
31
32 #include "context.hxx"
33 #include "generic_operations.hxx"
34 #include "types_or.hxx"
35 #include "types_and.hxx"
36 #include "localization.hxx"
37
38 #include "macrofile.hxx"
39 #include "macro.hxx"
40 #include "cell.hxx"
41 #include "filemanager_interface.h"
42
43 #include "runner.hxx"
44 #include "threadmanagement.hxx"
45
46 #include "coverage_instance.hxx"
47
48 extern "C"
49 {
50 #include "sciprint.h"
51 #include "os_string.h"
52 #include "elem_common.h"
53 #include "storeCommand.h"
54 #include "prompt.h"
55 #include "scilabRead.h"
56 }
57
58 namespace ast
59 {
60 template <class T>
61 void RunVisitorT<T>::visitprivate(const StringExp & e)
62 {
63     CoverageInstance::invokeAndStartChrono((void*)&e);
64     if (e.getConstant() == nullptr)
65     {
66         types::String *psz = new types::String(e.getValue().c_str());
67         (const_cast<StringExp *>(&e))->setConstant(psz);
68     }
69     setResult(e.getConstant());
70     CoverageInstance::stopChrono((void*)&e);
71 }
72
73 template <class T>
74 void RunVisitorT<T>::visitprivate(const DoubleExp & e)
75 {
76     CoverageInstance::invokeAndStartChrono((void*)&e);
77     if (e.getConstant() == nullptr)
78     {
79         types::Double *pdbl = new types::Double(e.getValue());
80         (const_cast<DoubleExp *>(&e))->setConstant(pdbl);
81     }
82     setResult(e.getConstant());
83     CoverageInstance::stopChrono((void*)&e);
84 }
85
86 template <class T>
87 void RunVisitorT<T>::visitprivate(const BoolExp & e)
88 {
89     CoverageInstance::invokeAndStartChrono((void*)&e);
90     if (e.getConstant() == nullptr)
91     {
92         types::Bool *pB = new types::Bool(e.getValue());
93         (const_cast<BoolExp *>(&e))->setConstant(pB);
94     }
95     setResult(e.getConstant());
96     CoverageInstance::stopChrono((void*)&e);
97 }
98
99 template <class T>
100 void RunVisitorT<T>::visitprivate(const NilExp & e)
101 {
102     CoverageInstance::invokeAndStartChrono((void*)&e);
103     setResult(new types::Void());
104     CoverageInstance::stopChrono((void*)&e);
105 }
106
107 template <class T>
108 void RunVisitorT<T>::visitprivate(const SimpleVar & e)
109 {
110     CoverageInstance::invokeAndStartChrono((void*)&e);
111     symbol::Context* ctx = symbol::Context::getInstance();
112     symbol::Variable* var = ((SimpleVar&)e).getStack();
113     types::InternalType *pI = ctx->get(var);
114     setResult(pI);
115     if (pI != nullptr)
116     {
117         if (e.isVerbose() && pI->isCallable() == false && ConfigVariable::isPrintOutput())
118         {
119             std::wostringstream ostr;
120             ostr << L" " << e.getSymbol().getName() << L"  = ";
121 #ifndef NDEBUG
122             ostr << L"(" << pI->getRef() << L")";
123 #endif
124             ostr << std::endl;
125             ostr << std::endl;
126             scilabWriteW(ostr.str().c_str());
127             std::wostringstream ostrName;
128             ostrName << e.getSymbol().getName();
129             VariableToString(pI, ostrName.str().c_str());
130         }
131
132         //check if var is recalled in current scope like
133         //function f()
134         //  a; //<=> a=a;
135         //  a(2) = 18;
136         //endfunction
137         if (e.getParent()->isSeqExp())
138         {
139             if (ctx->getScopeLevel() > 1 && var->empty() == false && var->top()->m_iLevel != ctx->getScopeLevel())
140             {
141                 //put var in current scope
142                 ctx->put(var, pI);
143             }
144         }
145     }
146     else
147     {
148         char pstError[bsiz];
149         wchar_t* pwstError;
150
151         char* strErr = wide_string_to_UTF8(e.getSymbol().getName().c_str());
152
153         os_sprintf(pstError, _("Undefined variable: %s\n"), strErr);
154         pwstError = to_wide_string(pstError);
155         FREE(strErr);
156         std::wstring wstError(pwstError);
157         FREE(pwstError);
158         CoverageInstance::stopChrono((void*)&e);
159         throw InternalError(wstError, 999, e.getLocation());
160         //Err, SimpleVar doesn't exist in Scilab scopes.
161     }
162     CoverageInstance::stopChrono((void*)&e);
163 }
164
165 template <class T>
166 void RunVisitorT<T>::visitprivate(const ColonVar & e)
167 {
168     CoverageInstance::invokeAndStartChrono((void*)&e);
169     types::Colon *pC = new types::Colon();
170     setResult(pC);
171     CoverageInstance::stopChrono((void*)&e);
172 }
173
174 template <class T>
175 void RunVisitorT<T>::visitprivate(const DollarVar & e)
176 {
177     CoverageInstance::invokeAndStartChrono((void*)&e);
178     setResult(types::Polynom::Dollar());
179     CoverageInstance::stopChrono((void*)&e);
180 }
181
182 template <class T>
183 void RunVisitorT<T>::visitprivate(const BreakExp & e)
184 {
185     CoverageInstance::invokeAndStartChrono((void*)&e);
186     const_cast<BreakExp*>(&e)->setBreak();
187     CoverageInstance::stopChrono((void*)&e);
188 }
189
190 template <class T>
191 void RunVisitorT<T>::visitprivate(const ContinueExp &e)
192 {
193     CoverageInstance::invokeAndStartChrono((void*)&e);
194     const_cast<ContinueExp*>(&e)->setContinue();
195     CoverageInstance::stopChrono((void*)&e);
196 }
197
198 template <class T>
199 void RunVisitorT<T>::visitprivate(const ArrayListExp & e)
200 {
201     CoverageInstance::invokeAndStartChrono((void*)&e);
202     exps_t::const_iterator it;
203     int iNbExpSize = this->getExpectedSize();
204     this->setExpectedSize(1);
205
206     types::typed_list lstIT;
207     for (it = e.getExps().begin(); it != e.getExps().end(); it++)
208     {
209         (*it)->accept(*this);
210         for (int j = 0; j < getResultSize(); j++)
211         {
212             lstIT.push_back(getResult(j));
213         }
214     }
215
216     setResult(lstIT);
217
218     this->setExpectedSize(iNbExpSize);
219     CoverageInstance::stopChrono((void*)&e);
220 }
221
222 template <class T>
223 void RunVisitorT<T>::visitprivate(const VarDec & e)
224 {
225     CoverageInstance::invokeAndStartChrono((void*)&e);
226     try
227     {
228         /*getting what to assign*/
229         e.getInit().accept(*this);
230         getResult()->IncreaseRef();
231     }
232     catch (const InternalError& error)
233     {
234         CoverageInstance::stopChrono((void*)&e);
235         throw error;
236     }
237     CoverageInstance::stopChrono((void*)&e);
238 }
239
240 template <class T>
241 void RunVisitorT<T>::visitprivate(const CellExp & e)
242 {
243     CoverageInstance::invokeAndStartChrono((void*)&e);
244
245     exps_t::const_iterator row;
246     exps_t::const_iterator col;
247     int iColMax = 0;
248
249     exps_t lines = e.getLines();
250     //check dimmension
251     for (row = lines.begin(); row != lines.end(); ++row)
252     {
253         exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
254         if (iColMax == 0)
255         {
256             iColMax = static_cast<int>(cols.size());
257         }
258
259         if (iColMax != static_cast<int>(cols.size()))
260         {
261             std::wostringstream os;
262             os << _W("inconsistent row/column dimensions\n");
263             //os << ((Location)(*row)->getLocation()).getLocationString() << std::endl;
264             CoverageInstance::stopChrono((void*)&e);
265             throw InternalError(os.str(), 999, (*row)->getLocation());
266         }
267     }
268
269     //alloc result cell
270     types::Cell *pC = new types::Cell(static_cast<int>(lines.size()), iColMax);
271
272     int i = 0;
273     int j = 0;
274
275     //insert items in cell
276     for (i = 0, row = lines.begin(); row != lines.end(); ++row, ++i)
277     {
278         exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
279         for (j = 0, col = cols.begin(); col != cols.end(); ++col, ++j)
280         {
281             try
282             {
283                 (*col)->accept(*this);
284             }
285             catch (ScilabException &)
286             {
287                 CoverageInstance::stopChrono((void*)&e);
288                 throw;
289             }
290             types::InternalType *pIT = getResult();
291             if (pIT->isImplicitList())
292             {
293                 types::InternalType * _pIT = pIT->getAs<types::ImplicitList>()->extractFullMatrix();
294                 pC->set(i, j, _pIT);
295                 _pIT->killMe();
296             }
297             else
298             {
299                 pC->set(i, j, pIT);
300             }
301             clearResult();
302         }
303     }
304
305     //return new cell
306     setResult(pC);
307
308     CoverageInstance::stopChrono((void*)&e);
309 }
310
311 template <class T>
312 void RunVisitorT<T>::visitprivate(const FieldExp &e)
313 {
314     /*
315       a.b
316       */
317
318     CoverageInstance::invokeAndStartChrono((void*)&e);
319
320     if (!e.getTail()->isSimpleVar())
321     {
322         wchar_t szError[bsiz];
323         os_swprintf(szError, bsiz, _W("/!\\ Unmanaged FieldExp.\n").c_str());
324         CoverageInstance::stopChrono((void*)&e);
325         throw InternalError(szError, 999, e.getLocation());
326     }
327
328     try
329     {
330         e.getHead()->accept(*this);
331     }
332     catch (const InternalError& error)
333     {
334         CoverageInstance::stopChrono((void*)&e);
335         throw error;
336     }
337
338     if (getResult() == NULL)
339     {
340         wchar_t szError[bsiz];
341         os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
342         CoverageInstance::stopChrono((void*)&e);
343         throw InternalError(szError, 999, e.getLocation());
344     }
345
346     // TODO: handle case where getSize() > 1
347     // l=list(struct("toto","coucou"),struct("toto","hello"),1,2);[a,b]=l(1:2).toto
348     //
349     if (getResultSize() > 1)
350     {
351         clearResult();
352         wchar_t szError[bsiz];
353         os_swprintf(szError, bsiz, _W("Not yet implemented in Scilab.\n").c_str());
354         CoverageInstance::stopChrono((void*)&e);
355         throw InternalError(szError, 999, e.getLocation());
356     }
357
358     SimpleVar * psvRightMember = static_cast<SimpleVar *>(const_cast<Exp *>(e.getTail()));
359     std::wstring wstField = psvRightMember->getSymbol().getName();
360     types::InternalType * pValue = getResult();
361     types::InternalType * pReturn = NULL;
362     bool ok = false;
363
364     try
365     {
366         if (pValue->isGenericType() || pValue->isUserType())
367         {
368             ok = pValue->getAs<types::GenericType>()->extract(wstField, pReturn);
369         }
370     }
371     catch (std::wstring & err)
372     {
373         CoverageInstance::stopChrono((void*)&e);
374         throw InternalError(err.c_str(), 999, e.getTail()->getLocation());
375     }
376
377     if (ok)
378     {
379         if (pReturn == NULL)
380         {
381             std::wostringstream os;
382             os << _W("Invalid index.\n");
383             CoverageInstance::stopChrono((void*)&e);
384             throw InternalError(os.str(), 999, e.getLocation());
385         }
386
387         setResult(pReturn);
388         if (pValue->isDeletable())
389         {
390             if (pValue->isContainer())
391             {
392                 // prevent delete of pReturn in case where
393                 // extract not return a clone
394                 pReturn->IncreaseRef();
395                 pValue->killMe();
396                 pReturn->DecreaseRef();
397             }
398             else
399             {
400                 pValue->killMe();
401             }
402         }
403     }
404     else if (pValue->isFieldExtractionOverloadable())
405     {
406         types::typed_list in;
407         types::typed_list out;
408
409         types::String* pS = new types::String(wstField.c_str());
410
411         //TODO: in the case where overload is a macro there is no need to incref in
412         // because args will be put in context, removed and killed if required.
413         // But if the overload is a function... it is another story...
414
415         pS->IncreaseRef();
416         pValue->IncreaseRef();
417
418         in.push_back(pS);
419         in.push_back(pValue);
420         types::Callable::ReturnValue Ret = types::Callable::Error;
421         std::wstring stType = pValue->getShortTypeStr();
422
423         try
424         {
425             Ret = Overload::call(L"%" + stType + L"_e", in, 1, out, this);
426         }
427         catch (const InternalError& ie)
428         {
429             try
430             {
431                 //to compatibility with scilab 5 code.
432                 //tlist/mlist name are truncated to 8 first character
433                 if (stType.size() > 8)
434                 {
435                     Ret = Overload::call(L"%" + stType.substr(0, 8) + L"_e", in, 1, out, this);
436                 }
437                 else
438                 {
439                     CoverageInstance::stopChrono((void*)&e);
440                     throw ie;
441                 }
442             }
443             catch (const InternalError& ie)
444             {
445                 // TList or Mlist
446                 if (pValue->isList())
447                 {
448                     Ret = Overload::call(L"%l_e", in, 1, out, this);
449                 }
450                 else
451                 {
452                     CoverageInstance::stopChrono((void*)&e);
453                     throw ie;
454                 }
455             }
456         }
457
458         if (Ret != types::Callable::OK)
459         {
460             cleanInOut(in, out);
461             setResult(NULL);
462             CoverageInstance::stopChrono((void*)&e);
463             throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
464         }
465
466         setResult(out);
467         cleanIn(in, out);
468     }
469     else
470     {
471         pValue->killMe();
472         wchar_t szError[bsiz];
473         os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
474         CoverageInstance::stopChrono((void*)&e);
475         throw InternalError(szError, 999, e.getLocation());
476     }
477
478     CoverageInstance::stopChrono((void*)&e);
479 }
480
481 template <class T>
482 void RunVisitorT<T>::visitprivate(const IfExp  &e)
483 {
484     CoverageInstance::invokeAndStartChrono((void*)&e);
485
486     //Create local exec visitor
487     ShortCutVisitor SCTest;
488     bool bTestStatus = false;
489
490     //condition
491     try
492     {
493         e.getTest().accept(SCTest);
494         e.getTest().accept(*this);
495     }
496     catch (ScilabException &)
497     {
498         CoverageInstance::stopChrono((void*)&e);
499         throw;
500     }
501
502     bTestStatus = getResult()->isTrue();
503     clearResult();
504     try
505     {
506         if (bTestStatus == true)
507         {
508             e.getThen().accept(*this);
509         }
510         else if (e.hasElse())
511         {
512             const ast::Exp & _else = e.getElse();
513             if (_else.isCommentExp())
514             {
515                 CoverageInstance::invoke(_else);
516             }
517             else
518             {
519                 e.getElse().accept(*this);
520             }
521         }
522     }
523     catch (ScilabException &)
524     {
525         CoverageInstance::stopChrono((void*)&e);
526         throw;
527     }
528
529     if (e.isBreakable()
530             && ((&e.getElse())->isBreak()
531                 || (&e.getThen())->isBreak()))
532     {
533         const_cast<IfExp*>(&e)->setBreak();
534         const_cast<Exp*>(&e.getElse())->resetBreak();
535         const_cast<Exp*>(&e.getThen())->resetBreak();
536     }
537
538     if (e.isContinuable()
539             && ((&e.getElse())->isContinue()
540                 || (&e.getThen())->isContinue()))
541     {
542         const_cast<IfExp*>(&e)->setContinue();
543         const_cast<Exp*>(&e.getElse())->resetContinue();
544         const_cast<Exp*>(&e.getThen())->resetContinue();
545     }
546
547     if (e.isReturnable()
548             && ((&e.getElse())->isReturn()
549                 || (&e.getThen())->isReturn()))
550     {
551         const_cast<IfExp*>(&e)->setReturn();
552         const_cast<Exp*>(&e.getElse())->resetReturn();
553         const_cast<Exp*>(&e.getThen())->resetReturn();
554     }
555
556     CoverageInstance::stopChrono((void*)&e);
557 }
558
559 template <class T>
560 void RunVisitorT<T>::visitprivate(const WhileExp  &e)
561 {
562     CoverageInstance::invokeAndStartChrono((void*)&e);
563
564     //Create local exec visitor
565     ShortCutVisitor SCTest;
566
567     try
568     {
569         //manage & and | like && and ||
570         e.getTest().accept(SCTest);
571         //condition
572         e.getTest().accept(*this);
573     }
574     catch (ScilabException &)
575     {
576         CoverageInstance::stopChrono((void*)&e);
577         throw;
578     }
579
580     types::InternalType* pIT = getResult();
581
582     while (pIT->isTrue())
583     {
584         pIT->killMe();
585         try
586         {
587             e.getBody().accept(*this);
588         }
589         catch (ScilabException &)
590         {
591             CoverageInstance::stopChrono((void*)&e);
592             throw;
593         }
594
595         //clear old result value before evaluate new one
596         if (getResult() != NULL)
597         {
598             getResult()->killMe();
599         }
600
601         if (e.getBody().isBreak())
602         {
603             const_cast<Exp*>(&(e.getBody()))->resetBreak();
604             break;
605         }
606
607         if (e.getBody().isReturn())
608         {
609             const_cast<WhileExp*>(&e)->setReturn();
610             const_cast<Exp*>(&(e.getBody()))->resetReturn();
611             break;
612         }
613
614         if (e.getBody().isContinue())
615         {
616             const_cast<Exp*>(&(e.getBody()))->resetContinue();
617         }
618
619         try
620         {
621             e.getTest().accept(*this);
622         }
623         catch (ScilabException &)
624         {
625             CoverageInstance::stopChrono((void*)&e);
626             throw;
627         }
628         pIT = getResult();
629     }
630
631     //pIT->killMe();
632     //clear result of condition or result of body
633     clearResult();
634     CoverageInstance::stopChrono((void*)&e);
635 }
636
637 template <class T>
638 void RunVisitorT<T>::visitprivate(const ForExp  &e)
639 {
640     CoverageInstance::invokeAndStartChrono((void*)&e);
641     symbol::Context* ctx = symbol::Context::getInstance();
642     //vardec visit increase its result reference
643     try
644     {
645         e.getVardec().accept(*this);
646     }
647     catch (ScilabException &)
648     {
649         CoverageInstance::stopChrono((void*)&e);
650         throw;
651     }
652     types::InternalType* pIT = getResult();
653
654     if (pIT->isImplicitList())
655     {
656         //get IL
657         types::ImplicitList* pVar = pIT->getAs<types::ImplicitList>();
658         //get IL initial Type
659         types::InternalType * pIL = pVar->getInitalType();
660         //std::cout << "for IL: " << pIL << std::endl;
661         //std::cout << "  for IV: " << pIT << std::endl;
662         //get index stack
663         symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
664
665         if (ctx->isprotected(var))
666         {
667             std::wostringstream os;
668             os << _W("Redefining permanent variable.\n");
669             CoverageInstance::stopChrono((void*)&e);
670             throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
671         }
672
673         ctx->put(var, pIL);
674         //use ref count to lock var against clear and detect any changes
675         pIL->IncreaseRef();
676
677         int size = static_cast<int>(pVar->getSize());
678         for (int i = 0; i < size; ++i)
679         {
680             //check if loop index has changed, deleted, copy ...
681             if (pIL->getRef() != 2)
682             {
683                 switch (pIL->getRef())
684                 {
685                     case 1:
686                         //someone clear me
687                         ctx->put(var, pIL);
688                         break;
689                     default:
690                         //someone assign me to another var
691                         //a = i;
692                         //unlock me
693                         pIL->DecreaseRef();
694
695                         //no need to destroy, it already assign to another var
696                         //pIL->killMe();
697
698                         //create a new me
699                         pIL = pVar->getInitalType();
700                         //lock loop index
701                         pIL->IncreaseRef();
702                         //update me ( must decrease ref of a )
703                         if (ctx->isprotected(var))
704                         {
705                             std::wostringstream os;
706                             os << _W("Redefining permanent variable.\n");
707                             CoverageInstance::stopChrono((void*)&e);
708                             throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
709                         }
710
711                         ctx->put(var, pIL);
712                         break;
713                 }
714             }
715
716             pVar->extractValue(i, pIL);
717
718             try
719             {
720                 e.getBody().accept(*this);
721             }
722             catch (const InternalError& ie)
723             {
724                 //unlock loop index and implicit list
725                 pIL->DecreaseRef();
726                 pIL->killMe();
727                 pIT->DecreaseRef();
728                 pIT->killMe();
729
730                 setResult(NULL);
731                 CoverageInstance::stopChrono((void*)&e);
732                 throw ie;
733             }
734
735             if (e.getBody().isBreak())
736             {
737                 const_cast<Exp&>(e.getBody()).resetBreak();
738                 break;
739             }
740
741             if (e.getBody().isContinue())
742             {
743                 const_cast<Exp&>(e.getBody()).resetContinue();
744                 continue;
745             }
746
747             if (e.getBody().isReturn())
748             {
749                 const_cast<ForExp&>(e).setReturn();
750                 const_cast<Exp&>(e.getBody()).resetReturn();
751                 break;
752             }
753         }
754
755         //unlock loop index
756         pIL->DecreaseRef();
757         pIL->killMe();
758     }
759     else if (pIT->isList())
760     {
761         types::List* pL = pIT->getAs<types::List>();
762         const int size = pL->getSize();
763         symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
764         for (int i = 0; i < size; ++i)
765         {
766             types::InternalType* pNew = pL->get(i);
767
768             if (ctx->isprotected(var))
769             {
770                 std::wostringstream os;
771                 os << _W("Redefining permanent variable.\n");
772                 CoverageInstance::stopChrono((void*)&e);
773                 throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
774             }
775             ctx->put(var, pNew);
776
777             try
778             {
779                 e.getBody().accept(*this);
780             }
781             catch (const InternalError& ie)
782             {
783                 //implicit list
784                 pIT->DecreaseRef();
785                 pIT->killMe();
786                 setResult(NULL);
787                 CoverageInstance::stopChrono((void*)&e);
788                 throw ie;
789             }
790
791             if (e.getBody().isBreak())
792             {
793                 const_cast<Exp*>(&(e.getBody()))->resetBreak();
794                 break;
795             }
796
797             if (e.getBody().isContinue())
798             {
799                 const_cast<Exp*>(&(e.getBody()))->resetContinue();
800                 continue;
801             }
802
803             if (e.getBody().isReturn())
804             {
805                 const_cast<ForExp*>(&e)->setReturn();
806                 const_cast<Exp&>(e.getBody()).resetReturn();
807                 break;
808             }
809         }
810     }
811     else if (pIT->isGenericType())
812     {
813         //Matrix i = [1,3,2,6] or other type
814         types::GenericType* pVar = pIT->getAs<types::GenericType>();
815         if (pVar->getDims() > 2)
816         {
817             pIT->DecreaseRef();
818             pIT->killMe();
819             CoverageInstance::stopChrono((void*)&e);
820             throw InternalError(_W("for expression can only manage 1 or 2 dimensions variables\n"), 999, e.getVardec().getLocation());
821         }
822
823         symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
824         for (int i = 0; i < pVar->getCols(); i++)
825         {
826             types::GenericType* pNew = pVar->getColumnValues(i);
827             if (pNew == NULL)
828             {
829                 pIT->DecreaseRef();
830                 pIT->killMe();
831                 CoverageInstance::stopChrono((void*)&e);
832                 throw InternalError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
833             }
834
835             if (ctx->isprotected(var))
836             {
837                 std::wostringstream os;
838                 os << _W("Redefining permanent variable.\n");
839                 CoverageInstance::stopChrono((void*)&e);
840                 throw InternalError(os.str(), 999, e.getVardec().getLocation());
841             }
842             ctx->put(var, pNew);
843
844             try
845             {
846                 e.getBody().accept(*this);
847             }
848             catch (const InternalError& ie)
849             {
850                 //implicit list
851                 pIT->DecreaseRef();
852                 pIT->killMe();
853                 setResult(NULL);
854                 CoverageInstance::stopChrono((void*)&e);
855                 throw ie;
856             }
857
858             if (e.getBody().isBreak())
859             {
860                 const_cast<Exp*>(&(e.getBody()))->resetBreak();
861                 break;
862             }
863
864             if (e.getBody().isContinue())
865             {
866                 const_cast<Exp*>(&(e.getBody()))->resetContinue();
867                 continue;
868             }
869
870             if (e.getBody().isReturn())
871             {
872                 const_cast<ForExp*>(&e)->setReturn();
873                 const_cast<Exp&>(e.getBody()).resetReturn();
874                 break;
875             }
876         }
877     }
878     else
879     {
880         pIT->DecreaseRef();
881         pIT->killMe();
882         CoverageInstance::stopChrono((void*)&e);
883         throw InternalError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
884     }
885
886     pIT->DecreaseRef();
887     pIT->killMe();
888
889     setResult(NULL);
890     CoverageInstance::stopChrono((void*)&e);
891 }
892
893 template <class T>
894 void RunVisitorT<T>::visitprivate(const ReturnExp &e)
895 {
896     CoverageInstance::invokeAndStartChrono((void*)&e);
897     if (e.isGlobal())
898     {
899         if (ConfigVariable::getPauseLevel() != 0 && symbol::Context::getInstance()->getScopeLevel() == ConfigVariable::getActivePauseLevel())
900         {
901             if (ConfigVariable::getEnableDebug() == true)
902             {
903                 sciprint(_("%s: function is disabled in debug mode.\n"), "resume");
904                 CoverageInstance::stopChrono((void*)&e);
905                 return;
906             }
907
908             //return or resume
909             ConfigVariable::DecreasePauseLevel();
910             CoverageInstance::stopChrono((void*)&e);
911             return;
912         }
913         else
914         {
915             const_cast<ReturnExp*>(&e)->setReturn();
916         }
917     }
918     else
919     {
920         //return(x)
921
922         if (e.getParent() == nullptr || e.getParent()->isAssignExp() == false)
923         {
924             CoverageInstance::stopChrono((void*)&e);
925             throw InternalError(_W("With input arguments, return / resume expects output arguments.\n"), 999, e.getLocation());
926         }
927         //in case of CallExp, we can return only one values
928         int iSaveExpectedSize = getExpectedSize();
929         setExpectedSize(1);
930         try
931         {
932             e.getExp().accept(*this);
933         }
934         catch (ScilabException &)
935         {
936             CoverageInstance::stopChrono((void*)&e);
937             throw;
938         }
939         setExpectedSize(iSaveExpectedSize);
940         const_cast<ReturnExp*>(&e)->setReturn();
941     }
942
943     CoverageInstance::stopChrono((void*)&e);
944 }
945
946 template <class T>
947 void RunVisitorT<T>::visitprivate(const IntSelectExp &e)
948 {
949     CoverageInstance::invokeAndStartChrono((void*)&e);
950     bool found = false;
951     //e.getSelect()->accept(*this);
952     //InternalType* pIT = getResult();
953     //setResult(nullptr);
954     //if (pIT && pIT->isDouble())
955     //{
956     //    Double * pDbl = static_cast<Double *>(pIT);
957     //    if (!pDbl->isComplex() && pDbl->getSize() == 1)
958     //    {
959     //        int64_t val;
960     //        if (analysis::tools::asInteger<int64_t>(pDbl->get(0), val))
961     //        {
962     //            Exp * exp = e.getExp(val);
963     //            found = true;
964     //            if (exp)
965     //            {
966     //                Exp * body = exp->isCaseExp() ? exp->getAs<CaseExp>()->getBody() : exp;
967     //                if (e.isBreakable())
968     //                {
969     //                    const_cast<IntSelectExp*>(&e)->resetBreak();
970     //                    body->setBreakable();
971     //                }
972
973     //                if (e.isContinuable())
974     //                {
975     //                    const_cast<IntSelectExp*>(&e)->resetContinue();
976     //                    body->setContinuable();
977     //                }
978
979     //                if (e.isReturnable())
980     //                {
981     //                    const_cast<IntSelectExp*>(&e)->resetReturn();
982     //                    body->setReturnable();
983     //                }
984
985     //                try
986     //                {
987     //                    //the good one
988     //                    body->accept(*this);
989     //                }
990     //                catch (const InternalError& ie)
991     //                {
992     //                    pIT->killMe();
993     //                    throw ie;
994     //                }
995
996     //                if (e.isBreakable() && body->isBreak())
997     //                {
998     //                    const_cast<IntSelectExp*>(&e)->setBreak();
999     //                    body->resetBreak();
1000     //                }
1001
1002     //                if (e.isContinuable() && body->isContinue())
1003     //                {
1004     //                    const_cast<IntSelectExp*>(&e)->setContinue();
1005     //                    body->resetContinue();
1006     //                }
1007
1008     //                if (e.isReturnable() && body->isReturn())
1009     //                {
1010     //                    const_cast<IntSelectExp*>(&e)->setReturn();
1011     //                    body->resetReturn();
1012     //                }
1013     //            }
1014     //        }
1015     //    }
1016     //}
1017
1018     if (!found)
1019     {
1020         try
1021         {
1022             e.getOriginal()->accept(*this);
1023         }
1024         catch (ScilabException &)
1025         {
1026             CoverageInstance::stopChrono((void*)&e);
1027             throw;
1028         }
1029     }
1030     CoverageInstance::stopChrono((void*)&e);
1031 }
1032
1033 template <class T>
1034 void RunVisitorT<T>::visitprivate(const StringSelectExp &e)
1035 {
1036     CoverageInstance::invokeAndStartChrono((void*)&e);
1037     try
1038     {
1039         e.getSelect()->accept(*this);
1040     }
1041     catch (ScilabException &)
1042     {
1043         CoverageInstance::stopChrono((void*)&e);
1044         throw;
1045     }
1046     types::InternalType* pIT = getResult();
1047     setResult(nullptr);
1048     bool found = false;
1049     if (pIT && pIT->isString())
1050     {
1051         types::String * pStr = static_cast<types::String *>(pIT);
1052         if (pStr->getSize() == 1)
1053         {
1054             if (wchar_t * s = pStr->get(0))
1055             {
1056                 const std::wstring ws(s);
1057                 Exp * exp = e.getExp(ws);
1058                 found = true;
1059                 if (exp)
1060                 {
1061                     Exp * body = exp->isCaseExp() ? exp->getAs<CaseExp>()->getBody() : exp;
1062                     if (e.isBreakable())
1063                     {
1064                         const_cast<StringSelectExp*>(&e)->resetBreak();
1065                         body->setBreakable();
1066                     }
1067
1068                     if (e.isContinuable())
1069                     {
1070                         const_cast<StringSelectExp*>(&e)->resetContinue();
1071                         body->setContinuable();
1072                     }
1073
1074                     if (e.isReturnable())
1075                     {
1076                         const_cast<StringSelectExp*>(&e)->resetReturn();
1077                         body->setReturnable();
1078                     }
1079
1080                     try
1081                     {
1082                         //the good one
1083                         body->accept(*this);
1084                     }
1085                     catch (const InternalError& ie)
1086                     {
1087                         pIT->killMe();
1088                         CoverageInstance::stopChrono((void*)&e);
1089                         throw ie;
1090                     }
1091
1092                     if (e.isBreakable() && body->isBreak())
1093                     {
1094                         const_cast<StringSelectExp*>(&e)->setBreak();
1095                         body->resetBreak();
1096                     }
1097
1098                     if (e.isContinuable() && body->isContinue())
1099                     {
1100                         const_cast<StringSelectExp*>(&e)->setContinue();
1101                         body->resetContinue();
1102                     }
1103
1104                     if (e.isReturnable() && body->isReturn())
1105                     {
1106                         const_cast<StringSelectExp*>(&e)->setReturn();
1107                         body->resetReturn();
1108                     }
1109                 }
1110             }
1111         }
1112     }
1113
1114     if (!found)
1115     {
1116         try
1117         {
1118             e.getOriginal()->accept(*this);
1119         }
1120         catch (ScilabException &)
1121         {
1122             CoverageInstance::stopChrono((void*)&e);
1123             throw;
1124         }
1125     }
1126     CoverageInstance::stopChrono((void*)&e);
1127 }
1128
1129 template <class T>
1130 void RunVisitorT<T>::visitprivate(const SelectExp &e)
1131 {
1132     // FIXME : exec select ... case ... else ... end
1133     CoverageInstance::invokeAndStartChrono((void*)&e);
1134     try
1135     {
1136         e.getSelect()->accept(*this);
1137     }
1138     catch (ScilabException &)
1139     {
1140         CoverageInstance::stopChrono((void*)&e);
1141         throw;
1142     }
1143
1144     bool bCase = false;
1145
1146     types::InternalType* pIT = getResult();
1147     setResult(NULL);
1148     if (pIT)
1149     {
1150         // protect pIT to avoid double free when
1151         // the variable in select is override in the case
1152         pIT->IncreaseRef();
1153
1154         //find good case
1155         exps_t cases = e.getCases();
1156         for (auto exp : cases)
1157         {
1158             CaseExp * pCase = exp->getAs<CaseExp>();
1159             try
1160             {
1161                 pCase->getTest()->accept(*this);
1162             }
1163             catch (ScilabException &)
1164             {
1165                 CoverageInstance::stopChrono((void*)&e);
1166                 throw;
1167             }
1168             types::InternalType *pITCase = getResult();
1169             setResult(NULL);
1170             if (pITCase)
1171             {
1172                 if (pITCase->isContainer()) //WARNING ONLY FOR CELL
1173                 {
1174                     //check each item
1175                 }
1176                 else if (*pITCase == *pIT)
1177                 {
1178                     try
1179                     {
1180                         //the good one
1181                         pCase->getBody()->accept(*this);
1182                     }
1183                     catch (const InternalError& ie)
1184                     {
1185                         pIT->DecreaseRef();
1186                         pIT->killMe();
1187                         CoverageInstance::stopChrono((void*)&e);
1188                         throw ie;
1189                     }
1190
1191                     if (e.isBreakable() && pCase->getBody()->isBreak())
1192                     {
1193                         const_cast<SelectExp*>(&e)->setBreak();
1194                         pCase->getBody()->resetBreak();
1195                     }
1196
1197                     if (e.isContinuable() && pCase->getBody()->isContinue())
1198                     {
1199                         const_cast<SelectExp*>(&e)->setContinue();
1200                         pCase->getBody()->resetContinue();
1201                     }
1202
1203                     if (e.isReturnable() && pCase->getBody()->isReturn())
1204                     {
1205                         const_cast<SelectExp*>(&e)->setReturn();
1206                         pCase->getBody()->resetReturn();
1207                     }
1208
1209                     pITCase->killMe();
1210                     bCase = true;
1211                     break;
1212                 }
1213
1214                 pITCase->killMe();
1215             }
1216         }
1217     }
1218
1219     if (bCase == false && e.getDefaultCase() != NULL)
1220     {
1221         try
1222         {
1223             //default case
1224             e.getDefaultCase()->accept(*this);
1225         }
1226         catch (const InternalError& ie)
1227         {
1228             if (pIT)
1229             {
1230                 pIT->DecreaseRef();
1231                 pIT->killMe();
1232             }
1233             CoverageInstance::stopChrono((void*)&e);
1234             throw ie;
1235         }
1236
1237         if (e.isBreakable() && e.getDefaultCase()->isBreak())
1238         {
1239             const_cast<SelectExp*>(&e)->setBreak();
1240             e.getDefaultCase()->resetBreak();
1241         }
1242
1243         if (e.isContinuable() && e.getDefaultCase()->isContinue())
1244         {
1245             const_cast<SelectExp*>(&e)->setContinue();
1246             e.getDefaultCase()->resetContinue();
1247         }
1248
1249         if (e.isReturnable() && e.getDefaultCase()->isReturn())
1250         {
1251             const_cast<SelectExp*>(&e)->setReturn();
1252             e.getDefaultCase()->resetReturn();
1253         }
1254     }
1255
1256     clearResult();
1257
1258     if (pIT)
1259     {
1260         pIT->DecreaseRef();
1261         pIT->killMe();
1262     }
1263     CoverageInstance::stopChrono((void*)&e);
1264 }
1265
1266 template <class T>
1267 void RunVisitorT<T>::visitprivate(const NotExp &e)
1268 {
1269     CoverageInstance::invokeAndStartChrono((void*)&e);
1270     /*
1271       @ or ~ !
1272       */
1273     try
1274     {
1275         e.getExp().accept(*this);
1276     }
1277     catch (ScilabException &)
1278     {
1279         CoverageInstance::stopChrono((void*)&e);
1280         throw;
1281     }
1282
1283     types::InternalType * pValue = getResult();
1284     types::InternalType * pReturn = NULL;
1285     if (pValue->neg(pReturn))
1286     {
1287         if (pValue != pReturn)
1288         {
1289             pValue->killMe();
1290         }
1291
1292         setResult(pReturn);
1293     }
1294     else
1295     {
1296         // neg returned false so the negation is not possible so we call the overload (%foo_5)
1297         types::typed_list in;
1298         types::typed_list out;
1299
1300         pValue->IncreaseRef();
1301         in.push_back(pValue);
1302
1303         types::Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_5", in, 1, out, this);
1304
1305         if (Ret != types::Callable::OK)
1306         {
1307             cleanInOut(in, out);
1308             CoverageInstance::stopChrono((void*)&e);
1309             throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1310         }
1311
1312         setResult(out);
1313         cleanIn(in, out);
1314     }
1315     CoverageInstance::stopChrono((void*)&e);
1316 }
1317
1318 template <class T>
1319 void RunVisitorT<T>::visitprivate(const TransposeExp &e)
1320 {
1321     CoverageInstance::invokeAndStartChrono((void*)&e);
1322     try
1323     {
1324         e.getExp().accept(*this);
1325     }
1326     catch (ScilabException &)
1327     {
1328         CoverageInstance::stopChrono((void*)&e);
1329         throw;
1330     }
1331
1332     if (getResultSize() != 1)
1333     {
1334         clearResult();
1335         wchar_t szError[bsiz];
1336         os_swprintf(szError, bsiz, _W("%ls: Can not transpose multiple elements.\n").c_str(), L"Transpose");
1337         CoverageInstance::stopChrono((void*)&e);
1338         throw InternalError(szError, 999, e.getLocation());
1339     }
1340
1341     types::InternalType * pValue = getResult();
1342     types::InternalType * pReturn = NULL;
1343     const bool bConjug = e.getConjugate() == TransposeExp::_Conjugate_;
1344
1345     if ((bConjug && pValue->adjoint(pReturn)) || (!bConjug && pValue->transpose(pReturn)))
1346     {
1347         if (pValue != pReturn)
1348         {
1349             pValue->killMe();
1350         }
1351
1352         setResult(pReturn);
1353         CoverageInstance::stopChrono((void*)&e);
1354
1355         return;
1356     }
1357     else
1358     {
1359         // transpose returned false so the negation is not possible so we call the overload (%foo_t or %foo_0)
1360         types::typed_list in;
1361         types::typed_list out;
1362
1363         pValue->IncreaseRef();
1364         in.push_back(pValue);
1365
1366         types::Callable::ReturnValue Ret;
1367         if (bConjug)
1368         {
1369             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_t", in, 1, out, this);
1370         }
1371         else
1372         {
1373             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_0", in, 1, out, this);
1374         }
1375
1376         if (Ret != types::Callable::OK)
1377         {
1378             cleanInOut(in, out);
1379             CoverageInstance::stopChrono((void*)&e);
1380             throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1381         }
1382
1383         setResult(out);
1384         cleanIn(in, out);
1385     }
1386
1387     CoverageInstance::stopChrono((void*)&e);
1388 }
1389
1390 template <class T>
1391 void RunVisitorT<T>::visitprivate(const FunctionDec & e)
1392 {
1393     CoverageInstance::invokeAndStartChrono((void*)&e);
1394     symbol::Context* ctx = symbol::Context::getInstance();
1395     /*
1396       function foo
1397       endfunction
1398       */
1399
1400     // funcprot(0) : do nothing
1401     // funcprot(1) && warning(on) : warning
1402     //get input parameters list
1403     std::list<symbol::Variable*> *pVarList = new std::list<symbol::Variable*>();
1404     const exps_t & vars = e.getArgs().getVars();
1405     for (const auto var : vars)
1406     {
1407         pVarList->push_back(var->getAs<SimpleVar>()->getStack());
1408     }
1409
1410     //get output parameters list
1411     std::list<symbol::Variable*> *pRetList = new std::list<symbol::Variable*>();
1412     const exps_t & rets = e.getReturns().getVars();
1413     for (const auto ret : rets)
1414     {
1415         pRetList->push_back(ret->getAs<SimpleVar>()->getStack());
1416     }
1417
1418     types::Macro *pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList,
1419                                             const_cast<SeqExp&>(static_cast<const SeqExp&>(e.getBody())), L"script");
1420     pMacro->setLines(e.getLocation().first_line, e.getLocation().last_line);
1421
1422     if (ctx->isprotected(symbol::Symbol(pMacro->getName())))
1423     {
1424         delete pMacro;
1425         std::wostringstream os;
1426         os << _W("Redefining permanent variable.\n");
1427         CoverageInstance::stopChrono((void*)&e);
1428         throw InternalError(os.str(), 999, e.getLocation());
1429     }
1430
1431     if (ctx->addMacro(pMacro) == false)
1432     {
1433         char pstError[1024];
1434         char* pstFuncName = wide_string_to_UTF8(e.getSymbol().getName().c_str());
1435         os_sprintf(pstError, _("It is not possible to redefine the %s primitive this way (see clearfun).\n"), pstFuncName);
1436         wchar_t* pwstError = to_wide_string(pstError);
1437         std::wstring wstError(pwstError);
1438         FREE(pstFuncName);
1439         FREE(pwstError);
1440         pMacro->killMe();
1441         CoverageInstance::stopChrono((void*)&e);
1442         throw InternalError(wstError, 999, e.getLocation());
1443     }
1444
1445     CoverageInstance::stopChrono((void*)&e);
1446 }
1447
1448 template <class T>
1449 void RunVisitorT<T>::visitprivate(const ListExp &e)
1450 {
1451     CoverageInstance::invokeAndStartChrono((void*)&e);
1452     try
1453     {
1454         e.getStart().accept(*this);
1455     }
1456     catch (ScilabException &)
1457     {
1458         CoverageInstance::stopChrono((void*)&e);
1459         throw;
1460     }
1461     types::GenericType* pITStart = static_cast<types::GenericType*>(getResult());
1462     if ((pITStart->getSize() != 1 || (pITStart->isDouble() && pITStart->getAs<types::Double>()->isComplex())) &&
1463             pITStart->isList() == false) // list case => call overload
1464     {
1465         pITStart->killMe();
1466         setResult(NULL);
1467         wchar_t szError[bsiz];
1468         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 1);
1469         CoverageInstance::stopChrono((void*)&e);
1470         throw InternalError(szError, 999, e.getLocation());
1471     }
1472     types::InternalType * piStart = pITStart;
1473
1474     try
1475     {
1476         e.getStep().accept(*this);
1477     }
1478     catch (ScilabException &)
1479     {
1480         CoverageInstance::stopChrono((void*)&e);
1481         throw;
1482     }
1483     types::GenericType* pITStep = static_cast<types::GenericType*>(getResult());
1484     setResult(NULL);
1485     if ((pITStep->getSize() != 1 || (pITStep->isDouble() && pITStep->getAs<types::Double>()->isComplex())) &&
1486             pITStep->isList() == false) // list case => call overload
1487     {
1488         pITStart->killMe();
1489         pITStep->killMe();
1490         setResult(NULL);
1491         wchar_t szError[bsiz];
1492         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2);
1493         CoverageInstance::stopChrono((void*)&e);
1494         throw InternalError(szError, 999, e.getLocation());
1495     }
1496     types::InternalType* piStep = pITStep;
1497
1498     try
1499     {
1500         e.getEnd().accept(*this);
1501     }
1502     catch (ScilabException &)
1503     {
1504         CoverageInstance::stopChrono((void*)&e);
1505         throw;
1506     }
1507
1508     types::GenericType* pITEnd = static_cast<types::GenericType*>(getResult());
1509     setResult(NULL);
1510     if ((pITEnd->getSize() != 1 || (pITEnd->isDouble() && pITEnd->getAs<types::Double>()->isComplex())) &&
1511             pITEnd->isList() == false) // list case => call overload
1512     {
1513         pITStart->killMe();
1514         pITStep->killMe();
1515         pITEnd->killMe();
1516         setResult(NULL);
1517         wchar_t szError[bsiz];
1518         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 3);
1519         CoverageInstance::stopChrono((void*)&e);
1520         throw InternalError(szError, 999, e.getLocation());
1521     }
1522     types::InternalType* piEnd = pITEnd;
1523
1524     ////check if implicitlist is 1:$ to replace by ':'
1525     //if (piStart->isDouble() && piStep->isDouble() && piEnd->isPoly())
1526     //{
1527     //    if (piStart->getAs<Double>()->get()[0] == 1 && piStep->getAs<Double>()->get()[0] == 1)
1528     //    {
1529     //        SinglePoly* end = piEnd->getAs<Polynom>()->get()[0];
1530     //        if (end->getRank() == 1 && end->get()[0] == 0 && end->get()[1] == 1)
1531     //        {
1532     //            setResult(new Colon());
1533     //            return;
1534     //        }
1535     //    }
1536     //}
1537
1538     //check compatibility
1539     // double : double : double or poly : poly : poly and mix like double : double : poly
1540     if ((piStart->isPoly() || piStart->isDouble()) &&
1541             (piStep->isPoly() || piStep->isDouble()) &&
1542             (piEnd->isPoly() || piEnd->isDouble()))
1543     {
1544         // No need to kill piStart, ... because Implicit list ctor will incref them
1545         setResult(new types::ImplicitList(piStart, piStep, piEnd));
1546         CoverageInstance::stopChrono((void*)&e);
1547         return;
1548     }
1549
1550     // int : double or int : int
1551     if (piStart->isInt() &&
1552             (piStep->isDouble() || piStep->isInt()) &&
1553             piEnd->isInt())
1554     {
1555         // check for same int type int8, int 16 ...
1556         if (piStart->getType() == piEnd->getType() &&
1557                 (piStart->getType() == piStep->getType() ||
1558                  piStep->isDouble()))
1559         {
1560             // No need to kill piStart, ... because Implicit list ctor will incref them
1561             setResult(new types::ImplicitList(piStart, piStep, piEnd));
1562             CoverageInstance::stopChrono((void*)&e);
1563             return;
1564         }
1565     }
1566
1567     // Call Overload
1568     types::Callable::ReturnValue Ret;
1569     types::typed_list in;
1570     types::typed_list out;
1571
1572     piStart->IncreaseRef();
1573     in.push_back(piStart);
1574
1575     try
1576     {
1577         if (e.hasExplicitStep())
1578         {
1579             // 1:2:4
1580             //call overload %typeStart_b_typeStep
1581             piStep->IncreaseRef();
1582             in.push_back(piStep);
1583             piEnd->IncreaseRef();
1584             in.push_back(piEnd);
1585             Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piStep->getShortTypeStr(), in, 1, out, true);
1586         }
1587         else
1588         {
1589             // 1:2
1590             //call overload %typeStart_b_typeEnd
1591             piStep->killMe();
1592             piEnd->IncreaseRef();
1593             in.push_back(piEnd);
1594             Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piEnd->getShortTypeStr(), in, 1, out, true);
1595         }
1596     }
1597     catch (const InternalError& error)
1598     {
1599         setResult(NULL);
1600         cleanInOut(in, out);
1601         CoverageInstance::stopChrono((void*)&e);
1602         throw error;
1603     }
1604
1605     if (Ret != types::Callable::OK)
1606     {
1607         setResult(NULL);
1608         cleanInOut(in, out);
1609         CoverageInstance::stopChrono((void*)&e);
1610         throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1611     }
1612
1613     setResult(out);
1614     cleanIn(in, out);
1615     CoverageInstance::stopChrono((void*)&e);
1616 }
1617
1618 template <class T>
1619 void RunVisitorT<T>::visitprivate(const OptimizedExp &e)
1620 {
1621 }
1622
1623 template <class T>
1624 void RunVisitorT<T>::visitprivate(const MemfillExp &e)
1625 {
1626     CoverageInstance::invokeAndStartChrono((void*)&e);
1627     try
1628     {
1629         e.getOriginal()->accept(*this);
1630     }
1631     catch (ScilabException &)
1632     {
1633         CoverageInstance::stopChrono((void*)&e);
1634         throw;
1635     }
1636 }
1637
1638 template <class T>
1639 void RunVisitorT<T>::visitprivate(const DAXPYExp &e)
1640 {
1641     CoverageInstance::invokeAndStartChrono((void*)&e);
1642     types::InternalType* pIT = NULL;
1643     types::Double* ad = NULL;
1644     int ar = 0;
1645     int ac = 0;
1646
1647     types::Double* xd = NULL;
1648     int xr = 0;
1649     int xc = 0;
1650
1651     types::Double* yd = NULL;
1652     int yr = 0;
1653     int yc = 0;
1654
1655     //check types and dimensions
1656
1657     //y must be double
1658     const Exp &ye = e.getY();
1659     try
1660     {
1661         ye.accept(*this);
1662     }
1663     catch (ScilabException &)
1664     {
1665         CoverageInstance::stopChrono((void*)&e);
1666         throw;
1667     }
1668
1669     pIT = getResult();
1670     if (pIT->isDouble())
1671     {
1672         yd = pIT->getAs<types::Double>();
1673         if (yd->getDims() == 2 && yd->isComplex() == false)
1674         {
1675             yr = yd->getRows();
1676             yc = yd->getCols();
1677         }
1678         else
1679         {
1680             yd->killMe();
1681             try
1682             {
1683                 e.getOriginal()->accept(*this);
1684             }
1685             catch (ScilabException &)
1686             {
1687                 CoverageInstance::stopChrono((void*)&e);
1688                 throw;
1689             }
1690             CoverageInstance::stopChrono((void*)&e);
1691             return;
1692         }
1693     }
1694     else
1695     {
1696         pIT->killMe();
1697         try
1698         {
1699             e.getOriginal()->accept(*this);
1700         }
1701         catch (ScilabException &)
1702         {
1703             CoverageInstance::stopChrono((void*)&e);
1704             throw;
1705         }
1706         CoverageInstance::stopChrono((void*)&e);
1707         return;
1708     }
1709
1710     //x
1711     const Exp &xe = e.getX();
1712     try
1713     {
1714         xe.accept(*this);
1715     }
1716     catch (ScilabException &)
1717     {
1718         CoverageInstance::stopChrono((void*)&e);
1719         throw;
1720     }
1721     pIT = getResult();
1722
1723     if (pIT->isDouble())
1724     {
1725         xd = pIT->getAs<types::Double>();
1726         if (xd->isScalar() && xd->isComplex() == false)
1727         {
1728             // x become a
1729             ad = xd;
1730             ar = 1;
1731             ac = 1;
1732         }
1733         else if (xd->getDims() == 2 && xd->isComplex() == false)
1734         {
1735             xr = xd->getRows();
1736             xc = xd->getCols();
1737         }
1738         else
1739         {
1740             yd->killMe();
1741             xd->killMe();
1742             try
1743             {
1744                 e.getOriginal()->accept(*this);
1745             }
1746             catch (ScilabException &)
1747             {
1748                 CoverageInstance::stopChrono((void*)&e);
1749                 throw;
1750             }
1751             CoverageInstance::stopChrono((void*)&e);
1752             return;
1753         }
1754     }
1755     else
1756     {
1757         pIT->killMe();
1758         yd->killMe();
1759         try
1760         {
1761             e.getOriginal()->accept(*this);
1762         }
1763         catch (ScilabException &)
1764         {
1765             CoverageInstance::stopChrono((void*)&e);
1766             throw;
1767         }
1768         CoverageInstance::stopChrono((void*)&e);
1769         return;
1770     }
1771
1772     const Exp &ae = e.getA();
1773     try
1774     {
1775         ae.accept(*this);
1776     }
1777     catch (ScilabException &)
1778     {
1779         CoverageInstance::stopChrono((void*)&e);
1780         throw;
1781     }
1782     pIT = getResult();
1783
1784     if (pIT->isDouble())
1785     {
1786         if (ad)
1787         {
1788             xd = pIT->getAs<types::Double>();
1789             //X is scalar it become A
1790             //now use A as X
1791             if (xd->getDims() == 2 && xd->isComplex() == false)
1792             {
1793                 xr = xd->getRows();
1794                 xc = xd->getCols();
1795             }
1796             else
1797             {
1798                 yd->killMe();
1799                 xd->killMe();
1800                 ad->killMe();
1801                 try
1802                 {
1803                     e.getOriginal()->accept(*this);
1804                 }
1805                 catch (ScilabException &)
1806                 {
1807                     CoverageInstance::stopChrono((void*)&e);
1808                     throw;
1809                 }
1810                 CoverageInstance::stopChrono((void*)&e);
1811                 return;
1812             }
1813         }
1814         else
1815         {
1816             //a is a and it must be scalar
1817             ad = pIT->getAs<types::Double>();
1818             if (/*ad->isScalar() && */ad->isComplex() == false)
1819             {
1820                 ar = ad->getRows(); //1;
1821                 ac = ad->getCols();//1;
1822             }
1823             else
1824             {
1825                 yd->killMe();
1826                 xd->killMe();
1827                 ad->killMe();
1828                 try
1829                 {
1830                     e.getOriginal()->accept(*this);
1831                 }
1832                 catch (ScilabException &)
1833                 {
1834                     CoverageInstance::stopChrono((void*)&e);
1835                     throw;
1836                 }
1837                 throw;
1838                 return;
1839             }
1840         }
1841     }
1842     else
1843     {
1844         pIT->killMe();
1845         yd->killMe();
1846         xd->killMe();
1847         try
1848         {
1849             e.getOriginal()->accept(*this);
1850         }
1851         catch (ScilabException &)
1852         {
1853             CoverageInstance::stopChrono((void*)&e);
1854             throw;
1855         }
1856         CoverageInstance::stopChrono((void*)&e);
1857         return;
1858     }
1859
1860     if (ad && xd && yd)
1861     {
1862         if (ac == 1 &&
1863                 ar == 1 &&
1864                 xr == yr &&
1865                 xc == yc)
1866         {
1867             //go !
1868             int one = 1;
1869             int size = xc * xr;
1870             //Double* od = (Double*)yd->clone();
1871             C2F(daxpy)(&size, ad->get(), xd->get(), &one, yd->get(), &one);
1872             //setResult(od);
1873             //yd->killMe();
1874             xd->killMe();
1875             ad->killMe();
1876             CoverageInstance::stopChrono((void*)&e);
1877             return;
1878         }
1879         else if (ac == xr && ar == yr && xc == yc)
1880         {
1881             char n = 'n';
1882             double one = 1;
1883             C2F(dgemm)(&n, &n, &ar, &xc, &ac, &one, ad->get(), &ar, xd->get(), &ac, &one, yd->get(), &ar);
1884             xd->killMe();
1885             ad->killMe();
1886             CoverageInstance::stopChrono((void*)&e);
1887             return;
1888         }
1889     }
1890
1891     if (yd)
1892     {
1893         yd->killMe();
1894     }
1895
1896     if (xd)
1897     {
1898         xd->killMe();
1899     }
1900
1901     if (ad)
1902     {
1903         ad->killMe();
1904     }
1905
1906     try
1907     {
1908         e.getOriginal()->accept(*this);
1909     }
1910     catch (ScilabException &)
1911     {
1912         CoverageInstance::stopChrono((void*)&e);
1913         throw;
1914     }
1915     CoverageInstance::stopChrono((void*)&e);
1916
1917     return;
1918 }
1919
1920 template <class T>
1921 void RunVisitorT<T>::visitprivate(const TryCatchExp  &e)
1922 {
1923     CoverageInstance::invokeAndStartChrono((void*)&e);
1924     //save current prompt mode
1925     bool oldVal = ConfigVariable::isSilentError();
1926     int oldMode = ConfigVariable::getPromptMode();
1927     //set mode silent for errors
1928     ConfigVariable::setSilentError(true);
1929
1930     symbol::Context* pCtx = symbol::Context::getInstance();
1931     try
1932     {
1933         int scope = pCtx->getScopeLevel();
1934         int level = ConfigVariable::getRecursionLevel();
1935         try
1936         {
1937             e.getTry().accept(*this);
1938             //restore previous prompt mode
1939             ConfigVariable::setSilentError(oldVal);
1940         }
1941         catch (const RecursionException& /* re */)
1942         {
1943             ConfigVariable::setPromptMode(oldMode);
1944
1945             //close opened scope during try
1946             while (pCtx->getScopeLevel() > scope)
1947             {
1948                 pCtx->scope_end();
1949             }
1950
1951             //decrease recursion to init value and close where
1952             while (ConfigVariable::getRecursionLevel() > level)
1953             {
1954                 ConfigVariable::where_end();
1955                 ConfigVariable::decreaseRecursion();
1956             }
1957
1958             //print msg about recursion limit and trigger an error
1959             wchar_t sz[1024];
1960             os_swprintf(sz, 1024, _W("Recursion limit reached (%d).\n").data(), ConfigVariable::getRecursionLimit());
1961             CoverageInstance::stopChrono((void*)&e);
1962             throw ast::InternalError(sz);
1963         }
1964
1965     }
1966     catch (const InternalError& /* ie */)
1967     {
1968         //restore previous prompt mode
1969         ConfigVariable::setSilentError(oldVal);
1970         //to lock lasterror
1971         ConfigVariable::setLastErrorCall();
1972         // reset call stack filled when error occured
1973         ConfigVariable::resetWhereError();
1974         try
1975         {
1976             e.getCatch().accept(*this);
1977         }
1978         catch (ScilabException &)
1979         {
1980             CoverageInstance::stopChrono((void*)&e);
1981             throw;
1982         }
1983     }
1984     CoverageInstance::stopChrono((void*)&e);
1985 }
1986
1987
1988 } /* namespace ast */
1989
1990 #include "run_SeqExp.hpp"
1991 #include "run_CallExp.hpp"
1992 #include "run_MatrixExp.hpp"
1993 #include "run_OpExp.hpp"
1994 #include "run_AssignExp.hpp"
1995
1996 template EXTERN_AST class ast::RunVisitorT<ast::ExecVisitor>;
1997 template EXTERN_AST class ast::RunVisitorT<ast::StepVisitor>;
1998 template EXTERN_AST class ast::RunVisitorT<ast::TimedVisitor>;
1999 template EXTERN_AST class ast::RunVisitorT<ast::DebuggerVisitor>;