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