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