fix bug 6792 : save expected size before recursive call of SeqExp.
[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
42 extern "C"
43 {
44 #include "sciprint.h"
45 #include "os_string.h"
46 #include "elem_common.h"
47
48 #include "Thread_Wrapper.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())
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         //condition == true
283         if (e.isBreakable())
284         {
285             const_cast<IfExp*>(&e)->resetBreak();
286             const_cast<Exp*>(&e.getThen())->setBreakable();
287         }
288
289         if (e.isContinuable())
290         {
291             const_cast<IfExp*>(&e)->resetContinue();
292             const_cast<Exp*>(&e.getThen())->setContinuable();
293         }
294
295         if (e.isReturnable())
296         {
297             const_cast<IfExp*>(&e)->resetReturn();
298             const_cast<Exp*>(&e.getThen())->setReturnable();
299         }
300
301         e.getThen().accept(*this);
302     }
303     else
304     {
305         //condition == false
306
307         if (e.hasElse())
308         {
309             if (e.isBreakable())
310             {
311                 const_cast<Exp*>(&e.getElse())->setBreakable();
312             }
313
314             if (e.isContinuable())
315             {
316                 const_cast<IfExp*>(&e)->resetContinue();
317                 const_cast<Exp*>(&e.getElse())->setContinuable();
318             }
319
320             if (e.isReturnable())
321             {
322                 const_cast<Exp*>(&e.getElse())->setReturnable();
323             }
324
325             e.getElse().accept(*this);
326         }
327     }
328
329     if (e.isBreakable()
330             && ( (&e.getElse())->isBreak()
331                  || (&e.getThen())->isBreak() ))
332     {
333         const_cast<IfExp*>(&e)->setBreak();
334         const_cast<Exp*>(&e.getElse())->resetBreak();
335         const_cast<Exp*>(&e.getThen())->resetBreak();
336     }
337
338     if (e.isContinuable()
339             && ( (&e.getElse())->isContinue()
340                  || (&e.getThen())->isContinue() ))
341     {
342         const_cast<IfExp*>(&e)->setContinue();
343         const_cast<Exp*>(&e.getElse())->resetContinue();
344         const_cast<Exp*>(&e.getThen())->resetContinue();
345     }
346
347     if (e.isReturnable()
348             && ( (&e.getElse())->isReturn()
349                  || (&e.getThen())->isReturn() ))
350     {
351         const_cast<IfExp*>(&e)->setReturn();
352         const_cast<Exp*>(&e.getElse())->resetReturn();
353         const_cast<Exp*>(&e.getThen())->resetReturn();
354     }
355 }
356
357 template <class T>
358 void RunVisitorT<T>::visitprivate(const WhileExp  &e)
359 {
360     //allow break and continue operations
361     const_cast<Exp*>(&e.getBody())->setBreakable();
362     const_cast<Exp*>(&e.getBody())->setContinuable();
363     //allow return operation
364     if (e.isReturnable())
365     {
366         const_cast<Exp*>(&(e.getBody()))->setReturnable();
367     }
368
369     //condition
370     e.getTest().accept(*this);
371     InternalType* pIT = getResult();
372     while (pIT->isTrue())
373     {
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         pIT->killMe();
403         e.getTest().accept(*this);
404         pIT = getResult();
405     }
406
407     //pIT->killMe();
408     //clear result of condition or result of body
409     clearResult();
410 }
411
412 template <class T>
413 void RunVisitorT<T>::visitprivate(const ForExp  &e)
414 {
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         symbol::Context* ctx = symbol::Context::getInstance();
431         //get IL
432         ImplicitList* pVar = pIT->getAs<ImplicitList>();
433         //get IL initial Type
434         InternalType * pIL = pVar->getInitalType();
435         //get index stack
436         symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
437
438         ctx->put(var, pIL);
439         //use ref count to lock var against clear and detect any changes
440         pIL->IncreaseRef();
441
442
443         int size = pVar->getSize();
444         for (int i = 0; i < size; ++i)
445         {
446             //check if loop index has changed, deleted, copy ...
447             switch (pIL->getRef())
448             {
449                 case 2:
450                     //normal case
451                     break;
452                 case 1:
453                     //someone clear me
454                     ctx->put(var, pIL);
455                     break;
456                 default:
457                     //someone assign me to another var
458                     //a = i;
459                     //unlock me
460                     pIL->DecreaseRef();
461
462                     //create a new me
463                     pIL = pVar->getInitalType();
464                     //lock loop index
465                     pIL->IncreaseRef();
466                     //update me ( must decrease ref of a
467                     symbol::Context::getInstance()->put(var, pIL);
468                     break;
469             }
470
471             pVar->extractValue(i, pIL);
472
473             e.getBody().accept(*this);
474             if (e.getBody().isBreak())
475             {
476                 const_cast<Exp&>(e.getBody()).resetBreak();
477                 break;
478             }
479
480             if (e.getBody().isContinue())
481             {
482                 const_cast<Exp&>(e.getBody()).resetContinue();
483                 continue;
484             }
485
486             if (e.getBody().isReturn())
487             {
488                 const_cast<ForExp&>(e).setReturn();
489                 const_cast<Exp&>(e.getBody()).resetReturn();
490                 break;
491             }
492         }
493
494         //unlock loop index
495         pIL->DecreaseRef();
496         pIL->killMe();
497     }
498     else if (pIT->isList())
499     {
500         List* pL = pIT->getAs<List>();
501         const int size = pL->getSize();
502         for (int i = 0; i < size; ++i)
503         {
504             InternalType* pNew = pL->get(i);
505             symbol::Context::getInstance()->put(e.getVardec().getAs<VarDec>()->getStack(), pNew);
506
507             e.getBody().accept(*this);
508             if (e.getBody().isBreak())
509             {
510                 const_cast<Exp*>(&(e.getBody()))->resetBreak();
511                 break;
512             }
513
514             if (e.getBody().isContinue())
515             {
516                 const_cast<Exp*>(&(e.getBody()))->resetContinue();
517                 continue;
518             }
519
520             if (e.getBody().isReturn())
521             {
522                 const_cast<ForExp*>(&e)->setReturn();
523                 const_cast<Exp&>(e.getBody()).resetReturn();
524                 break;
525             }
526         }
527     }
528     else if (pIT->isGenericType())
529     {
530         //Matrix i = [1,3,2,6] or other type
531         GenericType* pVar = pIT->getAs<GenericType>();
532         if (pVar->getDims() > 2)
533         {
534             pIT->DecreaseRef();
535             pIT->killMe();
536             throw ScilabError(_W("for expression can only manage 1 or 2 dimensions variables\n"), 999, e.getVardec().getLocation());
537         }
538
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             symbol::Context::getInstance()->put(e.getVardec().getAs<VarDec>()->getStack(), pNew);
550
551             e.getBody().accept(*this);
552             if (e.getBody().isBreak())
553             {
554                 const_cast<Exp*>(&(e.getBody()))->resetBreak();
555                 break;
556             }
557
558             if (e.getBody().isContinue())
559             {
560                 const_cast<Exp*>(&(e.getBody()))->resetContinue();
561                 continue;
562             }
563
564             if (e.getBody().isReturn())
565             {
566                 const_cast<ForExp*>(&e)->setReturn();
567                 const_cast<Exp&>(e.getBody()).resetReturn();
568                 break;
569             }
570         }
571     }
572     else
573     {
574         pIT->DecreaseRef();
575         pIT->killMe();
576         throw ScilabError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
577     }
578
579     pIT->DecreaseRef();
580     pIT->killMe();
581
582     setResult(NULL);
583 }
584
585 template <class T>
586 void RunVisitorT<T>::visitprivate(const ReturnExp &e)
587 {
588     if (e.isGlobal())
589     {
590         if (ConfigVariable::getPauseLevel() != 0 && symbol::Context::getInstance()->getScopeLevel() == ConfigVariable::getActivePauseLevel())
591         {
592             //return or resume
593             ThreadId* pThreadId = ConfigVariable::getLastPausedThread();
594             if (pThreadId == NULL)
595             {
596                 //no paused thread, so just go leave
597                 return;
598             }
599
600             //force exit without prompt of current thread ( via Aborted status )
601             ThreadId* pMe = ConfigVariable::getThread(__GetCurrentThreadKey());
602             pMe->setStatus(ThreadId::Aborted);
603
604             //resume previous execution thread
605             pThreadId->resume();
606
607             return;
608         }
609         else
610         {
611             const_cast<ReturnExp*>(&e)->setReturn();
612         }
613     }
614     else
615     {
616         //return(x)
617
618         //in case of CallExp, we can return only one values
619         int iSaveExpectedSize = getExpectedSize();
620         setExpectedSize(1);
621         e.getExp().accept(*this);
622         setExpectedSize(iSaveExpectedSize);
623         const_cast<ReturnExp*>(&e)->setReturn();
624     }
625 }
626
627 template <class T>
628 void RunVisitorT<T>::visitprivate(const SelectExp &e)
629 {
630     // FIXME : exec select ... case ... else ... end
631     e.getSelect()->accept(*this);
632     bool bCase = false;
633
634     InternalType* pIT = getResult();
635     setResult(NULL);
636     if (pIT)
637     {
638         //find good case
639         exps_t cases = e.getCases();
640         for (auto exp : cases)
641         {
642             CaseExp* pCase = exp->getAs<CaseExp>();
643             pCase->getTest()->accept(*this);
644             InternalType *pITCase = getResult();
645             setResult(NULL);
646             if (pITCase)
647             {
648                 if (pITCase->isContainer()) //WARNING ONLY FOR CELL
649                 {
650                     //check each item
651                 }
652                 else if (*pITCase == *pIT)
653                 {
654                     if (e.isBreakable())
655                     {
656                         const_cast<SelectExp*>(&e)->resetBreak();
657                         pCase->getBody()->setBreakable();
658                     }
659
660                     if (e.isContinuable())
661                     {
662                         const_cast<SelectExp*>(&e)->resetContinue();
663                         pCase->getBody()->setContinuable();
664                     }
665
666                     if (e.isReturnable())
667                     {
668                         const_cast<SelectExp*>(&e)->resetReturn();
669                         pCase->getBody()->setReturnable();
670                     }
671
672                     try
673                     {
674                         //the good one
675                         pCase->getBody()->accept(*this);
676                     }
677                     catch (ScilabMessage& sm)
678                     {
679                         pIT->killMe();
680                         throw sm;
681                     }
682
683                     if (e.isBreakable() && pCase->getBody()->isBreak())
684                     {
685                         const_cast<SelectExp*>(&e)->setBreak();
686                         pCase->getBody()->resetBreak();
687                     }
688
689                     if (e.isContinuable() && pCase->getBody()->isContinue())
690                     {
691                         const_cast<SelectExp*>(&e)->setContinue();
692                         pCase->getBody()->resetContinue();
693                     }
694
695                     if (e.isReturnable() && pCase->getBody()->isReturn())
696                     {
697                         const_cast<SelectExp*>(&e)->setReturn();
698                         pCase->getBody()->resetReturn();
699                     }
700
701                     pITCase->killMe();
702                     bCase = true;
703                     break;
704                 }
705
706                 pITCase->killMe();
707             }
708         }
709     }
710
711     if (bCase == false && e.getDefaultCase() != NULL)
712     {
713         if (e.isBreakable())
714         {
715             const_cast<SelectExp*>(&e)->resetBreak();
716             e.getDefaultCase()->setBreakable();
717         }
718
719         if (e.isContinuable())
720         {
721             const_cast<SelectExp*>(&e)->resetContinue();
722             e.getDefaultCase()->setContinuable();
723         }
724
725         if (e.isReturnable())
726         {
727             const_cast<SelectExp*>(&e)->resetReturn();
728             e.getDefaultCase()->setReturnable();
729         }
730
731         //default case
732         e.getDefaultCase()->accept(*this);
733
734         if (e.isBreakable() && e.getDefaultCase()->isBreak())
735         {
736             const_cast<SelectExp*>(&e)->setBreak();
737             e.getDefaultCase()->resetBreak();
738         }
739
740         if (e.isContinuable() && e.getDefaultCase()->isContinue())
741         {
742             const_cast<SelectExp*>(&e)->setContinue();
743             e.getDefaultCase()->resetContinue();
744         }
745
746         if (e.isReturnable() && e.getDefaultCase()->isReturn())
747         {
748             const_cast<SelectExp*>(&e)->setReturn();
749             e.getDefaultCase()->resetReturn();
750         }
751     }
752
753     clearResult();
754
755     pIT->killMe();
756 }
757
758 template <class T>
759 void RunVisitorT<T>::visitprivate(const SeqExp  &e)
760 {
761     //T execMe;
762     exps_t::const_iterator itExp;
763     exps_t exps = e.getExps();
764
765     types::ThreadId* pThreadMe = ConfigVariable::getThread(__GetCurrentThreadKey());
766
767     for (itExp = exps.begin (); itExp != exps.end (); ++itExp)
768     {
769         if (pThreadMe && pThreadMe->getInterrupt())
770         {
771             __Signal(getAstPendingSignal());
772             pThreadMe->suspend();
773         }
774
775         if (e.isBreakable())
776         {
777             (*itExp)->resetBreak();
778             (*itExp)->setBreakable();
779         }
780
781         if (e.isContinuable())
782         {
783             (*itExp)->resetContinue();
784             (*itExp)->setContinuable();
785         }
786
787         if (e.isReturnable())
788         {
789             (*itExp)->setReturnable();
790         }
791
792         try
793         {
794             //reset default values
795             setResult(NULL);
796             int iExpectedSize = getExpectedSize();
797             setExpectedSize(-1);
798             (*itExp)->accept(*this);
799             setExpectedSize(iExpectedSize);
800             InternalType * pIT = getResult();
801
802             if (pIT != NULL)
803             {
804                 bool bImplicitCall = false;
805                 if (pIT->isCallable()) //to manage call without ()
806                 {
807                     Callable *pCall = pIT->getAs<Callable>();
808                     typed_list out;
809                     typed_list in;
810                     optional_list opt;
811
812                     try
813                     {
814                         //in this case of calling, we can return only one values
815                         int iSaveExpectedSize = getExpectedSize();
816                         setExpectedSize(1);
817
818                         pCall->invoke(in, opt, getExpectedSize(), out, *this, e);
819                         setExpectedSize(iSaveExpectedSize);
820
821                         if (out.size() == 0)
822                         {
823                             setResult(NULL);
824                         }
825                         else
826                         {
827                             setResult(out[0]);
828                         }
829
830                         bImplicitCall = true;
831                     }
832                     catch (ScilabMessage& sm)
833                     {
834                         wostringstream os;
835                         PrintVisitor printMe(os);
836                         (*itExp)->accept(printMe);
837                         //os << std::endl << std::endl;
838                         if (ConfigVariable::getLastErrorFunction() == L"")
839                         {
840                             ConfigVariable::setLastErrorFunction(pCall->getName());
841                         }
842
843                         if (pCall->isMacro() || pCall->isMacroFile())
844                         {
845                             wchar_t szError[bsiz];
846                             os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), sm.GetErrorLocation().first_line, pCall->getName().c_str());
847                             throw ScilabMessage(szError + os.str());
848                         }
849                         else
850                         {
851                             sm.SetErrorMessage(sm.GetErrorMessage() + os.str());
852                             throw sm;
853                         }
854                     }
855                     catch (ast::ScilabError & se)
856                     {
857                         if (ConfigVariable::getLastErrorFunction() == L"")
858                         {
859                             ConfigVariable::setLastErrorFunction(pCall->getName());
860                             ConfigVariable::setLastErrorLine(e.getLocation().first_line);
861                             throw ScilabError();
862                         }
863
864                         if (pCall->isMacro() || pCall->isMacroFile())
865                         {
866                             wchar_t szError[bsiz];
867                             os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), (*itExp)->getLocation().first_line, pCall->getName().c_str());
868                             throw ScilabMessage(szError);
869                         }
870                         else
871                         {
872                             throw ScilabMessage();
873                         }
874                     }
875                 }
876
877                 //don't output Simplevar and empty result
878                 if (getResult() != NULL && (!(*itExp)->isSimpleVar() || bImplicitCall))
879                 {
880                     //symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), *execMe.getResult());
881                     InternalType* pITAns = getResult();
882                     symbol::Context::getInstance()->put(m_pAns, pITAns);
883                     if ((*itExp)->isVerbose() && ConfigVariable::isPromptShow())
884                     {
885                         //TODO manage multiple returns
886                         scilabWriteW(L" ans  =\n\n");
887                         std::wostringstream ostrName;
888                         ostrName << L"ans";
889                         VariableToString(pITAns, ostrName.str().c_str());
890                     }
891                 }
892
893                 pIT->killMe();
894             }
895
896             if ((&e)->isBreakable() && (*itExp)->isBreak())
897             {
898                 const_cast<SeqExp *>(&e)->setBreak();
899                 break;
900             }
901
902             if ((&e)->isContinuable() && (*itExp)->isContinue())
903             {
904                 const_cast<SeqExp *>(&e)->setContinue();
905                 break;
906             }
907
908             if ((&e)->isReturnable() && (*itExp)->isReturn())
909             {
910                 const_cast<SeqExp *>(&e)->setReturn();
911                 (*itExp)->resetReturn();
912                 break;
913             }
914         }
915         catch (const ScilabMessage& sm)
916         {
917             scilabErrorW(sm.GetErrorMessage().c_str());
918
919             CallExp* pCall = dynamic_cast<CallExp*>(*itExp);
920             if (pCall != NULL)
921             {
922                 //to print call expression only of it is a macro
923                 pCall->getName().accept(*this);
924
925                 if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
926                 {
927                     wostringstream os;
928                     PrintVisitor printMe(os);
929                     pCall->accept(printMe);
930                     //os << std::endl << std::endl;
931                     if (ConfigVariable::getLastErrorFunction() == L"")
932                     {
933                         ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
934                     }
935                     throw ScilabMessage(os.str(), 0, (*itExp)->getLocation());
936                 }
937             }
938
939             throw ScilabMessage((*itExp)->getLocation());
940         }
941         catch (const ScilabError& se)
942         {
943             // check on error number because error message can be empty.
944             if (ConfigVariable::getLastErrorNumber() == 0)
945             {
946                 ConfigVariable::setLastErrorMessage(se.GetErrorMessage());
947                 ConfigVariable::setLastErrorNumber(se.GetErrorNumber());
948                 ConfigVariable::setLastErrorLine(se.GetErrorLocation().first_line);
949                 ConfigVariable::setLastErrorFunction(wstring(L""));
950             }
951
952             CallExp* pCall = dynamic_cast<CallExp*>(*itExp);
953             if (pCall != NULL)
954             {
955                 //to print call expression only of it is a macro
956                 try
957                 {
958                     pCall->getName().accept(*this);
959                     if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
960                     {
961                         wostringstream os;
962                         PrintVisitor printMe(os);
963                         pCall->accept(printMe);
964                         //os << std::endl << std::endl;
965                         ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
966                         scilabErrorW(se.GetErrorMessage().c_str());
967                         throw ScilabMessage(os.str(), 999, (*itExp)->getLocation());
968                     }
969                 }
970                 catch (ScilabError& se2)
971                 {
972                     //just to catch exception, do nothing
973                 }
974             }
975
976             scilabErrorW(se.GetErrorMessage().c_str());
977             scilabErrorW(L"\n");
978             throw ScilabMessage((*itExp)->getLocation());
979         }
980
981         // If something other than NULL is given to setResult, then that would imply
982         // to make a cleanup in visit(ForExp) for example (e.getBody().accept(*this);)
983         setResult(NULL);
984     }
985 }
986
987 template <class T>
988 void RunVisitorT<T>::visitprivate(const NotExp &e)
989 {
990     /*
991       @ or ~ !
992     */
993     e.getExp().accept(*this);
994
995     InternalType * pValue = getResult();
996     InternalType * pReturn = NULL;
997     if (pValue->neg(pReturn))
998     {
999         if (pValue != pReturn)
1000         {
1001             pValue->killMe();
1002         }
1003
1004         setResult(pReturn);
1005     }
1006     else
1007     {
1008         // neg returned false so the negation is not possible so we call the overload (%foo_5)
1009         types::typed_list in;
1010         types::typed_list out;
1011
1012         pValue->IncreaseRef();
1013         in.push_back(pValue);
1014
1015         Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_5", in, 1, out, this);
1016
1017         if (Ret != Callable::OK)
1018         {
1019             cleanInOut(in, out);
1020             throw ScilabError();
1021         }
1022
1023         setResult(out);
1024         cleanIn(in, out);
1025     }
1026 }
1027
1028 template <class T>
1029 void RunVisitorT<T>::visitprivate(const TransposeExp &e)
1030 {
1031     e.getExp().accept(*this);
1032
1033     if (getResultSize() != 1)
1034     {
1035         clearResult();
1036         wchar_t szError[bsiz];
1037         os_swprintf(szError, bsiz, _W("%ls: Can not transpose multiple elements.\n").c_str(), L"Transpose");
1038         throw ScilabError(szError, 999, e.getLocation());
1039     }
1040
1041     InternalType * pValue = getResult();
1042     InternalType * pReturn = NULL;
1043     const bool bConjug = e.getConjugate() == TransposeExp::_Conjugate_;
1044
1045     if ((bConjug && pValue->adjoint(pReturn)) || (!bConjug && pValue->transpose(pReturn)))
1046     {
1047         if (pValue != pReturn)
1048         {
1049             pValue->killMe();
1050         }
1051
1052         setResult(pReturn);
1053
1054         return;
1055     }
1056     else
1057     {
1058         // transpose returned false so the negation is not possible so we call the overload (%foo_t or %foo_0)
1059         types::typed_list in;
1060         types::typed_list out;
1061
1062         pValue->IncreaseRef();
1063         in.push_back(pValue);
1064
1065         Callable::ReturnValue Ret;
1066         if (bConjug)
1067         {
1068             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_t", in, 1, out, this);
1069         }
1070         else
1071         {
1072             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_0", in, 1, out, this);
1073         }
1074
1075         if (Ret != Callable::OK)
1076         {
1077             cleanInOut(in, out);
1078             throw ScilabError();
1079         }
1080
1081         setResult(out);
1082         cleanIn(in, out);
1083     }
1084 }
1085
1086 template <class T>
1087 void RunVisitorT<T>::visitprivate(const FunctionDec & e)
1088 {
1089
1090     /*
1091       function foo
1092       endfunction
1093     */
1094
1095     // funcprot(0) : do nothing
1096     // funcprot(1) && warning(on) : warning
1097     //get input parameters list
1098     std::list<symbol::Variable*> *pVarList = new std::list<symbol::Variable*>();
1099     const exps_t & vars = e.getArgs().getVars();
1100     for (const auto var : vars)
1101     {
1102         pVarList->push_back(var->getAs<SimpleVar>()->getStack());
1103     }
1104
1105     //get output parameters list
1106     std::list<symbol::Variable*> *pRetList = new std::list<symbol::Variable*>();
1107     const exps_t & rets = e.getReturns().getVars();
1108     for (const auto ret : rets)
1109     {
1110         pRetList->push_back(ret->getAs<SimpleVar>()->getStack());
1111     }
1112
1113     types::Macro *pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList,
1114                                             const_cast<SeqExp&>(static_cast<const SeqExp&>(e.getBody())), L"script");
1115     pMacro->setFirstLine(e.getLocation().first_line);
1116
1117     bool bEquals = false;
1118     int iFuncProt = ConfigVariable::getFuncprot();
1119     if (iFuncProt != 0)
1120     {
1121         types::InternalType* pITFunc = symbol::Context::getInstance()->get(((FunctionDec&)e).getStack());
1122         if (pITFunc && pITFunc->isCallable())
1123         {
1124             if (pITFunc->isMacroFile())
1125             {
1126                 types::MacroFile* pMF = pITFunc->getAs<types::MacroFile>();
1127                 bEquals = *pMF->getMacro() == *pMacro;
1128             }
1129             else if (pITFunc->isMacro())
1130             {
1131                 types::Macro* pM = pITFunc->getAs<types::Macro>();
1132                 bEquals = *pM == *pMacro;
1133             }
1134         }
1135         else
1136         {
1137             bEquals = true; //avoid msg but keep assignation
1138         }
1139     }
1140
1141     if (bEquals == false && iFuncProt == 1 && ConfigVariable::getWarningMode())
1142     {
1143         wchar_t pwstFuncName[1024];
1144         os_swprintf(pwstFuncName, 1024, L"%-24ls", e.getSymbol().getName().c_str());
1145         char* pstFuncName = wide_string_to_UTF8(pwstFuncName);
1146
1147         sciprint(_("Warning : redefining function: %s. Use funcprot(0) to avoid this message"), pstFuncName);
1148         sciprint("\n");
1149         FREE(pstFuncName);
1150     }
1151     else if (bEquals == false && iFuncProt == 2)
1152     {
1153         char pstError[1024];
1154         char* pstFuncName = wide_string_to_UTF8(e.getSymbol().getName().c_str());
1155         os_sprintf(pstError, _("It is not possible to redefine the %s primitive this way (see clearfun).\n"), pstFuncName);
1156         wchar_t* pwstError = to_wide_string(pstError);
1157         std::wstring wstError(pwstError);
1158         FREE(pstFuncName);
1159         FREE(pwstError);
1160         throw ScilabError(wstError, 999, e.getLocation());
1161     }
1162
1163     symbol::Context::getInstance()->addMacro(pMacro);
1164
1165 }
1166
1167 template <class T>
1168 void RunVisitorT<T>::visitprivate(const ListExp &e)
1169 {
1170     e.getStart().accept(*this);
1171     GenericType* pITStart = static_cast<GenericType*>(getResult());
1172     if ((pITStart->getSize() != 1 || (pITStart->isDouble() && pITStart->getAs<Double>()->isComplex())) &&
1173             pITStart->isList() == false) // list case => call overload
1174     {
1175         pITStart->killMe();
1176         wchar_t szError[bsiz];
1177         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 1);
1178         throw ScilabError(szError, 999, e.getLocation());
1179     }
1180     InternalType * piStart = pITStart;
1181
1182     e.getStep().accept(*this);
1183     GenericType* pITStep = static_cast<GenericType*>(getResult());
1184     if ((pITStep->getSize() != 1 || (pITStep->isDouble() && pITStep->getAs<Double>()->isComplex())) &&
1185             pITStep->isList() == false) // list case => call overload
1186     {
1187         pITStart->killMe();
1188         pITStep->killMe();
1189         wchar_t szError[bsiz];
1190         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2);
1191         throw ScilabError(szError, 999, e.getLocation());
1192     }
1193     InternalType* piStep = pITStep;
1194
1195     e.getEnd().accept(*this);
1196     GenericType* pITEnd = static_cast<GenericType*>(getResult());
1197     if ((pITEnd->getSize() != 1 || (pITEnd->isDouble() && pITEnd->getAs<Double>()->isComplex())) &&
1198             pITEnd->isList() == false) // list case => call overload
1199     {
1200         pITStart->killMe();
1201         pITStep->killMe();
1202         pITEnd->killMe();
1203         wchar_t szError[bsiz];
1204         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 3);
1205         throw ScilabError(szError, 999, e.getLocation());
1206     }
1207     InternalType* piEnd = pITEnd;
1208
1209     //check compatibility
1210     // double : double : double or poly : poly : poly and mix like double : double : poly
1211     if ((piStart->isPoly() || piStart->isDouble()) &&
1212             (piStep->isPoly()  || piStep->isDouble())  &&
1213             (piEnd->isPoly()   || piEnd->isDouble()))
1214     {
1215         // No need to kill piStart, ... because Implicit list ctor will incref them
1216         setResult(new ImplicitList(piStart, piStep, piEnd));
1217         return;
1218     }
1219
1220     // int : double or int : int
1221     if ( piStart->isInt()   &&
1222             (piStep->isDouble() || piStep->isInt()) &&
1223             piEnd->isInt())
1224     {
1225         // check for same int type int8, int 16 ...
1226         if (piStart->getType() == piEnd->getType()  &&
1227                 (piStart->getType() == piStep->getType() ||
1228                  piStep->isDouble()))
1229         {
1230             // No need to kill piStart, ... because Implicit list ctor will incref them
1231             setResult(new ImplicitList(piStart, piStep, piEnd));
1232             return;
1233         }
1234     }
1235
1236     // Call Overload
1237     Callable::ReturnValue Ret;
1238     types::typed_list in;
1239     types::typed_list out;
1240
1241     piStart->IncreaseRef();
1242     piStep->IncreaseRef();
1243     piEnd->IncreaseRef();
1244
1245     in.push_back(piStart);
1246     if (e.hasExplicitStep())
1247     {
1248         // 1:2:4
1249         //call overload %typeStart_b_typeEnd
1250         in.push_back(piStep);
1251         in.push_back(piEnd);
1252         Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piStep->getShortTypeStr(), in, 1, out, this, true);
1253     }
1254     else
1255     {
1256         // 1:2
1257         //call overload %typeStart_b_typeStep
1258         in.push_back(piEnd);
1259         Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piEnd->getShortTypeStr(), in, 1, out, this, true);
1260     }
1261
1262     if (Ret != Callable::OK)
1263     {
1264         cleanInOut(in, out);
1265         throw ScilabError();
1266     }
1267
1268     setResult(out);
1269     cleanIn(in, out);
1270 }
1271
1272 template <class T>
1273 void RunVisitorT<T>::visitprivate(const OptimizedExp &e)
1274 {
1275 }
1276
1277 template <class T>
1278 void RunVisitorT<T>::visitprivate(const DAXPYExp &e)
1279 {
1280     InternalType* pIT = NULL;
1281     Double* ad = NULL;
1282     int ar = 0;
1283     int ac = 0;
1284
1285     Double* xd = NULL;
1286     int xr = 0;
1287     int xc = 0;
1288
1289     Double* yd = NULL;
1290     int yr = 0;
1291     int yc = 0;
1292
1293     //check types and dimensions
1294
1295     //y must be double
1296     const Exp &ye = e.getY();
1297     ye.accept(*this);
1298     pIT = getResult();
1299     if (pIT->isDouble())
1300     {
1301         yd = pIT->getAs<Double>();
1302         if (yd->getDims() == 2 && yd->isComplex() == false)
1303         {
1304             yr = yd->getRows();
1305             yc = yd->getCols();
1306         }
1307         else
1308         {
1309             yd->killMe();
1310             e.getOriginal()->accept(*this);
1311             return;
1312         }
1313     }
1314     else
1315     {
1316         pIT->killMe();
1317         e.getOriginal()->accept(*this);
1318         return;
1319     }
1320
1321     //x
1322     const Exp &xe = e.getX();
1323     xe.accept(*this);
1324     pIT = getResult();
1325
1326     if (pIT->isDouble())
1327     {
1328         xd = pIT->getAs<Double>();
1329         if (xd->isScalar() && xd->isComplex() == false)
1330         {
1331             // x become a
1332             ad = xd;
1333             ar = 1;
1334             ac = 1;
1335         }
1336         else if (xd->getDims() == 2 && xd->isComplex() == false)
1337         {
1338             xr = xd->getRows();
1339             xc = xd->getCols();
1340         }
1341         else
1342         {
1343             yd->killMe();
1344             xd->killMe();
1345             e.getOriginal()->accept(*this);
1346             return;
1347         }
1348     }
1349     else
1350     {
1351         pIT->killMe();
1352         yd->killMe();
1353         e.getOriginal()->accept(*this);
1354         return;
1355     }
1356
1357     const Exp &ae = e.getA();
1358     ae.accept(*this);
1359     pIT = getResult();
1360
1361     if (pIT->isDouble())
1362     {
1363         if (ad)
1364         {
1365             xd = pIT->getAs<Double>();
1366             //X is scalar it become A
1367             //now use A as X
1368             if (xd->getDims() == 2 && xd->isComplex() == false)
1369             {
1370                 xr = xd->getRows();
1371                 xc = xd->getCols();
1372             }
1373             else
1374             {
1375                 yd->killMe();
1376                 xd->killMe();
1377                 ad->killMe();
1378                 e.getOriginal()->accept(*this);
1379                 return;
1380             }
1381         }
1382         else
1383         {
1384             //a is a and it must be scalar
1385             ad = pIT->getAs<Double>();
1386             if (/*ad->isScalar() && */ad->isComplex() == false)
1387             {
1388                 ar = ad->getRows(); //1;
1389                 ac = ad->getCols();//1;
1390             }
1391             else
1392             {
1393                 yd->killMe();
1394                 xd->killMe();
1395                 ad->killMe();
1396                 e.getOriginal()->accept(*this);
1397                 return;
1398             }
1399         }
1400     }
1401     else
1402     {
1403         pIT->killMe();
1404         yd->killMe();
1405         xd->killMe();
1406         e.getOriginal()->accept(*this);
1407         return;
1408     }
1409
1410     if (ad && xd && yd)
1411     {
1412         if ( ac == 1 &&
1413                 ar == 1 &&
1414                 xr == yr &&
1415                 xc == yc)
1416         {
1417             //go !
1418             int one = 1;
1419             int size = xc * xr;
1420             //Double* od = (Double*)yd->clone();
1421             C2F(daxpy)(&size, ad->get(), xd->get(), &one, yd->get(), &one);
1422             //setResult(od);
1423             //yd->killMe();
1424             xd->killMe();
1425             ad->killMe();
1426             return;
1427         }
1428         else if (ac == xr && ar == yr && xc == yc)
1429         {
1430             char n = 'n';
1431             double one = 1;
1432             C2F(dgemm)(&n, &n, &ar, &xc, &ac, &one, ad->get(), &ar, xd->get(), &ac, &one, yd->get(), &ar);
1433             xd->killMe();
1434             ad->killMe();
1435             return;
1436         }
1437     }
1438
1439     if (yd)
1440     {
1441         yd->killMe();
1442     }
1443
1444     if (xd)
1445     {
1446         xd->killMe();
1447     }
1448
1449     if (ad)
1450     {
1451         ad->killMe();
1452     }
1453
1454     e.getOriginal()->accept(*this);
1455     return;
1456 }
1457
1458 } /* namespace ast */
1459
1460 #include "run_CallExp.hpp"
1461 #include "run_MatrixExp.hpp"
1462 #include "run_OpExp.hpp"
1463 #include "run_AssignExp.hpp"
1464
1465 template EXTERN_AST class ast::RunVisitorT<ast::ExecVisitor>;
1466 template EXTERN_AST class ast::RunVisitorT<ast::StepVisitor>;
1467 template EXTERN_AST class ast::RunVisitorT<ast::TimedVisitor>;