AST : uniformize accessors name to setXXX and getXXX, add getAs<T> in ast::exp and...
[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 #include <string>
14
15 #include "runvisitor.hxx"
16 #include "execvisitor.hxx"
17 #include "stepvisitor.hxx"
18 #include "timedvisitor.hxx"
19 #include "shortcutvisitor.hxx"
20 #include "printvisitor.hxx"
21 #include "mutevisitor.hxx"
22
23 #include "visitor_common.hxx"
24
25 #include "context.hxx"
26 #include "generic_operations.hxx"
27 #include "types_or.hxx"
28 #include "types_and.hxx"
29 #include "localization.hxx"
30
31 #include "macrofile.hxx"
32 #include "macro.hxx"
33
34 extern "C"
35 {
36 #include "sciprint.h"
37 #include "os_swprintf.h"
38 }
39
40 namespace ast
41 {
42 template <class T>
43 void RunVisitorT<T>::visitprivate(const CellExp &e)
44 {
45     std::list<MatrixLineExp *>::const_iterator row;
46     std::list<Exp *>::const_iterator col;
47     int iColMax = 0;
48
49     //check dimmension
50     for (row = e.getLines().begin() ; row != e.getLines().end() ; ++row )
51     {
52         if (iColMax == 0)
53         {
54             iColMax = static_cast<int>((*row)->getColumns().size());
55         }
56
57         if (iColMax != static_cast<int>((*row)->getColumns().size()))
58         {
59             std::wostringstream os;
60             os << _W("inconsistent row/column dimensions\n");
61             //os << ((Location)(*row)->getLocation()).getLocationString() << std::endl;
62             throw ScilabError(os.str(), 999, (*row)->getLocation());
63         }
64     }
65
66     //alloc result cell
67     types::Cell *pC = new types::Cell(static_cast<int>(e.getLines().size()), iColMax);
68
69     int i = 0;
70     int j = 0;
71
72     //insert items in cell
73     for (i = 0, row = e.getLines().begin() ; row != e.getLines().end() ; ++row, ++i)
74     {
75         for (j = 0, col = (*row)->getColumns().begin() ; col != (*row)->getColumns().end() ; ++col, ++j)
76         {
77             (*col)->accept(*this);
78             InternalType *pIT = getResult();
79             if (pIT->isImplicitList())
80             {
81                 InternalType * _pIT = pIT->getAs<ImplicitList>()->extractFullMatrix();
82                 pC->set(i, j, _pIT);
83                 _pIT->killMe();
84             }
85             else
86             {
87                 pC->set(i, j, pIT);
88             }
89             clearResult();
90         }
91     }
92
93     //return new cell
94     setResult(pC);
95 }
96
97 template <class T>
98 void RunVisitorT<T>::visitprivate(const FieldExp &e)
99 {
100     /*
101       a.b
102     */
103
104     if (!e.getTail()->isSimpleVar())
105     {
106         wchar_t szError[bsiz];
107         os_swprintf(szError, bsiz, _W("/!\\ Unmanaged FieldExp.\n").c_str());
108         throw ScilabError(szError, 999, e.getLocation());
109     }
110
111     try
112     {
113         e.getHead()->accept(*this);
114     }
115     catch (const ScilabError& error)
116     {
117         throw error;
118     }
119
120     if (getResult() == NULL)
121     {
122         wchar_t szError[bsiz];
123         os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
124         throw ScilabError(szError, 999, e.getLocation());
125     }
126
127     // TODO: handle case where getSize() > 1
128     // l=list(struct("toto","coucou"),struct("toto","hello"),1,2);[a,b]=l(1:2).toto
129     //
130     if (getResultSize() > 1)
131     {
132         clearResult();
133         wchar_t szError[bsiz];
134         os_swprintf(szError, bsiz, _W("Not yet implemented in Scilab.\n").c_str());
135         throw ScilabError(szError, 999, e.getLocation());
136     }
137
138     SimpleVar * psvRightMember = static_cast<SimpleVar *>(const_cast<Exp *>(e.getTail()));
139     std::wstring wstField = psvRightMember->getSymbol().getName();
140     InternalType * pValue = getResult();
141     InternalType * pReturn = NULL;
142     bool ok;
143
144     try
145     {
146         ok = pValue->extract(wstField, pReturn);
147     }
148     catch (std::wstring & err)
149     {
150         pValue->killMe();
151         throw ScilabError(err.c_str(), 999, e.getTail()->getLocation());
152     }
153
154     if (ok)
155     {
156         setResult(pReturn);
157     }
158     else if (pValue->isFieldExtractionOverloadable())
159     {
160         types::typed_list in;
161         types::typed_list out;
162
163         String* pS = new String(wstField.c_str());
164
165         //TODO: in the case where overload is a macro there is no need to incref in
166         // because args will be put in context, removed and killed if required.
167         // But if the overload is a function... it is another story...
168
169         pS->IncreaseRef();
170         pValue->IncreaseRef();
171
172         in.push_back(pS);
173         in.push_back(pValue);
174
175         Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_e", in, 1, out, this);
176
177         if (Ret != Callable::OK)
178         {
179             cleanInOut(in, out);
180             throw ScilabError();
181         }
182
183         setResult(out);
184         cleanIn(in, out);
185     }
186     else
187     {
188         pValue->killMe();
189         wchar_t szError[bsiz];
190         os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
191         throw ScilabError(szError, 999, e.getLocation());
192     }
193 }
194
195 template <class T>
196 void RunVisitorT<T>::visitprivate(const IfExp  &e)
197 {
198     //Create local exec visitor
199     ShortCutVisitor SCTest;
200     bool bTestStatus = false;
201
202     //condition
203     e.getTest().accept(SCTest);
204     e.getTest().accept(*this);
205
206     bTestStatus = getResult()->isTrue();
207     clearResult();
208     if (bTestStatus == true)
209     {
210         //condition == true
211         if (e.isBreakable())
212         {
213             const_cast<IfExp*>(&e)->resetBreak();
214             const_cast<Exp*>(&e.getThen())->setBreakable();
215         }
216
217         if (e.isContinuable())
218         {
219             const_cast<IfExp*>(&e)->resetContinue();
220             const_cast<Exp*>(&e.getThen())->setContinuable();
221         }
222
223         if (e.isReturnable())
224         {
225             const_cast<IfExp*>(&e)->resetReturn();
226             const_cast<Exp*>(&e.getThen())->setReturnable();
227         }
228
229         e.getThen().accept(*this);
230     }
231     else
232     {
233         //condition == false
234
235         if (e.hasElse())
236         {
237             if (e.isBreakable())
238             {
239                 const_cast<Exp*>(&e.getElse())->setBreakable();
240             }
241
242             if (e.isContinuable())
243             {
244                 const_cast<IfExp*>(&e)->resetContinue();
245                 const_cast<Exp*>(&e.getElse())->setContinuable();
246             }
247
248             if (e.isReturnable())
249             {
250                 const_cast<Exp*>(&e.getElse())->setReturnable();
251             }
252
253             e.getElse().accept(*this);
254         }
255     }
256
257     if (e.isBreakable()
258             && ( (&e.getElse())->isBreak()
259                  || (&e.getThen())->isBreak() ))
260     {
261         const_cast<IfExp*>(&e)->setBreak();
262         const_cast<Exp*>(&e.getElse())->resetBreak();
263         const_cast<Exp*>(&e.getThen())->resetBreak();
264     }
265
266     if (e.isContinuable()
267             && ( (&e.getElse())->isContinue()
268                  || (&e.getThen())->isContinue() ))
269     {
270         const_cast<IfExp*>(&e)->setContinue();
271         const_cast<Exp*>(&e.getElse())->resetContinue();
272         const_cast<Exp*>(&e.getThen())->resetContinue();
273     }
274
275     if (e.isReturnable()
276             && ( (&e.getElse())->isReturn()
277                  || (&e.getThen())->isReturn() ))
278     {
279         const_cast<IfExp*>(&e)->setReturn();
280         const_cast<Exp*>(&e.getElse())->resetReturn();
281         const_cast<Exp*>(&e.getThen())->resetReturn();
282     }
283 }
284
285 template <class T>
286 void RunVisitorT<T>::visitprivate(const WhileExp  &e)
287 {
288     //allow break and continue operations
289     const_cast<Exp*>(&e.getBody())->setBreakable();
290     const_cast<Exp*>(&e.getBody())->setContinuable();
291     //allow return operation
292     if (e.isReturnable())
293     {
294         (&e.getBody())->isReturnable();
295     }
296
297     //condition
298     e.getTest().accept(*this);
299     while (getResult()->isTrue())
300     {
301         e.getBody().accept(*this);
302         if (e.getBody().isBreak())
303         {
304             const_cast<Exp*>(&(e.getBody()))->resetBreak();
305             break;
306         }
307
308         if (e.getBody().isReturn())
309         {
310             const_cast<WhileExp*>(&e)->setReturn();
311             const_cast<Exp*>(&(e.getBody()))->resetReturn();
312             break;
313         }
314
315         if (e.getBody().isContinue())
316         {
317             const_cast<WhileExp*>(&e)->setContinue();
318             const_cast<Exp*>(&(e.getBody()))->resetContinue();
319             e.getTest().accept(*this);
320             continue;
321         }
322
323         //clear old result value before evaluate new one
324         if (getResult() != NULL)
325         {
326             getResult()->killMe();
327         }
328
329         e.getTest().accept(*this);
330     }
331
332     //clear result of condition or result of body
333     clearResult();
334 }
335
336 template <class T>
337 void RunVisitorT<T>::visitprivate(const ForExp  &e)
338 {
339     e.getVardec().accept(*this);
340     InternalType* pIT = getResult();
341     //allow break and continue operations
342     const_cast<Exp&>(e.getBody()).setBreakable();
343     const_cast<Exp&>(e.getBody()).setContinuable();
344
345     //allow return operation
346     if (e.isReturnable())
347     {
348         e.getBody().isReturnable();
349     }
350
351     if (getResult()->isImplicitList())
352     {
353         ImplicitList* pVar = pIT->getAs<ImplicitList>();
354         for (int i = 0; i < pVar->getSize(); ++i)
355         {
356             //TODO : maybe it would be interesting here to reuse the same InternalType (to avoid delete/new)
357             InternalType * pIL = pVar->extractValue(i);
358             symbol::Context::getInstance()->put(e.getVardec().getStack(), pIL);
359
360             e.getBody().accept(*this);
361             if (e.getBody().isBreak())
362             {
363                 const_cast<Exp&>(e.getBody()).resetBreak();
364                 break;
365             }
366
367             if (e.getBody().isContinue())
368             {
369                 const_cast<Exp&>(e.getBody()).resetContinue();
370                 continue;
371             }
372
373             if (e.getBody().isReturn())
374             {
375                 const_cast<ForExp&>(e).setReturn();
376                 break;
377             }
378         }
379     }
380     else if (getResult()->isList())
381     {
382         List* pL = pIT->getAs<List>();
383         const int size = pL->getSize();
384         for (int i = 0; i < size; ++i)
385         {
386             InternalType* pNew = pL->get(i);
387             symbol::Context::getInstance()->put(e.getVardec().getStack(), pNew);
388
389             e.getBody().accept(*this);
390             if (e.getBody().isBreak())
391             {
392                 const_cast<Exp*>(&(e.getBody()))->resetBreak();
393                 break;
394             }
395
396             if (e.getBody().isContinue())
397             {
398                 const_cast<Exp*>(&(e.getBody()))->resetContinue();
399                 continue;
400             }
401
402             if (e.getBody().isReturn())
403             {
404                 const_cast<ForExp*>(&e)->setReturn();
405                 break;
406             }
407         }
408     }
409     else
410     {
411         //Matrix i = [1,3,2,6] or other type
412         GenericType* pVar = pIT->getAs<GenericType>();
413         if (pVar->getDims() > 2)
414         {
415             pIT->DecreaseRef();
416             pIT->killMe();
417
418             throw ScilabError(_W("for expression can only manage 1 or 2 dimensions variables\n"), 999, e.getVardec().getLocation());
419         }
420
421         for (int i = 0; i < pVar->getCols(); i++)
422         {
423             GenericType* pNew = pVar->getColumnValues(i);
424             symbol::Context::getInstance()->put(e.getVardec().getStack(), pNew);
425
426             e.getBody().accept(*this);
427             if (e.getBody().isBreak())
428             {
429                 const_cast<Exp*>(&(e.getBody()))->resetBreak();
430                 break;
431             }
432
433             if (e.getBody().isContinue())
434             {
435                 const_cast<Exp*>(&(e.getBody()))->resetContinue();
436                 continue;
437             }
438
439             if (e.getBody().isReturn())
440             {
441                 const_cast<ForExp*>(&e)->setReturn();
442                 break;
443             }
444         }
445     }
446
447     pIT->DecreaseRef();
448     pIT->killMe();
449
450     setResult(NULL);
451 }
452
453 template <class T>
454 void RunVisitorT<T>::visitprivate(const ReturnExp &e)
455 {
456     if (e.isGlobal())
457     {
458         //return or resume
459         if (ConfigVariable::getPauseLevel() != 0)
460         {
461             ThreadId* pThreadId = ConfigVariable::getLastPausedThread();
462             if (pThreadId == NULL)
463             {
464                 //no paused thread, so just go leave
465                 return;
466             }
467
468             //force exit without prompt of current thread ( via Aborted status )
469             ThreadId* pMe = ConfigVariable::getThread(__GetCurrentThreadKey());
470             pMe->setStatus(ThreadId::Aborted);
471
472             //resume previous execution thread
473             pThreadId->resume();
474
475             return;
476         }
477         else
478         {
479             const_cast<ReturnExp*>(&e)->setReturn();
480         }
481     }
482     else
483     {
484         //return(x)
485
486         //in case of CallExp, we can return only one values
487         int iSaveExpectedSize = getExpectedSize();
488         setExpectedSize(1);
489         e.getExp().accept(*this);
490         setExpectedSize(iSaveExpectedSize);
491
492         if (getResultSize() == 1)
493         {
494             //protect variable
495             getResult()->IncreaseRef();
496         }
497         else
498         {
499             for (int i = 0 ; i < getResultSize() ; i++)
500             {
501                 //protect variable
502                 getResult(i)->IncreaseRef();
503             }
504         }
505
506         if (getResultSize() == 1)
507         {
508             //unprotect variable
509             getResult()->DecreaseRef();
510         }
511         else
512         {
513             for (int i = 0 ; i < getResultSize() ; i++)
514             {
515                 //unprotect variable
516                 getResult(i)->DecreaseRef();
517             }
518         }
519
520         const_cast<ReturnExp*>(&e)->setReturn();
521     }
522 }
523
524 template <class T>
525 void RunVisitorT<T>::visitprivate(const SelectExp &e)
526 {
527     // FIXME : exec select ... case ... else ... end
528     e.getSelect()->accept(*this);
529     bool bCase = false;
530
531
532     InternalType* pIT = getResult();
533     setResult(NULL);
534     if (pIT)
535     {
536         //find good case
537         cases_t::iterator it;
538         for (it = e.getCases()->begin(); it != e.getCases()->end() ; it++)
539         {
540             CaseExp* pCase = *it;
541             pCase->getTest()->accept(*this);
542             InternalType *pITCase = getResult();
543             setResult(NULL);
544             if (pITCase)
545             {
546                 if (pITCase->isContainer()) //WARNING ONLY FOR CELL
547                 {
548                     //check each item
549                 }
550                 else if (*pITCase == *pIT)
551                 {
552                     if (e.isBreakable())
553                     {
554                         const_cast<SelectExp*>(&e)->resetBreak();
555                         pCase->getBody()->setBreakable();
556                     }
557
558                     if (e.isContinuable())
559                     {
560                         const_cast<SelectExp*>(&e)->resetContinue();
561                         pCase->getBody()->setContinuable();
562                     }
563
564                     if (e.isReturnable())
565                     {
566                         const_cast<SelectExp*>(&e)->resetReturn();
567                         pCase->getBody()->setReturnable();
568                     }
569
570                     //the good one
571                     pCase->getBody()->accept(*this);
572
573                     if (e.isBreakable() && pCase->getBody()->isBreak())
574                     {
575                         const_cast<SelectExp*>(&e)->setBreak();
576                         pCase->getBody()->resetBreak();
577                     }
578
579                     if (e.isContinuable() && pCase->getBody()->isContinue())
580                     {
581                         const_cast<SelectExp*>(&e)->setContinue();
582                         pCase->getBody()->resetContinue();
583                     }
584
585                     if (e.isReturnable() && pCase->getBody()->isReturn())
586                     {
587                         const_cast<SelectExp*>(&e)->setReturn();
588                         pCase->getBody()->resetReturn();
589                     }
590
591                     bCase = true;
592                     break;
593                 }
594             }
595         }
596     }
597
598     if (bCase == false && e.getDefaultCase() != NULL)
599     {
600         if (e.isBreakable())
601         {
602             const_cast<SelectExp*>(&e)->resetBreak();
603             e.getDefaultCase()->setBreakable();
604         }
605
606         if (e.isContinuable())
607         {
608             const_cast<SelectExp*>(&e)->resetContinue();
609             e.getDefaultCase()->setContinuable();
610         }
611
612         if (e.isReturnable())
613         {
614             const_cast<SelectExp*>(&e)->resetReturn();
615             e.getDefaultCase()->setReturnable();
616         }
617
618         //default case
619         e.getDefaultCase()->accept(*this);
620
621         if (e.isBreakable() && e.getDefaultCase()->isBreak())
622         {
623             const_cast<SelectExp*>(&e)->setBreak();
624             e.getDefaultCase()->resetBreak();
625         }
626
627         if (e.isContinuable() && e.getDefaultCase()->isContinue())
628         {
629             const_cast<SelectExp*>(&e)->setContinue();
630             e.getDefaultCase()->resetContinue();
631         }
632
633         if (e.isReturnable() && e.getDefaultCase()->isReturn())
634         {
635             const_cast<SelectExp*>(&e)->setReturn();
636             e.getDefaultCase()->resetReturn();
637         }
638     }
639
640     clearResult();
641 }
642
643 template <class T>
644 void RunVisitorT<T>::visitprivate(const SeqExp  &e)
645 {
646     //T execMe;
647     std::list<Exp *>::const_iterator        itExp;
648
649     for (itExp = e.getExps().begin (); itExp != e.getExps().end (); ++itExp)
650     {
651         if (e.isBreakable())
652         {
653             (*itExp)->resetBreak();
654             (*itExp)->setBreakable();
655         }
656
657         if (e.isContinuable())
658         {
659             (*itExp)->resetContinue();
660             (*itExp)->setContinuable();
661         }
662
663         if (e.isReturnable())
664         {
665             (*itExp)->setReturnable();
666         }
667
668         try
669         {
670             //reset default values
671             setResult(NULL);
672             setExpectedSize(-1);
673             (*itExp)->accept(*this);
674             InternalType * pIT = getResult();
675
676             if (pIT != NULL)
677             {
678                 bool bImplicitCall = false;
679                 if (pIT->isCallable()) //to manage call without ()
680                 {
681                     Callable *pCall = pIT->getAs<Callable>();
682                     typed_list out;
683                     typed_list in;
684                     optional_list opt;
685
686                     try
687                     {
688                         //in this case of calling, we can return only one values
689                         int iSaveExpectedSize = getExpectedSize();
690                         setExpectedSize(1);
691                         Function::ReturnValue Ret = pCall->call(in, opt, getExpectedSize(), out, this);
692                         setExpectedSize(iSaveExpectedSize);
693
694                         if (Ret == Callable::OK)
695                         {
696                             if (out.size() == 0)
697                             {
698                                 setResult(NULL);
699                             }
700                             else
701                             {
702                                 setResult(out[0]);
703                             }
704                             bImplicitCall = true;
705                         }
706                         else if (Ret == Callable::Error)
707                         {
708                             if (ConfigVariable::getLastErrorFunction() == L"")
709                             {
710                                 ConfigVariable::setLastErrorFunction(pCall->getName());
711                                 ConfigVariable::setLastErrorLine(e.getLocation().first_line);
712                                 throw ScilabError();
713                             }
714
715                             if (pCall->isMacro() || pCall->isMacroFile())
716                             {
717                                 wchar_t szError[bsiz];
718                                 os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), (*itExp)->getLocation().first_line, pCall->getName().c_str());
719                                 throw ScilabMessage(szError);
720                             }
721                             else
722                             {
723                                 throw ScilabMessage();
724                             }
725                         }
726                     }
727                     catch (ScilabMessage sm)
728                     {
729                         wostringstream os;
730                         PrintVisitor printMe(os);
731                         (*itExp)->accept(printMe);
732                         //os << std::endl << std::endl;
733                         if (ConfigVariable::getLastErrorFunction() == L"")
734                         {
735                             ConfigVariable::setLastErrorFunction(pCall->getName());
736                         }
737
738                         if (pCall->isMacro() || pCall->isMacroFile())
739                         {
740                             wchar_t szError[bsiz];
741                             os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), sm.GetErrorLocation().first_line, pCall->getName().c_str());
742                             throw ScilabMessage(szError + os.str());
743                         }
744                         else
745                         {
746                             sm.SetErrorMessage(sm.GetErrorMessage() + os.str());
747                             throw sm;
748                         }
749                     }
750                 }
751
752                 //don't output Simplevar and empty result
753                 if (getResult() != NULL && (!(*itExp)->isSimpleVar() || bImplicitCall))
754                 {
755                     //symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), *execMe.getResult());
756                     InternalType* pITAns = getResult();
757                     symbol::Context::getInstance()->put(m_pAns, pITAns);
758                     if ((*itExp)->isVerbose() && ConfigVariable::isPromptShow())
759                     {
760                         //TODO manage multiple returns
761                         scilabWriteW(L" ans  =\n\n");
762                         VariableToString(pITAns, L"ans");
763                     }
764                 }
765
766                 pIT->killMe();
767             }
768
769             if ((&e)->isBreakable() && (*itExp)->isBreak())
770             {
771                 const_cast<SeqExp *>(&e)->setBreak();
772                 break;
773             }
774
775             if ((&e)->isContinuable() && (*itExp)->isContinue())
776             {
777                 const_cast<SeqExp *>(&e)->setContinue();
778                 break;
779             }
780
781             if ((&e)->isReturnable() && (*itExp)->isReturn())
782             {
783                 const_cast<SeqExp *>(&e)->setReturn();
784                 (*itExp)->resetReturn();
785                 break;
786             }
787         }
788         catch (const ScilabMessage& sm)
789         {
790             scilabErrorW(sm.GetErrorMessage().c_str());
791
792             CallExp* pCall = dynamic_cast<CallExp*>(*itExp);
793             if (pCall != NULL)
794             {
795                 //to print call expression only of it is a macro
796                 pCall->getName().accept(*this);
797
798                 if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
799                 {
800                     wostringstream os;
801                     PrintVisitor printMe(os);
802                     pCall->accept(printMe);
803                     //os << std::endl << std::endl;
804                     if (ConfigVariable::getLastErrorFunction() == L"")
805                     {
806                         ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
807                     }
808                     throw ScilabMessage(os.str(), 0, (*itExp)->getLocation());
809                 }
810             }
811
812             throw ScilabMessage((*itExp)->getLocation());
813         }
814         catch (const ScilabError& se)
815         {
816             // check on error number because error message can be empty.
817             if (ConfigVariable::getLastErrorNumber() == 0)
818             {
819                 ConfigVariable::setLastErrorMessage(se.GetErrorMessage());
820                 ConfigVariable::setLastErrorNumber(se.GetErrorNumber());
821                 ConfigVariable::setLastErrorLine(se.GetErrorLocation().first_line);
822                 ConfigVariable::setLastErrorFunction(wstring(L""));
823             }
824
825             CallExp* pCall = dynamic_cast<CallExp*>(*itExp);
826             if (pCall != NULL)
827             {
828                 //to print call expression only of it is a macro
829                 try
830                 {
831                     pCall->getName().accept(*this);
832                     if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
833                     {
834                         wostringstream os;
835                         PrintVisitor printMe(os);
836                         pCall->accept(printMe);
837                         //os << std::endl << std::endl;
838                         ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
839                         scilabErrorW(se.GetErrorMessage().c_str());
840                         throw ScilabMessage(os.str(), 999, (*itExp)->getLocation());
841                     }
842                 }
843                 catch (ScilabError se2)
844                 {
845                     //just to catch exception, do nothing
846                 }
847             }
848
849             scilabErrorW(se.GetErrorMessage().c_str());
850             scilabErrorW(L"\n");
851             throw ScilabMessage((*itExp)->getLocation());
852         }
853
854         // If something other than NULL is given to setResult, then that would imply
855         // to make a cleanup in visit(ForExp) for example (e.getBody().accept(*this);)
856         setResult(NULL);
857     }
858 }
859
860 template <class T>
861 void RunVisitorT<T>::visitprivate(const NotExp &e)
862 {
863     /*
864       @ or ~ !
865     */
866     e.getExp().accept(*this);
867
868     InternalType * pValue = getResult();
869     InternalType * pReturn = NULL;
870     if (pValue->neg(pReturn))
871     {
872         if (pValue != pReturn)
873         {
874             pValue->killMe();
875         }
876
877         setResult(pReturn);
878     }
879     else
880     {
881         // neg returned false so the negation is not possible so we call the overload (%foo_5)
882         types::typed_list in;
883         types::typed_list out;
884
885         pValue->IncreaseRef();
886         in.push_back(pValue);
887
888         Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_5", in, 1, out, this);
889
890         if (Ret != Callable::OK)
891         {
892             cleanInOut(in, out);
893             throw ScilabError();
894         }
895
896         setResult(out);
897         cleanIn(in, out);
898     }
899 }
900
901 template <class T>
902 void RunVisitorT<T>::visitprivate(const TransposeExp &e)
903 {
904     e.getExp().accept(*this);
905
906     if (getResultSize() != 1)
907     {
908         clearResult();
909         wchar_t szError[bsiz];
910         os_swprintf(szError, bsiz, _W("%ls: Can not transpose multiple elements.\n").c_str(), L"Transpose");
911         throw ScilabError(szError, 999, e.getLocation());
912     }
913
914     InternalType * pValue = getResult();
915     InternalType * pReturn = NULL;
916     const bool bConjug = e.getConjugate() == TransposeExp::_Conjugate_;
917
918     if ((bConjug && pValue->adjoint(pReturn)) || (!bConjug && pValue->transpose(pReturn)))
919     {
920         if (pValue != pReturn)
921         {
922             pValue->killMe();
923         }
924
925         setResult(pReturn);
926
927         return;
928     }
929     else
930     {
931         // transpose returned false so the negation is not possible so we call the overload (%foo_t or %foo_0)
932         types::typed_list in;
933         types::typed_list out;
934
935         pValue->IncreaseRef();
936         in.push_back(pValue);
937
938         Callable::ReturnValue Ret;
939         if (bConjug)
940         {
941             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_t", in, 1, out, this);
942         }
943         else
944         {
945             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_0", in, 1, out, this);
946         }
947
948         if (Ret != Callable::OK)
949         {
950             cleanInOut(in, out);
951             throw ScilabError();
952         }
953
954         setResult(out);
955         cleanIn(in, out);
956     }
957 }
958
959 template <class T>
960 void RunVisitorT<T>::visitprivate(const FunctionDec & e)
961 {
962     /*
963       function foo
964       endfunction
965     */
966
967     // funcprot(0) : do nothing
968     // funcprot(1) && warning(on) : warning
969     //get input parameters list
970     std::list<symbol::Variable*> *pVarList = new std::list<symbol::Variable*>();
971     const ArrayListVar *pListVar = &e.getArgs();
972     for (std::list<Var *>::const_iterator i = pListVar->getVars().begin(), end = pListVar->getVars().end(); i != end; ++i)
973     {
974         pVarList->push_back(static_cast<SimpleVar*>(*i)->getStack());
975     }
976
977     //get output parameters list
978     std::list<symbol::Variable*> *pRetList = new std::list<symbol::Variable*>();
979     const ArrayListVar *pListRet = &e.getReturns();
980     for (std::list<Var *>::const_iterator i = pListRet->getVars().begin(), end = pListRet->getVars().end(); i != end; ++i)
981     {
982         pRetList->push_back(static_cast<SimpleVar*>(*i)->getStack());
983     }
984
985     types::Macro *pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList,
986                                             const_cast<SeqExp&>(static_cast<const SeqExp&>(e.getBody())), L"script");
987     pMacro->setFirstLine(e.getLocation().first_line);
988
989     bool bEquals = false;
990     int iFuncProt = ConfigVariable::getFuncprot();
991     if (iFuncProt != 0)
992     {
993         types::InternalType* pITFunc = symbol::Context::getInstance()->get(((FunctionDec&)e).getStack());
994         if (pITFunc && pITFunc->isCallable())
995         {
996             if (pITFunc->isMacroFile())
997             {
998                 types::MacroFile* pMF = pITFunc->getAs<types::MacroFile>();
999                 bEquals = *pMF->getMacro() == *pMacro;
1000             }
1001             else if (pITFunc->isMacro())
1002             {
1003                 types::Macro* pM = pITFunc->getAs<types::Macro>();
1004                 bEquals = *pM == *pMacro;
1005             }
1006         }
1007         else
1008         {
1009             bEquals = true; //avoid msg but keep assignation
1010         }
1011     }
1012
1013     if (bEquals == false && iFuncProt == 1 && ConfigVariable::getWarningMode())
1014     {
1015         wchar_t pwstFuncName[1024];
1016         os_swprintf(pwstFuncName, 1024, L"%-24ls", e.getSymbol().getName().c_str());
1017         char* pstFuncName = wide_string_to_UTF8(pwstFuncName);
1018
1019         sciprint(_("Warning : redefining function: %s. Use funcprot(0) to avoid this message"), pstFuncName);
1020         sciprint("\n");
1021         FREE(pstFuncName);
1022     }
1023     else if (bEquals == false && iFuncProt == 2)
1024     {
1025         char pstError[1024];
1026         char* pstFuncName = wide_string_to_UTF8(e.getSymbol().getName().c_str());
1027         sprintf(pstError, _("It is not possible to redefine the %s primitive this way (see clearfun).\n"), pstFuncName);
1028         wchar_t* pwstError = to_wide_string(pstError);
1029         std::wstring wstError(pwstError);
1030         FREE(pstFuncName);
1031         FREE(pwstError);
1032         throw ScilabError(wstError, 999, e.getLocation());
1033     }
1034
1035     symbol::Context::getInstance()->addMacro(pMacro);
1036
1037 }
1038
1039 template <class T>
1040 void RunVisitorT<T>::visitprivate(const ListExp &e)
1041 {
1042     e.getStart().accept(*this);
1043     GenericType* pITStart = static_cast<GenericType*>(getResult());
1044     if ((pITStart->getSize() != 1 || (pITStart->isDouble() && pITStart->getAs<Double>()->isComplex())) &&
1045             pITStart->isList() == false) // list case => call overload
1046     {
1047         pITStart->killMe();
1048         wchar_t szError[bsiz];
1049         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 1);
1050         throw ScilabError(szError, 999, e.getLocation());
1051     }
1052     InternalType * piStart = pITStart;
1053
1054     e.getStep().accept(*this);
1055     GenericType* pITStep = static_cast<GenericType*>(getResult());
1056     if ((pITStep->getSize() != 1 || (pITStep->isDouble() && pITStep->getAs<Double>()->isComplex())) &&
1057             pITStep->isList() == false) // list case => call overload
1058     {
1059         pITStart->killMe();
1060         pITStep->killMe();
1061         wchar_t szError[bsiz];
1062         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2);
1063         throw ScilabError(szError, 999, e.getLocation());
1064     }
1065     InternalType* piStep = pITStep;
1066
1067     e.getEnd().accept(*this);
1068     GenericType* pITEnd = static_cast<GenericType*>(getResult());
1069     if ((pITEnd->getSize() != 1 || (pITEnd->isDouble() && pITEnd->getAs<Double>()->isComplex())) &&
1070             pITEnd->isList() == false) // list case => call overload
1071     {
1072         pITStart->killMe();
1073         pITStep->killMe();
1074         pITEnd->killMe();
1075         wchar_t szError[bsiz];
1076         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 3);
1077         throw ScilabError(szError, 999, e.getLocation());
1078     }
1079     InternalType* piEnd = pITEnd;
1080
1081     //check compatibility
1082     // double : double : double or poly : poly : poly and mix like double : double : poly
1083     if ((piStart->isPoly() || piStart->isDouble()) &&
1084             (piStep->isPoly()  || piStep->isDouble())  &&
1085             (piEnd->isPoly()   || piEnd->isDouble()))
1086     {
1087         // No need to kill piStart, ... because Implicit list ctor will incref them
1088         setResult(new ImplicitList(piStart, piStep, piEnd));
1089         return;
1090     }
1091
1092     // int : double or int : int
1093     if ( piStart->isInt()   &&
1094             (piStep->isDouble() || piStep->isInt()) &&
1095             piEnd->isInt())
1096     {
1097         // check for same int type int8, int 16 ...
1098         if (piStart->getType() == piEnd->getType()  &&
1099                 (piStart->getType() == piStep->getType() ||
1100                  piStep->isDouble()))
1101         {
1102             // No need to kill piStart, ... because Implicit list ctor will incref them
1103             setResult(new ImplicitList(piStart, piStep, piEnd));
1104             return;
1105         }
1106     }
1107
1108     // Call Overload
1109     Callable::ReturnValue Ret;
1110     types::typed_list in;
1111     types::typed_list out;
1112
1113     piStart->IncreaseRef();
1114     piStep->IncreaseRef();
1115     piEnd->IncreaseRef();
1116
1117     in.push_back(piStart);
1118     if (e.hasExplicitStep())
1119     {
1120         // 1:2:4
1121         //call overload %typeStart_b_typeEnd
1122         in.push_back(piStep);
1123         in.push_back(piEnd);
1124         Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piStep->getShortTypeStr(), in, 1, out, this, true);
1125     }
1126     else
1127     {
1128         // 1:2
1129         //call overload %typeStart_b_typeStep
1130         in.push_back(piEnd);
1131         Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piEnd->getShortTypeStr(), in, 1, out, this, true);
1132     }
1133
1134     if (Ret != Callable::OK)
1135     {
1136         cleanInOut(in, out);
1137         throw ScilabError();
1138     }
1139
1140     setResult(out);
1141     cleanIn(in, out);
1142 }
1143
1144 #include "run_CallExp.cpp"
1145 #include "run_MatrixExp.cpp"
1146 #include "run_OpExp.cpp"
1147 #include "run_AssignExp.cpp"
1148 }
1149
1150 template EXTERN_AST class ast::RunVisitorT<ast::ExecVisitor>;
1151 template EXTERN_AST class ast::RunVisitorT<ast::StepVisitor>;
1152 template EXTERN_AST class ast::RunVisitorT<ast::TimedVisitor>;