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