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