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