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