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