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