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