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