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