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