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