78ec8fc77e532c1c76dc69c68502f10f6a7aeef7
[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             e.getElse().accept(*this);
517         }
518     }
519     catch (ScilabException &)
520     {
521         CoverageInstance::stopChrono((void*)&e);
522         throw;
523     }
524
525     if (e.isBreakable()
526         && ((e.hasElse() && (&e.getElse())->isContinue())
527         || (&e.getThen())->isBreak()))
528     {
529         const_cast<IfExp*>(&e)->setBreak();
530         const_cast<Exp*>(&e.getThen())->resetBreak();
531         if (e.hasElse())
532         {
533             const_cast<Exp*>(&e.getElse())->resetBreak();
534         }
535     }
536
537     if (e.isContinuable()
538         && ((e.hasElse() && (&e.getElse())->isContinue())
539         || (&e.getThen())->isContinue()))
540     {
541         const_cast<IfExp*>(&e)->setContinue();
542         const_cast<Exp*>(&e.getThen())->resetContinue();
543         if (e.hasElse())
544         {
545             const_cast<Exp*>(&e.getElse())->resetContinue();
546         }
547     }
548
549     if (e.isReturnable()
550         && ((e.hasElse() && (&e.getElse())->isReturn())
551         || (&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             if (ConfigVariable::getEnableDebug() == true)
909             {
910                 sciprint(_("%s: function is disabled in debug mode.\n"), "resume");
911                 CoverageInstance::stopChrono((void*)&e);
912                 return;
913             }
914
915             //return or resume
916             ConfigVariable::DecreasePauseLevel();
917             ConfigVariable::macroFirstLine_end();
918             CoverageInstance::stopChrono((void*)&e);
919             return;
920         }
921         else
922         {
923             const_cast<ReturnExp*>(&e)->setReturn();
924         }
925     }
926     else
927     {
928         //return(x)
929
930         if (e.getParent() == nullptr || e.getParent()->isAssignExp() == false)
931         {
932             CoverageInstance::stopChrono((void*)&e);
933             throw InternalError(_W("With input arguments, return / resume expects output arguments.\n"), 999, e.getLocation());
934         }
935         //in case of CallExp, we can return only one value
936         int iSaveExpectedSize = getExpectedSize();
937         setExpectedSize(1);
938         try
939         {
940             e.getExp().accept(*this);
941         }
942         catch (ScilabException &)
943         {
944             CoverageInstance::stopChrono((void*)&e);
945             throw;
946         }
947         setExpectedSize(iSaveExpectedSize);
948         const_cast<ReturnExp*>(&e)->setReturn();
949     }
950
951     CoverageInstance::stopChrono((void*)&e);
952 }
953
954 template <class T>
955 void RunVisitorT<T>::visitprivate(const IntSelectExp &e)
956 {
957     CoverageInstance::invokeAndStartChrono((void*)&e);
958     bool found = false;
959     //e.getSelect()->accept(*this);
960     //InternalType* pIT = getResult();
961     //setResult(nullptr);
962     //if (pIT && pIT->isDouble())
963     //{
964     //    Double * pDbl = static_cast<Double *>(pIT);
965     //    if (!pDbl->isComplex() && pDbl->getSize() == 1)
966     //    {
967     //        int64_t val;
968     //        if (analysis::tools::asInteger<int64_t>(pDbl->get(0), val))
969     //        {
970     //            Exp * exp = e.getExp(val);
971     //            found = true;
972     //            if (exp)
973     //            {
974     //                Exp * body = exp->isCaseExp() ? exp->getAs<CaseExp>()->getBody() : exp;
975     //                if (e.isBreakable())
976     //                {
977     //                    const_cast<IntSelectExp*>(&e)->resetBreak();
978     //                    body->setBreakable();
979     //                }
980
981     //                if (e.isContinuable())
982     //                {
983     //                    const_cast<IntSelectExp*>(&e)->resetContinue();
984     //                    body->setContinuable();
985     //                }
986
987     //                if (e.isReturnable())
988     //                {
989     //                    const_cast<IntSelectExp*>(&e)->resetReturn();
990     //                    body->setReturnable();
991     //                }
992
993     //                try
994     //                {
995     //                    //the good one
996     //                    body->accept(*this);
997     //                }
998     //                catch (const InternalError& ie)
999     //                {
1000     //                    pIT->killMe();
1001     //                    throw ie;
1002     //                }
1003
1004     //                if (e.isBreakable() && body->isBreak())
1005     //                {
1006     //                    const_cast<IntSelectExp*>(&e)->setBreak();
1007     //                    body->resetBreak();
1008     //                }
1009
1010     //                if (e.isContinuable() && body->isContinue())
1011     //                {
1012     //                    const_cast<IntSelectExp*>(&e)->setContinue();
1013     //                    body->resetContinue();
1014     //                }
1015
1016     //                if (e.isReturnable() && body->isReturn())
1017     //                {
1018     //                    const_cast<IntSelectExp*>(&e)->setReturn();
1019     //                    body->resetReturn();
1020     //                }
1021     //            }
1022     //        }
1023     //    }
1024     //}
1025
1026     if (!found)
1027     {
1028         try
1029         {
1030             e.getOriginal()->accept(*this);
1031         }
1032         catch (ScilabException &)
1033         {
1034             CoverageInstance::stopChrono((void*)&e);
1035             throw;
1036         }
1037     }
1038     CoverageInstance::stopChrono((void*)&e);
1039 }
1040
1041 template <class T>
1042 void RunVisitorT<T>::visitprivate(const StringSelectExp &e)
1043 {
1044     CoverageInstance::invokeAndStartChrono((void*)&e);
1045     try
1046     {
1047         e.getSelect()->accept(*this);
1048     }
1049     catch (ScilabException &)
1050     {
1051         CoverageInstance::stopChrono((void*)&e);
1052         throw;
1053     }
1054     types::InternalType* pIT = getResult();
1055     setResult(nullptr);
1056     bool found = false;
1057     if (pIT && pIT->isString())
1058     {
1059         types::String * pStr = static_cast<types::String *>(pIT);
1060         if (pStr->getSize() == 1)
1061         {
1062             if (wchar_t * s = pStr->get(0))
1063             {
1064                 const std::wstring ws(s);
1065                 Exp * exp = e.getExp(ws);
1066                 found = true;
1067                 if (exp)
1068                 {
1069                     Exp * body = exp->isCaseExp() ? exp->getAs<CaseExp>()->getBody() : exp;
1070                     if (e.isBreakable())
1071                     {
1072                         const_cast<StringSelectExp*>(&e)->resetBreak();
1073                         body->setBreakable();
1074                     }
1075
1076                     if (e.isContinuable())
1077                     {
1078                         const_cast<StringSelectExp*>(&e)->resetContinue();
1079                         body->setContinuable();
1080                     }
1081
1082                     if (e.isReturnable())
1083                     {
1084                         const_cast<StringSelectExp*>(&e)->resetReturn();
1085                         body->setReturnable();
1086                     }
1087
1088                     try
1089                     {
1090                         //the good one
1091                         body->accept(*this);
1092                     }
1093                     catch (const InternalError& ie)
1094                     {
1095                         pIT->killMe();
1096                         CoverageInstance::stopChrono((void*)&e);
1097                         throw ie;
1098                     }
1099
1100                     if (e.isBreakable() && body->isBreak())
1101                     {
1102                         const_cast<StringSelectExp*>(&e)->setBreak();
1103                         body->resetBreak();
1104                     }
1105
1106                     if (e.isContinuable() && body->isContinue())
1107                     {
1108                         const_cast<StringSelectExp*>(&e)->setContinue();
1109                         body->resetContinue();
1110                     }
1111
1112                     if (e.isReturnable() && body->isReturn())
1113                     {
1114                         const_cast<StringSelectExp*>(&e)->setReturn();
1115                         body->resetReturn();
1116                     }
1117                 }
1118             }
1119         }
1120     }
1121
1122     if (!found)
1123     {
1124         try
1125         {
1126             e.getOriginal()->accept(*this);
1127         }
1128         catch (ScilabException &)
1129         {
1130             CoverageInstance::stopChrono((void*)&e);
1131             throw;
1132         }
1133     }
1134     CoverageInstance::stopChrono((void*)&e);
1135 }
1136
1137 template <class T>
1138 void RunVisitorT<T>::visitprivate(const SelectExp &e)
1139 {
1140     // FIXME : exec select ... case ... else ... end
1141     CoverageInstance::invokeAndStartChrono((void*)&e);
1142     try
1143     {
1144         e.getSelect()->accept(*this);
1145     }
1146     catch (ScilabException &)
1147     {
1148         CoverageInstance::stopChrono((void*)&e);
1149         throw;
1150     }
1151
1152     bool bCase = false;
1153
1154     types::InternalType* pIT = getResult();
1155     setResult(NULL);
1156     if (pIT)
1157     {
1158         // protect pIT to avoid double free when
1159         // the variable in select is override in the case
1160         pIT->IncreaseRef();
1161
1162         //find good case
1163         exps_t cases = e.getCases();
1164         for (auto exp : cases)
1165         {
1166             CaseExp * pCase = exp->getAs<CaseExp>();
1167             try
1168             {
1169                 pCase->getTest()->accept(*this);
1170             }
1171             catch (ScilabException &)
1172             {
1173                 CoverageInstance::stopChrono((void*)&e);
1174                 throw;
1175             }
1176             types::InternalType *pITCase = getResult();
1177             setResult(NULL);
1178             if (pITCase)
1179             {
1180                 if (pITCase->isContainer()) //WARNING ONLY FOR CELL
1181                 {
1182                     //check each item
1183                 }
1184                 else if (*pITCase == *pIT)
1185                 {
1186                     try
1187                     {
1188                         //the good one
1189                         pCase->getBody()->accept(*this);
1190                     }
1191                     catch (const InternalError& ie)
1192                     {
1193                         pIT->DecreaseRef();
1194                         pIT->killMe();
1195                         CoverageInstance::stopChrono((void*)&e);
1196                         throw ie;
1197                     }
1198
1199                     if (e.isBreakable() && pCase->getBody()->isBreak())
1200                     {
1201                         const_cast<SelectExp*>(&e)->setBreak();
1202                         pCase->getBody()->resetBreak();
1203                     }
1204
1205                     if (e.isContinuable() && pCase->getBody()->isContinue())
1206                     {
1207                         const_cast<SelectExp*>(&e)->setContinue();
1208                         pCase->getBody()->resetContinue();
1209                     }
1210
1211                     if (e.isReturnable() && pCase->getBody()->isReturn())
1212                     {
1213                         const_cast<SelectExp*>(&e)->setReturn();
1214                         pCase->getBody()->resetReturn();
1215                     }
1216
1217                     pITCase->killMe();
1218                     bCase = true;
1219                     break;
1220                 }
1221
1222                 pITCase->killMe();
1223             }
1224         }
1225     }
1226
1227     if (bCase == false && e.getDefaultCase() != NULL)
1228     {
1229         try
1230         {
1231             //default case
1232             e.getDefaultCase()->accept(*this);
1233         }
1234         catch (const InternalError& ie)
1235         {
1236             if (pIT)
1237             {
1238                 pIT->DecreaseRef();
1239                 pIT->killMe();
1240             }
1241             CoverageInstance::stopChrono((void*)&e);
1242             throw ie;
1243         }
1244
1245         if (e.isBreakable() && e.getDefaultCase()->isBreak())
1246         {
1247             const_cast<SelectExp*>(&e)->setBreak();
1248             e.getDefaultCase()->resetBreak();
1249         }
1250
1251         if (e.isContinuable() && e.getDefaultCase()->isContinue())
1252         {
1253             const_cast<SelectExp*>(&e)->setContinue();
1254             e.getDefaultCase()->resetContinue();
1255         }
1256
1257         if (e.isReturnable() && e.getDefaultCase()->isReturn())
1258         {
1259             const_cast<SelectExp*>(&e)->setReturn();
1260             e.getDefaultCase()->resetReturn();
1261         }
1262     }
1263
1264     clearResult();
1265
1266     if (pIT)
1267     {
1268         pIT->DecreaseRef();
1269         pIT->killMe();
1270     }
1271     CoverageInstance::stopChrono((void*)&e);
1272 }
1273
1274 template <class T>
1275 void RunVisitorT<T>::visitprivate(const NotExp &e)
1276 {
1277     CoverageInstance::invokeAndStartChrono((void*)&e);
1278     /*
1279       @ or ~ !
1280       */
1281     try
1282     {
1283         e.getExp().accept(*this);
1284     }
1285     catch (ScilabException &)
1286     {
1287         CoverageInstance::stopChrono((void*)&e);
1288         throw;
1289     }
1290
1291     types::InternalType * pValue = getResult();
1292     types::InternalType * pReturn = NULL;
1293     if (pValue->neg(pReturn))
1294     {
1295         if (pValue != pReturn)
1296         {
1297             pValue->killMe();
1298         }
1299
1300         setResult(pReturn);
1301     }
1302     else
1303     {
1304         // neg returned false so the negation is not possible so we call the overload (%foo_5)
1305         types::typed_list in;
1306         types::typed_list out;
1307
1308         pValue->IncreaseRef();
1309         in.push_back(pValue);
1310
1311         types::Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_5", in, 1, out, true);
1312
1313         if (Ret != types::Callable::OK)
1314         {
1315             cleanInOut(in, out);
1316             CoverageInstance::stopChrono((void*)&e);
1317             throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1318         }
1319
1320         setResult(out);
1321         cleanIn(in, out);
1322     }
1323     CoverageInstance::stopChrono((void*)&e);
1324 }
1325
1326 template <class T>
1327 void RunVisitorT<T>::visitprivate(const TransposeExp &e)
1328 {
1329     CoverageInstance::invokeAndStartChrono((void*)&e);
1330     try
1331     {
1332         e.getExp().accept(*this);
1333     }
1334     catch (ScilabException &)
1335     {
1336         CoverageInstance::stopChrono((void*)&e);
1337         throw;
1338     }
1339
1340     if (getResultSize() != 1)
1341     {
1342         clearResult();
1343         wchar_t szError[bsiz];
1344         os_swprintf(szError, bsiz, _W("%ls: Can not transpose multiple elements.\n").c_str(), L"Transpose");
1345         CoverageInstance::stopChrono((void*)&e);
1346         throw InternalError(szError, 999, e.getLocation());
1347     }
1348
1349     types::InternalType * pValue = getResult();
1350     types::InternalType * pReturn = NULL;
1351     const bool bConjug = e.getConjugate() == TransposeExp::_Conjugate_;
1352
1353     if ((bConjug && pValue->adjoint(pReturn)) || (!bConjug && pValue->transpose(pReturn)))
1354     {
1355         if (pValue != pReturn)
1356         {
1357             pValue->killMe();
1358         }
1359
1360         setResult(pReturn);
1361         CoverageInstance::stopChrono((void*)&e);
1362
1363         return;
1364     }
1365     else
1366     {
1367         // transpose returned false so the negation is not possible so we call the overload (%foo_t or %foo_0)
1368         types::typed_list in;
1369         types::typed_list out;
1370
1371         pValue->IncreaseRef();
1372         in.push_back(pValue);
1373
1374         types::Callable::ReturnValue Ret;
1375         if (bConjug)
1376         {
1377             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_t", in, 1, out, true);
1378         }
1379         else
1380         {
1381             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_0", in, 1, out, true);
1382         }
1383
1384         if (Ret != types::Callable::OK)
1385         {
1386             cleanInOut(in, out);
1387             CoverageInstance::stopChrono((void*)&e);
1388             throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1389         }
1390
1391         setResult(out);
1392         cleanIn(in, out);
1393     }
1394
1395     CoverageInstance::stopChrono((void*)&e);
1396 }
1397
1398 template <class T>
1399 void RunVisitorT<T>::visitprivate(const FunctionDec & e)
1400 {
1401     CoverageInstance::invokeAndStartChrono((void*)&e);
1402     symbol::Context* ctx = symbol::Context::getInstance();
1403     /*
1404       function foo
1405       endfunction
1406       */
1407
1408     // funcprot(0) : do nothing
1409     // funcprot(1) && warning(on) : warning
1410     //get input parameters list
1411     std::list<symbol::Variable*> *pVarList = new std::list<symbol::Variable*>();
1412     const exps_t & vars = e.getArgs().getVars();
1413     for (const auto var : vars)
1414     {
1415         pVarList->push_back(var->getAs<SimpleVar>()->getStack());
1416     }
1417
1418     //get output parameters list
1419     std::list<symbol::Variable*> *pRetList = new std::list<symbol::Variable*>();
1420     const exps_t & rets = e.getReturns().getVars();
1421     for (const auto ret : rets)
1422     {
1423         pRetList->push_back(ret->getAs<SimpleVar>()->getStack());
1424     }
1425
1426     types::Macro *pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList,
1427                                             const_cast<SeqExp&>(static_cast<const SeqExp&>(e.getBody())), L"script");
1428     pMacro->setLines(e.getLocation().first_line, e.getLocation().last_line);
1429
1430     if (ctx->isprotected(symbol::Symbol(pMacro->getName())))
1431     {
1432         delete pMacro;
1433         std::wostringstream os;
1434         os << _W("Redefining permanent variable.\n");
1435         CoverageInstance::stopChrono((void*)&e);
1436         throw InternalError(os.str(), 999, e.getLocation());
1437     }
1438
1439     if (ctx->addMacro(pMacro) == false)
1440     {
1441         char pstError[1024];
1442         char* pstFuncName = wide_string_to_UTF8(e.getSymbol().getName().c_str());
1443         os_sprintf(pstError, _("It is not possible to redefine the %s primitive this way (see clearfun).\n"), pstFuncName);
1444         wchar_t* pwstError = to_wide_string(pstError);
1445         std::wstring wstError(pwstError);
1446         FREE(pstFuncName);
1447         FREE(pwstError);
1448         pMacro->killMe();
1449         CoverageInstance::stopChrono((void*)&e);
1450         throw InternalError(wstError, 999, e.getLocation());
1451     }
1452
1453     CoverageInstance::stopChrono((void*)&e);
1454 }
1455
1456 template <class T>
1457 void RunVisitorT<T>::visitprivate(const ListExp &e)
1458 {
1459     CoverageInstance::invokeAndStartChrono((void*)&e);
1460     try
1461     {
1462         e.getStart().accept(*this);
1463     }
1464     catch (ScilabException &)
1465     {
1466         CoverageInstance::stopChrono((void*)&e);
1467         throw;
1468     }
1469
1470     types::InternalType* pITStart = getResult();
1471     types::GenericType* pStart = static_cast<types::GenericType*>(pITStart);
1472     if (pITStart == NULL ||
1473         ((pITStart->isGenericType() == false || pStart->getSize() != 1 || (pStart->isDouble() && pStart->getAs<types::Double>()->isComplex())) &&
1474         pStart->isList() == false)) // list case => call overload
1475     {
1476         setResult(NULL);
1477         wchar_t szError[bsiz];
1478         if (pITStart && pITStart->isImplicitList()) {
1479             os_swprintf(szError, bsiz, _W("%ls: Too many %ls or wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", L"':'", 1);
1480         }
1481         else
1482         {
1483             os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 1);
1484         }
1485
1486         if (pITStart)
1487         {
1488             pITStart->killMe();
1489         }
1490
1491         CoverageInstance::stopChrono((void*)&e);
1492         throw InternalError(szError, 999, e.getLocation());
1493     }
1494
1495     try
1496     {
1497         e.getStep().accept(*this);
1498     }
1499     catch (ScilabException &)
1500     {
1501         CoverageInstance::stopChrono((void*)&e);
1502         throw;
1503     }
1504
1505     types::InternalType* pITStep = getResult();
1506     types::GenericType* pStep = static_cast<types::GenericType*>(pITStep);
1507     setResult(NULL);
1508     if (pITStep == NULL ||
1509         ((pITStep->isGenericType() == false || pStep->getSize() != 1 || (pStep->isDouble() && pStep->getAs<types::Double>()->isComplex())) &&
1510         pStep->isList() == false)) // list case => call overload
1511     {
1512         pITStart->killMe();
1513         if (pITStep)
1514         {
1515             pITStep->killMe();
1516         }
1517
1518         setResult(NULL);
1519         wchar_t szError[bsiz];
1520         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2);
1521         CoverageInstance::stopChrono((void*)&e);
1522         throw InternalError(szError, 999, e.getLocation());
1523     }
1524
1525     try
1526     {
1527         e.getEnd().accept(*this);
1528     }
1529     catch (ScilabException &)
1530     {
1531         CoverageInstance::stopChrono((void*)&e);
1532         throw;
1533     }
1534
1535     types::InternalType* pITEnd = getResult();
1536     types::GenericType* pEnd = static_cast<types::GenericType*>(pITEnd);
1537     setResult(NULL);
1538     if (pITEnd == NULL ||
1539         ((pITEnd->isGenericType() == false || pEnd->getSize() != 1 || (pEnd->isDouble() && pEnd->getAs<types::Double>()->isComplex())) &&
1540         pEnd->isList() == false)) // list case => call overload
1541     {
1542         pITStart->killMe();
1543         pITStep->killMe();
1544         if (pITEnd)
1545         {
1546             pITEnd->killMe();
1547         }
1548
1549         setResult(NULL);
1550         wchar_t szError[bsiz];
1551         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2 + e.hasExplicitStep());
1552         CoverageInstance::stopChrono((void*)&e);
1553         throw InternalError(szError, 999, e.getLocation());
1554     }
1555
1556     ////check if implicitlist is 1:$ to replace by ':'
1557     //if (piStart->isDouble() && piStep->isDouble() && piEnd->isPoly())
1558     //{
1559     //    if (piStart->getAs<Double>()->get()[0] == 1 && piStep->getAs<Double>()->get()[0] == 1)
1560     //    {
1561     //        SinglePoly* end = piEnd->getAs<Polynom>()->get()[0];
1562     //        if (end->getRank() == 1 && end->get()[0] == 0 && end->get()[1] == 1)
1563     //        {
1564     //            setResult(new Colon());
1565     //            return;
1566     //        }
1567     //    }
1568     //}
1569
1570     //check compatibility
1571     // double : double : double or poly : poly : poly and mix like double : double : poly
1572     if ((pStart->isPoly() || pStart->isDouble()) &&
1573             (pStep->isPoly() || pStep->isDouble()) &&
1574             (pEnd->isPoly() || pEnd->isDouble()))
1575     {
1576         // No need to kill piStart, ... because Implicit list ctor will incref them
1577         setResult(new types::ImplicitList(pStart, pStep, pEnd));
1578         CoverageInstance::stopChrono((void*)&e);
1579         return;
1580     }
1581
1582     // int : double or int : int
1583     if (pStart->isInt() &&
1584             (pStep->isDouble() || pStep->isInt()) &&
1585             pEnd->isInt())
1586     {
1587         // check for same int type int8, int 16 ...
1588         if (pStart->getType() == pEnd->getType() &&
1589                 (pStart->getType() == pStep->getType() ||
1590                  pStep->isDouble()))
1591         {
1592             // No need to kill piStart, ... because Implicit list ctor will incref them
1593             setResult(new types::ImplicitList(pStart, pStep, pEnd));
1594             CoverageInstance::stopChrono((void*)&e);
1595             return;
1596         }
1597     }
1598
1599     // Call Overload
1600     types::Callable::ReturnValue Ret;
1601     types::typed_list in;
1602     types::typed_list out;
1603
1604     pStart->IncreaseRef();
1605     in.push_back(pStart);
1606
1607     try
1608     {
1609         if (e.hasExplicitStep())
1610         {
1611             // 1:2:4
1612             //call overload %typeStart_b_typeStep
1613             pStep->IncreaseRef();
1614             in.push_back(pStep);
1615             pEnd->IncreaseRef();
1616             in.push_back(pEnd);
1617             Ret = Overload::call(L"%" + pStart->getShortTypeStr() + L"_b_" + pStep->getShortTypeStr(), in, 1, out, true);
1618         }
1619         else
1620         {
1621             // 1:2
1622             //call overload %typeStart_b_typeEnd
1623             pStep->killMe();
1624             pEnd->IncreaseRef();
1625             in.push_back(pEnd);
1626             Ret = Overload::call(L"%" + pStart->getShortTypeStr() + L"_b_" + pEnd->getShortTypeStr(), in, 1, out, true);
1627         }
1628     }
1629     catch (const InternalError& error)
1630     {
1631         setResult(NULL);
1632         cleanInOut(in, out);
1633         CoverageInstance::stopChrono((void*)&e);
1634         throw error;
1635     }
1636
1637     if (Ret != types::Callable::OK)
1638     {
1639         setResult(NULL);
1640         cleanInOut(in, out);
1641         CoverageInstance::stopChrono((void*)&e);
1642         throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1643     }
1644
1645     setResult(out);
1646     cleanIn(in, out);
1647     CoverageInstance::stopChrono((void*)&e);
1648 }
1649
1650 template <class T>
1651 void RunVisitorT<T>::visitprivate(const OptimizedExp &e)
1652 {
1653 }
1654
1655 template <class T>
1656 void RunVisitorT<T>::visitprivate(const MemfillExp &e)
1657 {
1658     CoverageInstance::invokeAndStartChrono((void*)&e);
1659     try
1660     {
1661         e.getOriginal()->accept(*this);
1662     }
1663     catch (ScilabException &)
1664     {
1665         CoverageInstance::stopChrono((void*)&e);
1666         throw;
1667     }
1668 }
1669
1670 template <class T>
1671 void RunVisitorT<T>::visitprivate(const DAXPYExp &e)
1672 {
1673     CoverageInstance::invokeAndStartChrono((void*)&e);
1674     types::InternalType* pIT = NULL;
1675     types::Double* ad = NULL;
1676     int ar = 0;
1677     int ac = 0;
1678
1679     types::Double* xd = NULL;
1680     int xr = 0;
1681     int xc = 0;
1682
1683     types::Double* yd = NULL;
1684     int yr = 0;
1685     int yc = 0;
1686
1687     //check types and dimensions
1688
1689     //y must be double
1690     const Exp &ye = e.getY();
1691     try
1692     {
1693         ye.accept(*this);
1694     }
1695     catch (ScilabException &)
1696     {
1697         CoverageInstance::stopChrono((void*)&e);
1698         throw;
1699     }
1700
1701     pIT = getResult();
1702     if (pIT->isDouble())
1703     {
1704         yd = pIT->getAs<types::Double>();
1705         if (yd->getDims() == 2 && yd->isComplex() == false)
1706         {
1707             yr = yd->getRows();
1708             yc = yd->getCols();
1709         }
1710         else
1711         {
1712             yd->killMe();
1713             try
1714             {
1715                 e.getOriginal()->accept(*this);
1716             }
1717             catch (ScilabException &)
1718             {
1719                 CoverageInstance::stopChrono((void*)&e);
1720                 throw;
1721             }
1722             CoverageInstance::stopChrono((void*)&e);
1723             return;
1724         }
1725     }
1726     else
1727     {
1728         pIT->killMe();
1729         try
1730         {
1731             e.getOriginal()->accept(*this);
1732         }
1733         catch (ScilabException &)
1734         {
1735             CoverageInstance::stopChrono((void*)&e);
1736             throw;
1737         }
1738         CoverageInstance::stopChrono((void*)&e);
1739         return;
1740     }
1741
1742     //x
1743     const Exp &xe = e.getX();
1744     try
1745     {
1746         xe.accept(*this);
1747     }
1748     catch (ScilabException &)
1749     {
1750         CoverageInstance::stopChrono((void*)&e);
1751         throw;
1752     }
1753     pIT = getResult();
1754
1755     if (pIT->isDouble())
1756     {
1757         xd = pIT->getAs<types::Double>();
1758         if (xd->isScalar() && xd->isComplex() == false)
1759         {
1760             // x become a
1761             ad = xd;
1762             ar = 1;
1763             ac = 1;
1764         }
1765         else if (xd->getDims() == 2 && xd->isComplex() == false)
1766         {
1767             xr = xd->getRows();
1768             xc = xd->getCols();
1769         }
1770         else
1771         {
1772             yd->killMe();
1773             xd->killMe();
1774             try
1775             {
1776                 e.getOriginal()->accept(*this);
1777             }
1778             catch (ScilabException &)
1779             {
1780                 CoverageInstance::stopChrono((void*)&e);
1781                 throw;
1782             }
1783             CoverageInstance::stopChrono((void*)&e);
1784             return;
1785         }
1786     }
1787     else
1788     {
1789         pIT->killMe();
1790         yd->killMe();
1791         try
1792         {
1793             e.getOriginal()->accept(*this);
1794         }
1795         catch (ScilabException &)
1796         {
1797             CoverageInstance::stopChrono((void*)&e);
1798             throw;
1799         }
1800         CoverageInstance::stopChrono((void*)&e);
1801         return;
1802     }
1803
1804     const Exp &ae = e.getA();
1805     try
1806     {
1807         ae.accept(*this);
1808     }
1809     catch (ScilabException &)
1810     {
1811         CoverageInstance::stopChrono((void*)&e);
1812         throw;
1813     }
1814     pIT = getResult();
1815
1816     if (pIT->isDouble())
1817     {
1818         if (ad)
1819         {
1820             xd = pIT->getAs<types::Double>();
1821             //X is scalar it become A
1822             //now use A as X
1823             if (xd->getDims() == 2 && xd->isComplex() == false)
1824             {
1825                 xr = xd->getRows();
1826                 xc = xd->getCols();
1827             }
1828             else
1829             {
1830                 yd->killMe();
1831                 xd->killMe();
1832                 ad->killMe();
1833                 try
1834                 {
1835                     e.getOriginal()->accept(*this);
1836                 }
1837                 catch (ScilabException &)
1838                 {
1839                     CoverageInstance::stopChrono((void*)&e);
1840                     throw;
1841                 }
1842                 CoverageInstance::stopChrono((void*)&e);
1843                 return;
1844             }
1845         }
1846         else
1847         {
1848             //a is a and it must be scalar
1849             ad = pIT->getAs<types::Double>();
1850             if (/*ad->isScalar() && */ad->isComplex() == false)
1851             {
1852                 ar = ad->getRows(); //1;
1853                 ac = ad->getCols();//1;
1854             }
1855             else
1856             {
1857                 yd->killMe();
1858                 xd->killMe();
1859                 ad->killMe();
1860                 try
1861                 {
1862                     e.getOriginal()->accept(*this);
1863                 }
1864                 catch (ScilabException &)
1865                 {
1866                     CoverageInstance::stopChrono((void*)&e);
1867                     throw;
1868                 }
1869                 throw;
1870                 return;
1871             }
1872         }
1873     }
1874     else
1875     {
1876         pIT->killMe();
1877         yd->killMe();
1878         xd->killMe();
1879         try
1880         {
1881             e.getOriginal()->accept(*this);
1882         }
1883         catch (ScilabException &)
1884         {
1885             CoverageInstance::stopChrono((void*)&e);
1886             throw;
1887         }
1888         CoverageInstance::stopChrono((void*)&e);
1889         return;
1890     }
1891
1892     // If we get here we are certain that ad, xd & yd have been set
1893     if (ac == 1 &&
1894             ar == 1 &&
1895             xr == yr &&
1896             xc == yc)
1897     {
1898         //go !
1899         int one = 1;
1900         int size = xc * xr;
1901         //Double* od = (Double*)yd->clone();
1902         C2F(daxpy)(&size, ad->get(), xd->get(), &one, yd->get(), &one);
1903         //setResult(od);
1904         //yd->killMe();
1905         xd->killMe();
1906         ad->killMe();
1907         CoverageInstance::stopChrono((void*)&e);
1908         return;
1909     }
1910     else if (ac == xr && ar == yr && xc == yc)
1911     {
1912         char n = 'n';
1913         double one = 1;
1914         C2F(dgemm)(&n, &n, &ar, &xc, &ac, &one, ad->get(), &ar, xd->get(), &ac, &one, yd->get(), &ar);
1915         xd->killMe();
1916         ad->killMe();
1917         CoverageInstance::stopChrono((void*)&e);
1918         return;
1919     }
1920
1921     yd->killMe();
1922     xd->killMe();
1923     ad->killMe();
1924
1925     try
1926     {
1927         e.getOriginal()->accept(*this);
1928     }
1929     catch (ScilabException &)
1930     {
1931         CoverageInstance::stopChrono((void*)&e);
1932         throw;
1933     }
1934     CoverageInstance::stopChrono((void*)&e);
1935
1936     return;
1937 }
1938
1939 template <class T>
1940 void RunVisitorT<T>::visitprivate(const TryCatchExp  &e)
1941 {
1942     CoverageInstance::invokeAndStartChrono((void*)&e);
1943     //save current prompt mode
1944     bool oldVal = ConfigVariable::isSilentError();
1945     int oldMode = ConfigVariable::getPromptMode();
1946     //set mode silent for errors
1947     ConfigVariable::setSilentError(true);
1948
1949     symbol::Context* pCtx = symbol::Context::getInstance();
1950     try
1951     {
1952         int scope = pCtx->getScopeLevel();
1953         int level = ConfigVariable::getRecursionLevel();
1954         try
1955         {
1956             const_cast<Exp*>(&e.getTry())->setReturnable();
1957             e.getTry().accept(*this);
1958             //restore previous prompt mode
1959             ConfigVariable::setSilentError(oldVal);
1960
1961             if (e.getTry().isReturn())
1962             {
1963                 const_cast<Exp*>(&e.getTry())->resetReturn();
1964                 const_cast<TryCatchExp*>(&e)->setReturn();
1965             }
1966         }
1967         catch (const RecursionException& /* re */)
1968         {
1969             ConfigVariable::setPromptMode(oldMode);
1970
1971             //close opened scope during try
1972             while (pCtx->getScopeLevel() > scope)
1973             {
1974                 pCtx->scope_end();
1975             }
1976
1977             //decrease recursion to init value and close where
1978             while (ConfigVariable::getRecursionLevel() > level)
1979             {
1980                 ConfigVariable::where_end();
1981                 ConfigVariable::decreaseRecursion();
1982             }
1983
1984             //print msg about recursion limit and trigger an error
1985             wchar_t sz[1024];
1986             os_swprintf(sz, 1024, _W("Recursion limit reached (%d).\n").data(), ConfigVariable::getRecursionLimit());
1987             CoverageInstance::stopChrono((void*)&e);
1988             throw ast::InternalError(sz);
1989         }
1990
1991     }
1992     catch (const InternalError& /* ie */)
1993     {
1994         //restore previous prompt mode
1995         ConfigVariable::setSilentError(oldVal);
1996         //to lock lasterror
1997         ConfigVariable::setLastErrorCall();
1998         // reset call stack filled when error occurred
1999         ConfigVariable::resetWhereError();
2000         try
2001         {
2002             const_cast<Exp*>(&e.getCatch())->setReturnable();
2003             e.getCatch().accept(*this);
2004             if (e.getCatch().isReturn())
2005             {
2006                 const_cast<Exp*>(&e.getCatch())->resetReturn();
2007                 const_cast<TryCatchExp*>(&e)->setReturn();
2008             }
2009         }
2010         catch (ScilabException &)
2011         {
2012             CoverageInstance::stopChrono((void*)&e);
2013             throw;
2014         }
2015     }
2016     CoverageInstance::stopChrono((void*)&e);
2017 }
2018
2019
2020 } /* namespace ast */
2021
2022 #include "run_SeqExp.hpp"
2023 #include "run_CallExp.hpp"
2024 #include "run_MatrixExp.hpp"
2025 #include "run_OpExp.hpp"
2026 #include "run_AssignExp.hpp"
2027
2028 template EXTERN_AST class ast::RunVisitorT<ast::ExecVisitor>;
2029 template EXTERN_AST class ast::RunVisitorT<ast::StepVisitor>;
2030 template EXTERN_AST class ast::RunVisitorT<ast::TimedVisitor>;
2031 template EXTERN_AST class ast::RunVisitorT<ast::DebuggerVisitor>;