[debugger] return statement fix
[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 extern "C"
47 {
48 #include "sciprint.h"
49 #include "os_string.h"
50 #include "elem_common.h"
51 #include "storeCommand.h"
52 }
53
54 namespace ast
55 {
56 template <class T>
57 void RunVisitorT<T>::visitprivate(const CellExp &e)
58 {
59     exps_t::const_iterator row;
60     exps_t::const_iterator col;
61     int iColMax = 0;
62
63     exps_t lines = e.getLines();
64     //check dimmension
65     for (row = lines.begin() ; row != lines.end() ; ++row )
66     {
67         exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
68         if (iColMax == 0)
69         {
70             iColMax = static_cast<int>(cols.size());
71         }
72
73         if (iColMax != static_cast<int>(cols.size()))
74         {
75             std::wostringstream os;
76             os << _W("inconsistent row/column dimensions\n");
77             //os << ((Location)(*row)->getLocation()).getLocationString() << std::endl;
78             throw InternalError(os.str(), 999, (*row)->getLocation());
79         }
80     }
81
82     //alloc result cell
83     types::Cell *pC = new types::Cell(static_cast<int>(lines.size()), iColMax);
84
85     int i = 0;
86     int j = 0;
87
88     //insert items in cell
89     for (i = 0, row = lines.begin() ; row != lines.end() ; ++row, ++i)
90     {
91         exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
92         for (j = 0, col = cols.begin() ; col != cols.end() ; ++col, ++j)
93         {
94             (*col)->accept(*this);
95             types::InternalType *pIT = getResult();
96             if (pIT->isImplicitList())
97             {
98                 types::InternalType * _pIT = pIT->getAs<types::ImplicitList>()->extractFullMatrix();
99                 pC->set(i, j, _pIT);
100                 _pIT->killMe();
101             }
102             else
103             {
104                 pC->set(i, j, pIT);
105             }
106             clearResult();
107         }
108     }
109
110     //return new cell
111     setResult(pC);
112 }
113
114 template <class T>
115 void RunVisitorT<T>::visitprivate(const FieldExp &e)
116 {
117     /*
118       a.b
119     */
120
121     if (!e.getTail()->isSimpleVar())
122     {
123         wchar_t szError[bsiz];
124         os_swprintf(szError, bsiz, _W("/!\\ Unmanaged FieldExp.\n").c_str());
125         throw InternalError(szError, 999, e.getLocation());
126     }
127
128     try
129     {
130         e.getHead()->accept(*this);
131     }
132     catch (const InternalError& error)
133     {
134         throw error;
135     }
136
137     if (getResult() == NULL)
138     {
139         wchar_t szError[bsiz];
140         os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
141         throw InternalError(szError, 999, e.getLocation());
142     }
143
144     // TODO: handle case where getSize() > 1
145     // l=list(struct("toto","coucou"),struct("toto","hello"),1,2);[a,b]=l(1:2).toto
146     //
147     if (getResultSize() > 1)
148     {
149         clearResult();
150         wchar_t szError[bsiz];
151         os_swprintf(szError, bsiz, _W("Not yet implemented in Scilab.\n").c_str());
152         throw InternalError(szError, 999, e.getLocation());
153     }
154
155     SimpleVar * psvRightMember = static_cast<SimpleVar *>(const_cast<Exp *>(e.getTail()));
156     std::wstring wstField = psvRightMember->getSymbol().getName();
157     types::InternalType * pValue = getResult();
158     types::InternalType * pReturn = NULL;
159     bool ok = false;
160
161     try
162     {
163         if (pValue->isGenericType() || pValue->isUserType())
164         {
165             ok = pValue->getAs<types::GenericType>()->extract(wstField, pReturn);
166         }
167     }
168     catch (std::wstring & err)
169     {
170         pValue->killMe();
171         throw InternalError(err.c_str(), 999, e.getTail()->getLocation());
172     }
173
174     if (ok)
175     {
176         if (pReturn == NULL)
177         {
178             std::wostringstream os;
179             os << _W("Invalid index.\n");
180             throw InternalError(os.str(), 999, e.getLocation());
181         }
182
183         setResult(pReturn);
184         if (pValue->isDeletable())
185         {
186             if (pValue->isContainer())
187             {
188                 // prevent delete of pReturn in case where
189                 // extract not return a clone
190                 pReturn->IncreaseRef();
191                 pValue->killMe();
192                 pReturn->DecreaseRef();
193             }
194             else
195             {
196                 pValue->killMe();
197             }
198         }
199     }
200     else if (pValue->isFieldExtractionOverloadable())
201     {
202         types::typed_list in;
203         types::typed_list out;
204
205         types::String* pS = new types::String(wstField.c_str());
206
207         //TODO: in the case where overload is a macro there is no need to incref in
208         // because args will be put in context, removed and killed if required.
209         // But if the overload is a function... it is another story...
210
211         pS->IncreaseRef();
212         pValue->IncreaseRef();
213
214         in.push_back(pS);
215         in.push_back(pValue);
216         types::Callable::ReturnValue Ret = types::Callable::Error;
217         std::wstring stType = pValue->getShortTypeStr();
218
219         try
220         {
221             Ret = Overload::call(L"%" + stType + L"_e", in, 1, out, this);
222         }
223         catch (const InternalError& ie)
224         {
225             try
226             {
227                 //to compatibility with scilab 5 code.
228                 //tlist/mlist name are truncated to 8 first character
229                 if (stType.size() > 8)
230                 {
231                     Ret = Overload::call(L"%" + stType.substr(0, 8) + L"_e", in, 1, out, this);
232                 }
233                 else
234                 {
235                     throw ie;
236                 }
237             }
238             catch (const InternalError& ie)
239             {
240                 // TList or Mlist
241                 if (pValue->isList())
242                 {
243                     Ret = Overload::call(L"%l_e", in, 1, out, this);
244                 }
245                 else
246                 {
247                     throw ie;
248                 }
249             }
250         }
251
252         if (Ret != types::Callable::OK)
253         {
254             cleanInOut(in, out);
255             setResult(NULL);
256             throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
257         }
258
259         setResult(out);
260         cleanIn(in, out);
261     }
262     else
263     {
264         pValue->killMe();
265         wchar_t szError[bsiz];
266         os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
267         throw InternalError(szError, 999, e.getLocation());
268     }
269 }
270
271 template <class T>
272 void RunVisitorT<T>::visitprivate(const IfExp  &e)
273 {
274     //Create local exec visitor
275     ShortCutVisitor SCTest;
276     bool bTestStatus = false;
277
278     //condition
279     e.getTest().accept(SCTest);
280     e.getTest().accept(*this);
281
282     bTestStatus = getResult()->isTrue();
283     clearResult();
284     if (bTestStatus == true)
285     {
286         e.getThen().accept(*this);
287     }
288     else if (e.hasElse())
289     {
290         e.getElse().accept(*this);
291     }
292
293     if (e.isBreakable()
294             && ( (&e.getElse())->isBreak()
295                  || (&e.getThen())->isBreak() ))
296     {
297         const_cast<IfExp*>(&e)->setBreak();
298         const_cast<Exp*>(&e.getElse())->resetBreak();
299         const_cast<Exp*>(&e.getThen())->resetBreak();
300     }
301
302     if (e.isContinuable()
303             && ( (&e.getElse())->isContinue()
304                  || (&e.getThen())->isContinue() ))
305     {
306         const_cast<IfExp*>(&e)->setContinue();
307         const_cast<Exp*>(&e.getElse())->resetContinue();
308         const_cast<Exp*>(&e.getThen())->resetContinue();
309     }
310
311     if (e.isReturnable()
312             && ( (&e.getElse())->isReturn()
313                  || (&e.getThen())->isReturn() ))
314     {
315         const_cast<IfExp*>(&e)->setReturn();
316         const_cast<Exp*>(&e.getElse())->resetReturn();
317         const_cast<Exp*>(&e.getThen())->resetReturn();
318     }
319 }
320
321 template <class T>
322 void RunVisitorT<T>::visitprivate(const WhileExp  &e)
323 {
324
325     //Create local exec visitor
326     ShortCutVisitor SCTest;
327
328     //manage & and | like && and ||
329     e.getTest().accept(SCTest);
330     //condition
331     e.getTest().accept(*this);
332
333     types::InternalType* pIT = getResult();
334
335     while (pIT->isTrue())
336     {
337         pIT->killMe();
338         e.getBody().accept(*this);
339
340         //clear old result value before evaluate new one
341         if (getResult() != NULL)
342         {
343             getResult()->killMe();
344         }
345
346         if (e.getBody().isBreak())
347         {
348             const_cast<Exp*>(&(e.getBody()))->resetBreak();
349             break;
350         }
351
352         if (e.getBody().isReturn())
353         {
354             const_cast<WhileExp*>(&e)->setReturn();
355             const_cast<Exp*>(&(e.getBody()))->resetReturn();
356             break;
357         }
358
359         if (e.getBody().isContinue())
360         {
361             const_cast<Exp*>(&(e.getBody()))->resetContinue();
362         }
363
364         e.getTest().accept(*this);
365         pIT = getResult();
366     }
367
368     //pIT->killMe();
369     //clear result of condition or result of body
370     clearResult();
371 }
372
373 template <class T>
374 void RunVisitorT<T>::visitprivate(const ForExp  &e)
375 {
376     symbol::Context* ctx = symbol::Context::getInstance();
377     //vardec visit increase its result reference
378     e.getVardec().accept(*this);
379     types::InternalType* pIT = getResult();
380
381     if (pIT->isImplicitList())
382     {
383         //get IL
384         types::ImplicitList* pVar = pIT->getAs<types::ImplicitList>();
385         //get IL initial Type
386         types::InternalType * pIL = pVar->getInitalType();
387         //std::cout << "for IL: " << pIL << std::endl;
388         //std::cout << "  for IV: " << pIT << std::endl;
389         //get index stack
390         symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
391
392         if (ctx->isprotected(var))
393         {
394             std::wostringstream os;
395             os << _W("Redefining permanent variable.\n");
396             throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
397         }
398
399         ctx->put(var, pIL);
400         //use ref count to lock var against clear and detect any changes
401         pIL->IncreaseRef();
402
403         int size = static_cast<int>(pVar->getSize());
404         for (int i = 0; i < size; ++i)
405         {
406             //check if loop index has changed, deleted, copy ...
407             if (pIL->getRef() != 2)
408             {
409                 switch (pIL->getRef())
410                 {
411                     case 1:
412                         //someone clear me
413                         ctx->put(var, pIL);
414                         break;
415                     default:
416                         //someone assign me to another var
417                         //a = i;
418                         //unlock me
419                         pIL->DecreaseRef();
420
421                         //no need to destroy, it already assign to another var
422                         //pIL->killMe();
423
424                         //create a new me
425                         pIL = pVar->getInitalType();
426                         //lock loop index
427                         pIL->IncreaseRef();
428                         //update me ( must decrease ref of a )
429                         if (ctx->isprotected(var))
430                         {
431                             std::wostringstream os;
432                             os << _W("Redefining permanent variable.\n");
433                             throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
434                         }
435
436                         ctx->put(var, pIL);
437                         break;
438                 }
439             }
440
441             pVar->extractValue(i, pIL);
442
443             try
444             {
445                 e.getBody().accept(*this);
446             }
447             catch (const InternalError& ie)
448             {
449                 //unlock loop index and implicit list
450                 pIL->DecreaseRef();
451                 pIL->killMe();
452                 pIT->DecreaseRef();
453                 pIT->killMe();
454
455                 setResult(NULL);
456                 throw ie;
457             }
458
459             if (e.getBody().isBreak())
460             {
461                 const_cast<Exp&>(e.getBody()).resetBreak();
462                 break;
463             }
464
465             if (e.getBody().isContinue())
466             {
467                 const_cast<Exp&>(e.getBody()).resetContinue();
468                 continue;
469             }
470
471             if (e.getBody().isReturn())
472             {
473                 const_cast<ForExp&>(e).setReturn();
474                 const_cast<Exp&>(e.getBody()).resetReturn();
475                 break;
476             }
477         }
478
479         //unlock loop index
480         pIL->DecreaseRef();
481         pIL->killMe();
482     }
483     else if (pIT->isList())
484     {
485         types::List* pL = pIT->getAs<types::List>();
486         const int size = pL->getSize();
487         symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
488         for (int i = 0; i < size; ++i)
489         {
490             types::InternalType* pNew = pL->get(i);
491
492             if (ctx->isprotected(var))
493             {
494                 std::wostringstream os;
495                 os << _W("Redefining permanent variable.\n");
496                 throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
497             }
498             ctx->put(var, pNew);
499
500             try
501             {
502                 e.getBody().accept(*this);
503             }
504             catch (const InternalError& ie)
505             {
506                 //implicit list
507                 pIT->DecreaseRef();
508                 pIT->killMe();
509                 setResult(NULL);
510                 throw ie;
511             }
512
513             if (e.getBody().isBreak())
514             {
515                 const_cast<Exp*>(&(e.getBody()))->resetBreak();
516                 break;
517             }
518
519             if (e.getBody().isContinue())
520             {
521                 const_cast<Exp*>(&(e.getBody()))->resetContinue();
522                 continue;
523             }
524
525             if (e.getBody().isReturn())
526             {
527                 const_cast<ForExp*>(&e)->setReturn();
528                 const_cast<Exp&>(e.getBody()).resetReturn();
529                 break;
530             }
531         }
532     }
533     else if (pIT->isGenericType())
534     {
535         //Matrix i = [1,3,2,6] or other type
536         types::GenericType* pVar = pIT->getAs<types::GenericType>();
537         if (pVar->getDims() > 2)
538         {
539             pIT->DecreaseRef();
540             pIT->killMe();
541             throw InternalError(_W("for expression can only manage 1 or 2 dimensions variables\n"), 999, e.getVardec().getLocation());
542         }
543
544         symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
545         for (int i = 0; i < pVar->getCols(); i++)
546         {
547             types::GenericType* pNew = pVar->getColumnValues(i);
548             if (pNew == NULL)
549             {
550                 pIT->DecreaseRef();
551                 pIT->killMe();
552                 throw InternalError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
553             }
554
555             if (ctx->isprotected(var))
556             {
557                 std::wostringstream os;
558                 os << _W("Redefining permanent variable.\n");
559                 throw InternalError(os.str(), 999, e.getVardec().getLocation());
560             }
561             ctx->put(var, pNew);
562
563             try
564             {
565                 e.getBody().accept(*this);
566             }
567             catch (const InternalError& ie)
568             {
569                 //implicit list
570                 pIT->DecreaseRef();
571                 pIT->killMe();
572                 setResult(NULL);
573                 throw ie;
574             }
575
576             if (e.getBody().isBreak())
577             {
578                 const_cast<Exp*>(&(e.getBody()))->resetBreak();
579                 break;
580             }
581
582             if (e.getBody().isContinue())
583             {
584                 const_cast<Exp*>(&(e.getBody()))->resetContinue();
585                 continue;
586             }
587
588             if (e.getBody().isReturn())
589             {
590                 const_cast<ForExp*>(&e)->setReturn();
591                 const_cast<Exp&>(e.getBody()).resetReturn();
592                 break;
593             }
594         }
595     }
596     else
597     {
598         pIT->DecreaseRef();
599         pIT->killMe();
600         throw InternalError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
601     }
602
603     pIT->DecreaseRef();
604     pIT->killMe();
605
606     setResult(NULL);
607 }
608
609 template <class T>
610 void RunVisitorT<T>::visitprivate(const ReturnExp &e)
611 {
612     if (e.isGlobal())
613     {
614         if (ConfigVariable::getPauseLevel() != 0 && symbol::Context::getInstance()->getScopeLevel() == ConfigVariable::getActivePauseLevel())
615         {
616             if (ConfigVariable::getEnableDebug() == true)
617             {
618                 sciprint(_("%s: function is disable in debug mode.\n"), "resume");
619                 return;
620             }
621
622             //return or resume
623             ConfigVariable::DecreasePauseLevel();
624             return;
625         }
626         else
627         {
628             const_cast<ReturnExp*>(&e)->setReturn();
629         }
630     }
631     else
632     {
633         //return(x)
634
635         //in case of CallExp, we can return only one values
636         int iSaveExpectedSize = getExpectedSize();
637         setExpectedSize(1);
638         e.getExp().accept(*this);
639         setExpectedSize(iSaveExpectedSize);
640         const_cast<ReturnExp*>(&e)->setReturn();
641     }
642 }
643
644 template <class T>
645 void RunVisitorT<T>::visitprivate(const IntSelectExp &e)
646 {
647     bool found = false;
648     //e.getSelect()->accept(*this);
649     //InternalType* pIT = getResult();
650     //setResult(nullptr);
651     //if (pIT && pIT->isDouble())
652     //{
653     //    Double * pDbl = static_cast<Double *>(pIT);
654     //    if (!pDbl->isComplex() && pDbl->getSize() == 1)
655     //    {
656     //        int64_t val;
657     //        if (analysis::tools::asInteger<int64_t>(pDbl->get(0), val))
658     //        {
659     //            Exp * exp = e.getExp(val);
660     //            found = true;
661     //            if (exp)
662     //            {
663     //                Exp * body = exp->isCaseExp() ? exp->getAs<CaseExp>()->getBody() : exp;
664     //                if (e.isBreakable())
665     //                {
666     //                    const_cast<IntSelectExp*>(&e)->resetBreak();
667     //                    body->setBreakable();
668     //                }
669
670     //                if (e.isContinuable())
671     //                {
672     //                    const_cast<IntSelectExp*>(&e)->resetContinue();
673     //                    body->setContinuable();
674     //                }
675
676     //                if (e.isReturnable())
677     //                {
678     //                    const_cast<IntSelectExp*>(&e)->resetReturn();
679     //                    body->setReturnable();
680     //                }
681
682     //                try
683     //                {
684     //                    //the good one
685     //                    body->accept(*this);
686     //                }
687     //                catch (const InternalError& ie)
688     //                {
689     //                    pIT->killMe();
690     //                    throw ie;
691     //                }
692
693     //                if (e.isBreakable() && body->isBreak())
694     //                {
695     //                    const_cast<IntSelectExp*>(&e)->setBreak();
696     //                    body->resetBreak();
697     //                }
698
699     //                if (e.isContinuable() && body->isContinue())
700     //                {
701     //                    const_cast<IntSelectExp*>(&e)->setContinue();
702     //                    body->resetContinue();
703     //                }
704
705     //                if (e.isReturnable() && body->isReturn())
706     //                {
707     //                    const_cast<IntSelectExp*>(&e)->setReturn();
708     //                    body->resetReturn();
709     //                }
710     //            }
711     //        }
712     //    }
713     //}
714
715     if (!found)
716     {
717         e.getOriginal()->accept(*this);
718     }
719 }
720
721 template <class T>
722 void RunVisitorT<T>::visitprivate(const StringSelectExp &e)
723 {
724     e.getSelect()->accept(*this);
725     types::InternalType* pIT = getResult();
726     setResult(nullptr);
727     bool found = false;
728     if (pIT && pIT->isString())
729     {
730         types::String * pStr = static_cast<types::String *>(pIT);
731         if (pStr->getSize() == 1)
732         {
733             if (wchar_t * s = pStr->get(0))
734             {
735                 const std::wstring ws(s);
736                 Exp * exp = e.getExp(ws);
737                 found = true;
738                 if (exp)
739                 {
740                     Exp * body = exp->isCaseExp() ? exp->getAs<CaseExp>()->getBody() : exp;
741                     if (e.isBreakable())
742                     {
743                         const_cast<StringSelectExp*>(&e)->resetBreak();
744                         body->setBreakable();
745                     }
746
747                     if (e.isContinuable())
748                     {
749                         const_cast<StringSelectExp*>(&e)->resetContinue();
750                         body->setContinuable();
751                     }
752
753                     if (e.isReturnable())
754                     {
755                         const_cast<StringSelectExp*>(&e)->resetReturn();
756                         body->setReturnable();
757                     }
758
759                     try
760                     {
761                         //the good one
762                         body->accept(*this);
763                     }
764                     catch (const InternalError& ie)
765                     {
766                         pIT->killMe();
767                         throw ie;
768                     }
769
770                     if (e.isBreakable() && body->isBreak())
771                     {
772                         const_cast<StringSelectExp*>(&e)->setBreak();
773                         body->resetBreak();
774                     }
775
776                     if (e.isContinuable() && body->isContinue())
777                     {
778                         const_cast<StringSelectExp*>(&e)->setContinue();
779                         body->resetContinue();
780                     }
781
782                     if (e.isReturnable() && body->isReturn())
783                     {
784                         const_cast<StringSelectExp*>(&e)->setReturn();
785                         body->resetReturn();
786                     }
787                 }
788             }
789         }
790     }
791
792     if (!found)
793     {
794         e.getOriginal()->accept(*this);
795     }
796 }
797
798 template <class T>
799 void RunVisitorT<T>::visitprivate(const SelectExp &e)
800 {
801     // FIXME : exec select ... case ... else ... end
802     e.getSelect()->accept(*this);
803     bool bCase = false;
804
805     types::InternalType* pIT = getResult();
806     setResult(NULL);
807     if (pIT)
808     {
809         // protect pIT to avoid double free when
810         // the variable in select is override in the case
811         pIT->IncreaseRef();
812
813         //find good case
814         exps_t cases = e.getCases();
815         for (auto exp : cases)
816         {
817             CaseExp* pCase = exp->getAs<CaseExp>();
818             pCase->getTest()->accept(*this);
819             types::InternalType *pITCase = getResult();
820             setResult(NULL);
821             if (pITCase)
822             {
823                 if (pITCase->isContainer()) //WARNING ONLY FOR CELL
824                 {
825                     //check each item
826                 }
827                 else if (*pITCase == *pIT)
828                 {
829                     try
830                     {
831                         //the good one
832                         pCase->getBody()->accept(*this);
833                     }
834                     catch (const InternalError& ie)
835                     {
836                         pIT->DecreaseRef();
837                         pIT->killMe();
838                         throw ie;
839                     }
840
841                     if (e.isBreakable() && pCase->getBody()->isBreak())
842                     {
843                         const_cast<SelectExp*>(&e)->setBreak();
844                         pCase->getBody()->resetBreak();
845                     }
846
847                     if (e.isContinuable() && pCase->getBody()->isContinue())
848                     {
849                         const_cast<SelectExp*>(&e)->setContinue();
850                         pCase->getBody()->resetContinue();
851                     }
852
853                     if (e.isReturnable() && pCase->getBody()->isReturn())
854                     {
855                         const_cast<SelectExp*>(&e)->setReturn();
856                         pCase->getBody()->resetReturn();
857                     }
858
859                     pITCase->killMe();
860                     bCase = true;
861                     break;
862                 }
863
864                 pITCase->killMe();
865             }
866         }
867     }
868
869     if (bCase == false && e.getDefaultCase() != NULL)
870     {
871         try
872         {
873             //default case
874             e.getDefaultCase()->accept(*this);
875         }
876         catch (const InternalError& ie)
877         {
878             if (pIT)
879             {
880                 pIT->DecreaseRef();
881                 pIT->killMe();
882             }
883             throw ie;
884         }
885
886         if (e.isBreakable() && e.getDefaultCase()->isBreak())
887         {
888             const_cast<SelectExp*>(&e)->setBreak();
889             e.getDefaultCase()->resetBreak();
890         }
891
892         if (e.isContinuable() && e.getDefaultCase()->isContinue())
893         {
894             const_cast<SelectExp*>(&e)->setContinue();
895             e.getDefaultCase()->resetContinue();
896         }
897
898         if (e.isReturnable() && e.getDefaultCase()->isReturn())
899         {
900             const_cast<SelectExp*>(&e)->setReturn();
901             e.getDefaultCase()->resetReturn();
902         }
903     }
904
905     clearResult();
906
907     if (pIT)
908     {
909         pIT->DecreaseRef();
910         pIT->killMe();
911     }
912 }
913
914 template <class T>
915 void RunVisitorT<T>::visitprivate(const SeqExp  &e)
916 {
917     for (auto exp : e.getExps())
918     {
919         if (exp->isCommentExp())
920         {
921             continue;
922         }
923
924         if (ConfigVariable::isExecutionBreak())
925         {
926             ConfigVariable::resetExecutionBreak();
927             StorePrioritaryCommand("pause");
928         }
929
930         // interrupt me to execute a prioritary command
931         while (StaticRunner_isInterruptibleCommand() == 1 && StaticRunner_isRunnerAvailable() == 1)
932         {
933             StaticRunner_launch();
934             StaticRunner_setInterruptibleCommand(1);
935         }
936
937         try
938         {
939             //reset default values
940             setResult(NULL);
941             int iExpectedSize = getExpectedSize();
942             setExpectedSize(-1);
943             exp->accept(*this);
944             setExpectedSize(iExpectedSize);
945             types::InternalType * pIT = getResult();
946
947             // In case of exec file, set the file name in the Macro to store where it is defined.
948             int iFileID = ConfigVariable::getExecutedFileID();
949             if (iFileID && exp->isFunctionDec())
950             {
951                 types::InternalType* pITMacro = symbol::Context::getInstance()->get(exp->getAs<FunctionDec>()->getSymbol());
952                 if (pITMacro)
953                 {
954                     types::Macro* pMacro = pITMacro->getAs<types::Macro>();
955                     const wchar_t* filename = getfile_filename(iFileID);
956                     // scilab.quit is not open with mopen
957                     // in this case filename is NULL because FileManager have not been filled.
958                     if (filename)
959                     {
960                         pMacro->setFileName(filename);
961                     }
962                 }
963             }
964
965             if (pIT != NULL)
966             {
967                 bool bImplicitCall = false;
968                 if (pIT->isCallable()) //to manage call without ()
969                 {
970                     types::Callable *pCall = pIT->getAs<types::Callable>();
971                     types::typed_list out;
972                     types::typed_list in;
973                     types::optional_list opt;
974
975                     try
976                     {
977                         //in this case of calling, we can return only one values
978                         int iSaveExpectedSize = getExpectedSize();
979                         setExpectedSize(1);
980
981                         pCall->invoke(in, opt, getExpectedSize(), out, e);
982                         setExpectedSize(iSaveExpectedSize);
983
984                         if (out.size() == 0)
985                         {
986                             setResult(NULL);
987                         }
988                         else
989                         {
990                             setResult(out[0]);
991                         }
992
993                         bImplicitCall = true;
994                     }
995                     catch (const InternalError& ie)
996                     {
997                         if (ConfigVariable::getLastErrorFunction() == L"")
998                         {
999                             ConfigVariable::setLastErrorFunction(pCall->getName());
1000                             ConfigVariable::setLastErrorLine(e.getLocation().first_line);
1001                         }
1002
1003                         throw ie;
1004                     }
1005                 }
1006
1007                 //don't output Simplevar and empty result
1008                 if (getResult() != NULL && (!exp->isSimpleVar() || bImplicitCall))
1009                 {
1010                     //symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), *execMe.getResult());
1011                     types::InternalType* pITAns = getResult();
1012                     symbol::Context::getInstance()->put(m_pAns, pITAns);
1013                     if (exp->isVerbose() && ConfigVariable::isPromptShow())
1014                     {
1015                         //TODO manage multiple returns
1016                         scilabWriteW(L" ans  =\n\n");
1017                         std::wostringstream ostrName;
1018                         ostrName << L"ans";
1019                         VariableToString(pITAns, ostrName.str().c_str());
1020                     }
1021                 }
1022
1023                 pIT->killMe();
1024             }
1025
1026             if ((&e)->isBreakable() && exp->isBreak())
1027             {
1028                 const_cast<SeqExp *>(&e)->setBreak();
1029                 exp->resetBreak();
1030                 break;
1031             }
1032
1033             if ((&e)->isContinuable() && exp->isContinue())
1034             {
1035                 const_cast<SeqExp *>(&e)->setContinue();
1036                 exp->resetContinue();
1037                 break;
1038             }
1039
1040             if ((&e)->isReturnable() && exp->isReturn())
1041             {
1042                 const_cast<SeqExp *>(&e)->setReturn();
1043                 exp->resetReturn();
1044                 break;
1045             }
1046         }
1047         catch (const InternalError& ie)
1048         {
1049             ConfigVariable::fillWhereError(ie.GetErrorLocation().first_line);
1050             throw ie;
1051         }
1052
1053         // If something other than NULL is given to setResult, then that would imply
1054         // to make a cleanup in visit(ForExp) for example (e.getBody().accept(*this);)
1055         setResult(NULL);
1056     }
1057 }
1058
1059 template <class T>
1060 void RunVisitorT<T>::visitprivate(const NotExp &e)
1061 {
1062     /*
1063       @ or ~ !
1064     */
1065     e.getExp().accept(*this);
1066
1067     types::InternalType * pValue = getResult();
1068     types::InternalType * pReturn = NULL;
1069     if (pValue->neg(pReturn))
1070     {
1071         if (pValue != pReturn)
1072         {
1073             pValue->killMe();
1074         }
1075
1076         setResult(pReturn);
1077     }
1078     else
1079     {
1080         // neg returned false so the negation is not possible so we call the overload (%foo_5)
1081         types::typed_list in;
1082         types::typed_list out;
1083
1084         pValue->IncreaseRef();
1085         in.push_back(pValue);
1086
1087         types::Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_5", in, 1, out, this);
1088
1089         if (Ret != types::Callable::OK)
1090         {
1091             cleanInOut(in, out);
1092             throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1093         }
1094
1095         setResult(out);
1096         cleanIn(in, out);
1097     }
1098 }
1099
1100 template <class T>
1101 void RunVisitorT<T>::visitprivate(const TransposeExp &e)
1102 {
1103     e.getExp().accept(*this);
1104
1105     if (getResultSize() != 1)
1106     {
1107         clearResult();
1108         wchar_t szError[bsiz];
1109         os_swprintf(szError, bsiz, _W("%ls: Can not transpose multiple elements.\n").c_str(), L"Transpose");
1110         throw InternalError(szError, 999, e.getLocation());
1111     }
1112
1113     types::InternalType * pValue = getResult();
1114     types::InternalType * pReturn = NULL;
1115     const bool bConjug = e.getConjugate() == TransposeExp::_Conjugate_;
1116
1117     if ((bConjug && pValue->adjoint(pReturn)) || (!bConjug && pValue->transpose(pReturn)))
1118     {
1119         if (pValue != pReturn)
1120         {
1121             pValue->killMe();
1122         }
1123
1124         setResult(pReturn);
1125
1126         return;
1127     }
1128     else
1129     {
1130         // transpose returned false so the negation is not possible so we call the overload (%foo_t or %foo_0)
1131         types::typed_list in;
1132         types::typed_list out;
1133
1134         pValue->IncreaseRef();
1135         in.push_back(pValue);
1136
1137         types::Callable::ReturnValue Ret;
1138         if (bConjug)
1139         {
1140             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_t", in, 1, out, this);
1141         }
1142         else
1143         {
1144             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_0", in, 1, out, this);
1145         }
1146
1147         if (Ret != types::Callable::OK)
1148         {
1149             cleanInOut(in, out);
1150             throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1151         }
1152
1153         setResult(out);
1154         cleanIn(in, out);
1155     }
1156 }
1157
1158 template <class T>
1159 void RunVisitorT<T>::visitprivate(const FunctionDec & e)
1160 {
1161     symbol::Context* ctx = symbol::Context::getInstance();
1162     /*
1163       function foo
1164       endfunction
1165     */
1166
1167     // funcprot(0) : do nothing
1168     // funcprot(1) && warning(on) : warning
1169     //get input parameters list
1170     std::list<symbol::Variable*> *pVarList = new std::list<symbol::Variable*>();
1171     const exps_t & vars = e.getArgs().getVars();
1172     for (const auto var : vars)
1173     {
1174         pVarList->push_back(var->getAs<SimpleVar>()->getStack());
1175     }
1176
1177     //get output parameters list
1178     std::list<symbol::Variable*> *pRetList = new std::list<symbol::Variable*>();
1179     const exps_t & rets = e.getReturns().getVars();
1180     for (const auto ret : rets)
1181     {
1182         pRetList->push_back(ret->getAs<SimpleVar>()->getStack());
1183     }
1184
1185     types::Macro *pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList,
1186                                             const_cast<SeqExp&>(static_cast<const SeqExp&>(e.getBody())), L"script");
1187     pMacro->setLines(e.getLocation().first_line, e.getLocation().last_line);
1188
1189     bool bEquals = false;
1190     int iFuncProt = ConfigVariable::getFuncprot();
1191     if (iFuncProt != 0)
1192     {
1193         types::InternalType* pITFunc = ctx->get(((FunctionDec&)e).getStack());
1194         if (pITFunc && pITFunc->isCallable())
1195         {
1196             if (pITFunc->isMacroFile())
1197             {
1198                 types::MacroFile* pMF = pITFunc->getAs<types::MacroFile>();
1199                 bEquals = *pMF->getMacro() == *pMacro;
1200             }
1201             else if (pITFunc->isMacro())
1202             {
1203                 types::Macro* pM = pITFunc->getAs<types::Macro>();
1204                 bEquals = *pM == *pMacro;
1205             }
1206         }
1207         else
1208         {
1209             bEquals = true; //avoid msg but keep assignation
1210         }
1211     }
1212
1213     if (bEquals == false && iFuncProt == 1 && ConfigVariable::getWarningMode())
1214     {
1215         wchar_t pwstFuncName[1024];
1216         os_swprintf(pwstFuncName, 1024, L"%-24ls", e.getSymbol().getName().c_str());
1217         char* pstFuncName = wide_string_to_UTF8(pwstFuncName);
1218
1219
1220         sciprint(_("Warning : redefining function: %s. Use funcprot(0) to avoid this message"), pstFuncName);
1221         sciprint("\n");
1222         FREE(pstFuncName);
1223     }
1224     else if (bEquals == false && iFuncProt == 2)
1225     {
1226         char pstError[1024];
1227         char* pstFuncName = wide_string_to_UTF8(e.getSymbol().getName().c_str());
1228         os_sprintf(pstError, _("It is not possible to redefine the %s primitive this way (see clearfun).\n"), pstFuncName);
1229         wchar_t* pwstError = to_wide_string(pstError);
1230         std::wstring wstError(pwstError);
1231         FREE(pstFuncName);
1232         FREE(pwstError);
1233         delete pMacro;
1234         throw InternalError(wstError, 999, e.getLocation());
1235     }
1236
1237
1238     if (ctx->isprotected(symbol::Symbol(pMacro->getName())))
1239     {
1240         delete pMacro;
1241         std::wostringstream os;
1242         os << _W("Redefining permanent variable.\n");
1243         throw InternalError(os.str(), 999, e.getLocation());
1244     }
1245
1246     ctx->addMacro(pMacro);
1247
1248 }
1249
1250 template <class T>
1251 void RunVisitorT<T>::visitprivate(const ListExp &e)
1252 {
1253     e.getStart().accept(*this);
1254     types::GenericType* pITStart = static_cast<types::GenericType*>(getResult());
1255     if ((pITStart->getSize() != 1 || (pITStart->isDouble() && pITStart->getAs<types::Double>()->isComplex())) &&
1256             pITStart->isList() == false) // list case => call overload
1257     {
1258         pITStart->killMe();
1259         wchar_t szError[bsiz];
1260         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 1);
1261         throw InternalError(szError, 999, e.getLocation());
1262     }
1263     types::InternalType * piStart = pITStart;
1264
1265     e.getStep().accept(*this);
1266     types::GenericType* pITStep = static_cast<types::GenericType*>(getResult());
1267     if ((pITStep->getSize() != 1 || (pITStep->isDouble() && pITStep->getAs<types::Double>()->isComplex())) &&
1268             pITStep->isList() == false) // list case => call overload
1269     {
1270         pITStart->killMe();
1271         pITStep->killMe();
1272         wchar_t szError[bsiz];
1273         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2);
1274         throw InternalError(szError, 999, e.getLocation());
1275     }
1276     types::InternalType* piStep = pITStep;
1277
1278     e.getEnd().accept(*this);
1279     types::GenericType* pITEnd = static_cast<types::GenericType*>(getResult());
1280     if ((pITEnd->getSize() != 1 || (pITEnd->isDouble() && pITEnd->getAs<types::Double>()->isComplex())) &&
1281             pITEnd->isList() == false) // list case => call overload
1282     {
1283         pITStart->killMe();
1284         pITStep->killMe();
1285         pITEnd->killMe();
1286         wchar_t szError[bsiz];
1287         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 3);
1288         throw InternalError(szError, 999, e.getLocation());
1289     }
1290     types::InternalType* piEnd = pITEnd;
1291
1292     ////check if implicitlist is 1:$ to replace by ':'
1293     //if (piStart->isDouble() && piStep->isDouble() && piEnd->isPoly())
1294     //{
1295     //    if (piStart->getAs<Double>()->get()[0] == 1 && piStep->getAs<Double>()->get()[0] == 1)
1296     //    {
1297     //        SinglePoly* end = piEnd->getAs<Polynom>()->get()[0];
1298     //        if (end->getRank() == 1 && end->get()[0] == 0 && end->get()[1] == 1)
1299     //        {
1300     //            setResult(new Colon());
1301     //            return;
1302     //        }
1303     //    }
1304     //}
1305
1306     //check compatibility
1307     // double : double : double or poly : poly : poly and mix like double : double : poly
1308     if ((piStart->isPoly() || piStart->isDouble()) &&
1309             (piStep->isPoly()  || piStep->isDouble())  &&
1310             (piEnd->isPoly()   || piEnd->isDouble()))
1311     {
1312         // No need to kill piStart, ... because Implicit list ctor will incref them
1313         setResult(new types::ImplicitList(piStart, piStep, piEnd));
1314         return;
1315     }
1316
1317     // int : double or int : int
1318     if ( piStart->isInt()   &&
1319             (piStep->isDouble() || piStep->isInt()) &&
1320             piEnd->isInt())
1321     {
1322         // check for same int type int8, int 16 ...
1323         if (piStart->getType() == piEnd->getType()  &&
1324                 (piStart->getType() == piStep->getType() ||
1325                  piStep->isDouble()))
1326         {
1327             // No need to kill piStart, ... because Implicit list ctor will incref them
1328             setResult(new types::ImplicitList(piStart, piStep, piEnd));
1329             return;
1330         }
1331     }
1332
1333     // Call Overload
1334     types::Callable::ReturnValue Ret;
1335     types::typed_list in;
1336     types::typed_list out;
1337
1338     piStart->IncreaseRef();
1339     in.push_back(piStart);
1340
1341     try
1342     {
1343         if (e.hasExplicitStep())
1344         {
1345             // 1:2:4
1346             //call overload %typeStart_b_typeStep
1347             piStep->IncreaseRef();
1348             in.push_back(piStep);
1349             piEnd->IncreaseRef();
1350             in.push_back(piEnd);
1351             Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piStep->getShortTypeStr(), in, 1, out, true);
1352         }
1353         else
1354         {
1355             // 1:2
1356             //call overload %typeStart_b_typeEnd
1357             piStep->killMe();
1358             piEnd->IncreaseRef();
1359             in.push_back(piEnd);
1360             Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piEnd->getShortTypeStr(), in, 1, out, true);
1361         }
1362     }
1363     catch (const InternalError& error)
1364     {
1365         cleanInOut(in, out);
1366         throw error;
1367     }
1368
1369     if (Ret != types::Callable::OK)
1370     {
1371         cleanInOut(in, out);
1372         throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1373     }
1374
1375     setResult(out);
1376     cleanIn(in, out);
1377 }
1378
1379 template <class T>
1380 void RunVisitorT<T>::visitprivate(const OptimizedExp &e)
1381 {
1382 }
1383
1384 template <class T>
1385 void RunVisitorT<T>::visitprivate(const MemfillExp &e)
1386 {
1387     e.getOriginal()->accept(*this);
1388 }
1389
1390 template <class T>
1391 void RunVisitorT<T>::visitprivate(const DAXPYExp &e)
1392 {
1393     types::InternalType* pIT = NULL;
1394     types::Double* ad = NULL;
1395     int ar = 0;
1396     int ac = 0;
1397
1398     types::Double* xd = NULL;
1399     int xr = 0;
1400     int xc = 0;
1401
1402     types::Double* yd = NULL;
1403     int yr = 0;
1404     int yc = 0;
1405
1406     //check types and dimensions
1407
1408     //y must be double
1409     const Exp &ye = e.getY();
1410     ye.accept(*this);
1411     pIT = getResult();
1412     if (pIT->isDouble())
1413     {
1414         yd = pIT->getAs<types::Double>();
1415         if (yd->getDims() == 2 && yd->isComplex() == false)
1416         {
1417             yr = yd->getRows();
1418             yc = yd->getCols();
1419         }
1420         else
1421         {
1422             yd->killMe();
1423             e.getOriginal()->accept(*this);
1424             return;
1425         }
1426     }
1427     else
1428     {
1429         pIT->killMe();
1430         e.getOriginal()->accept(*this);
1431         return;
1432     }
1433
1434     //x
1435     const Exp &xe = e.getX();
1436     xe.accept(*this);
1437     pIT = getResult();
1438
1439     if (pIT->isDouble())
1440     {
1441         xd = pIT->getAs<types::Double>();
1442         if (xd->isScalar() && xd->isComplex() == false)
1443         {
1444             // x become a
1445             ad = xd;
1446             ar = 1;
1447             ac = 1;
1448         }
1449         else if (xd->getDims() == 2 && xd->isComplex() == false)
1450         {
1451             xr = xd->getRows();
1452             xc = xd->getCols();
1453         }
1454         else
1455         {
1456             yd->killMe();
1457             xd->killMe();
1458             e.getOriginal()->accept(*this);
1459             return;
1460         }
1461     }
1462     else
1463     {
1464         pIT->killMe();
1465         yd->killMe();
1466         e.getOriginal()->accept(*this);
1467         return;
1468     }
1469
1470     const Exp &ae = e.getA();
1471     ae.accept(*this);
1472     pIT = getResult();
1473
1474     if (pIT->isDouble())
1475     {
1476         if (ad)
1477         {
1478             xd = pIT->getAs<types::Double>();
1479             //X is scalar it become A
1480             //now use A as X
1481             if (xd->getDims() == 2 && xd->isComplex() == false)
1482             {
1483                 xr = xd->getRows();
1484                 xc = xd->getCols();
1485             }
1486             else
1487             {
1488                 yd->killMe();
1489                 xd->killMe();
1490                 ad->killMe();
1491                 e.getOriginal()->accept(*this);
1492                 return;
1493             }
1494         }
1495         else
1496         {
1497             //a is a and it must be scalar
1498             ad = pIT->getAs<types::Double>();
1499             if (/*ad->isScalar() && */ad->isComplex() == false)
1500             {
1501                 ar = ad->getRows(); //1;
1502                 ac = ad->getCols();//1;
1503             }
1504             else
1505             {
1506                 yd->killMe();
1507                 xd->killMe();
1508                 ad->killMe();
1509                 e.getOriginal()->accept(*this);
1510                 return;
1511             }
1512         }
1513     }
1514     else
1515     {
1516         pIT->killMe();
1517         yd->killMe();
1518         xd->killMe();
1519         e.getOriginal()->accept(*this);
1520         return;
1521     }
1522
1523     if (ad && xd && yd)
1524     {
1525         if ( ac == 1 &&
1526                 ar == 1 &&
1527                 xr == yr &&
1528                 xc == yc)
1529         {
1530             //go !
1531             int one = 1;
1532             int size = xc * xr;
1533             //Double* od = (Double*)yd->clone();
1534             C2F(daxpy)(&size, ad->get(), xd->get(), &one, yd->get(), &one);
1535             //setResult(od);
1536             //yd->killMe();
1537             xd->killMe();
1538             ad->killMe();
1539             return;
1540         }
1541         else if (ac == xr && ar == yr && xc == yc)
1542         {
1543             char n = 'n';
1544             double one = 1;
1545             C2F(dgemm)(&n, &n, &ar, &xc, &ac, &one, ad->get(), &ar, xd->get(), &ac, &one, yd->get(), &ar);
1546             xd->killMe();
1547             ad->killMe();
1548             return;
1549         }
1550     }
1551
1552     if (yd)
1553     {
1554         yd->killMe();
1555     }
1556
1557     if (xd)
1558     {
1559         xd->killMe();
1560     }
1561
1562     if (ad)
1563     {
1564         ad->killMe();
1565     }
1566
1567     e.getOriginal()->accept(*this);
1568     return;
1569 }
1570
1571 template <class T>
1572 void RunVisitorT<T>::visitprivate(const TryCatchExp  &e)
1573 {
1574     //save current prompt mode
1575     int oldVal = ConfigVariable::getSilentError();
1576     int oldMode = ConfigVariable::getPromptMode();
1577     //set mode silent for errors
1578     ConfigVariable::setSilentError(1);
1579
1580     symbol::Context* pCtx = symbol::Context::getInstance();
1581     try
1582     {
1583         int scope = pCtx->getScopeLevel();
1584         int level = ConfigVariable::getRecursionLevel();
1585         try
1586         {
1587             e.getTry().accept(*this);
1588             //restore previous prompt mode
1589             ConfigVariable::setSilentError(oldVal);
1590         }
1591         catch (const RecursionException& /* re */)
1592         {
1593             ConfigVariable::setPromptMode(oldMode);
1594
1595             //close opened scope during try
1596             while (pCtx->getScopeLevel() > scope)
1597             {
1598                 pCtx->scope_end();
1599             }
1600
1601             //decrease recursion to init value and close where
1602             while (ConfigVariable::getRecursionLevel() > level)
1603             {
1604                 ConfigVariable::where_end();
1605                 ConfigVariable::decreaseRecursion();
1606             }
1607
1608             //print msg about recursion limit and trigger an error
1609             wchar_t sz[1024];
1610             os_swprintf(sz, 1024, _W("Recursion limit reached (%d).\n").data(), ConfigVariable::getRecursionLimit());
1611             throw ast::InternalError(sz);
1612         }
1613
1614     }
1615     catch (const InternalError& /* ie */)
1616     {
1617         //restore previous prompt mode
1618         ConfigVariable::setSilentError(oldVal);
1619         //to lock lasterror
1620         ConfigVariable::setLastErrorCall();
1621         // reset call stack filled when error occured
1622         ConfigVariable::resetWhereError();
1623         e.getCatch().accept(*this);
1624     }
1625 }
1626
1627
1628 } /* namespace ast */
1629
1630 #include "run_CallExp.hpp"
1631 #include "run_MatrixExp.hpp"
1632 #include "run_OpExp.hpp"
1633 #include "run_AssignExp.hpp"
1634
1635 template EXTERN_AST class ast::RunVisitorT<ast::ExecVisitor>;
1636 template EXTERN_AST class ast::RunVisitorT<ast::StepVisitor>;
1637 template EXTERN_AST class ast::RunVisitorT<ast::TimedVisitor>;
1638 template EXTERN_AST class ast::RunVisitorT<ast::DebuggerVisitor>;