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