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