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