SingleStruct clone and fieldExp corrected.
[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                         VariableToString(pITAns, L"ans");
752                     }
753                 }
754
755                 pIT->killMe();
756             }
757
758             if ((&e)->isBreakable() && (*itExp)->isBreak())
759             {
760                 const_cast<SeqExp *>(&e)->setBreak();
761                 break;
762             }
763
764             if ((&e)->isContinuable() && (*itExp)->isContinue())
765             {
766                 const_cast<SeqExp *>(&e)->setContinue();
767                 break;
768             }
769
770             if ((&e)->isReturnable() && (*itExp)->isReturn())
771             {
772                 const_cast<SeqExp *>(&e)->setReturn();
773                 (*itExp)->resetReturn();
774                 break;
775             }
776         }
777         catch (const ScilabMessage& sm)
778         {
779             scilabErrorW(sm.GetErrorMessage().c_str());
780
781             CallExp* pCall = dynamic_cast<CallExp*>(*itExp);
782             if (pCall != NULL)
783             {
784                 //to print call expression only of it is a macro
785                 pCall->getName().accept(*this);
786
787                 if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
788                 {
789                     wostringstream os;
790                     PrintVisitor printMe(os);
791                     pCall->accept(printMe);
792                     //os << std::endl << std::endl;
793                     if (ConfigVariable::getLastErrorFunction() == L"")
794                     {
795                         ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
796                     }
797                     throw ScilabMessage(os.str(), 0, (*itExp)->getLocation());
798                 }
799             }
800
801             throw ScilabMessage((*itExp)->getLocation());
802         }
803         catch (const ScilabError& se)
804         {
805             // check on error number because error message can be empty.
806             if (ConfigVariable::getLastErrorNumber() == 0)
807             {
808                 ConfigVariable::setLastErrorMessage(se.GetErrorMessage());
809                 ConfigVariable::setLastErrorNumber(se.GetErrorNumber());
810                 ConfigVariable::setLastErrorLine(se.GetErrorLocation().first_line);
811                 ConfigVariable::setLastErrorFunction(wstring(L""));
812             }
813
814             CallExp* pCall = dynamic_cast<CallExp*>(*itExp);
815             if (pCall != NULL)
816             {
817                 //to print call expression only of it is a macro
818                 try
819                 {
820                     pCall->getName().accept(*this);
821                     if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
822                     {
823                         wostringstream os;
824                         PrintVisitor printMe(os);
825                         pCall->accept(printMe);
826                         //os << std::endl << std::endl;
827                         ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
828                         scilabErrorW(se.GetErrorMessage().c_str());
829                         throw ScilabMessage(os.str(), 999, (*itExp)->getLocation());
830                     }
831                 }
832                 catch (ScilabError se2)
833                 {
834                     //just to catch exception, do nothing
835                 }
836             }
837
838             scilabErrorW(se.GetErrorMessage().c_str());
839             scilabErrorW(L"\n");
840             throw ScilabMessage((*itExp)->getLocation());
841         }
842
843         // If something other than NULL is given to setResult, then that would imply
844         // to make a cleanup in visit(ForExp) for example (e.getBody().accept(*this);)
845         setResult(NULL);
846     }
847 }
848
849 template <class T>
850 void RunVisitorT<T>::visitprivate(const NotExp &e)
851 {
852     /*
853       @ or ~ !
854     */
855     e.getExp().accept(*this);
856
857     InternalType * pValue = getResult();
858     InternalType * pReturn = NULL;
859     if (pValue->neg(pReturn))
860     {
861         if (pValue != pReturn)
862         {
863             pValue->killMe();
864         }
865
866         setResult(pReturn);
867     }
868     else
869     {
870         // neg returned false so the negation is not possible so we call the overload (%foo_5)
871         types::typed_list in;
872         types::typed_list out;
873
874         pValue->IncreaseRef();
875         in.push_back(pValue);
876
877         Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_5", in, 1, out, this);
878
879         if (Ret != Callable::OK)
880         {
881             cleanInOut(in, out);
882             throw ScilabError();
883         }
884
885         setResult(out);
886         cleanIn(in, out);
887     }
888 }
889
890 template <class T>
891 void RunVisitorT<T>::visitprivate(const TransposeExp &e)
892 {
893     e.getExp().accept(*this);
894
895     if (getResultSize() != 1)
896     {
897         clearResult();
898         wchar_t szError[bsiz];
899         os_swprintf(szError, bsiz, _W("%ls: Can not transpose multiple elements.\n").c_str(), L"Transpose");
900         throw ScilabError(szError, 999, e.getLocation());
901     }
902
903     InternalType * pValue = getResult();
904     InternalType * pReturn = NULL;
905     const bool bConjug = e.getConjugate() == TransposeExp::_Conjugate_;
906
907     if ((bConjug && pValue->adjoint(pReturn)) || (!bConjug && pValue->transpose(pReturn)))
908     {
909         if (pValue != pReturn)
910         {
911             pValue->killMe();
912         }
913
914         setResult(pReturn);
915
916         return;
917     }
918     else
919     {
920         // transpose returned false so the negation is not possible so we call the overload (%foo_t or %foo_0)
921         types::typed_list in;
922         types::typed_list out;
923
924         pValue->IncreaseRef();
925         in.push_back(pValue);
926
927         Callable::ReturnValue Ret;
928         if (bConjug)
929         {
930             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_t", in, 1, out, this);
931         }
932         else
933         {
934             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_0", in, 1, out, this);
935         }
936
937         if (Ret != Callable::OK)
938         {
939             cleanInOut(in, out);
940             throw ScilabError();
941         }
942
943         setResult(out);
944         cleanIn(in, out);
945     }
946 }
947
948 template <class T>
949 void RunVisitorT<T>::visitprivate(const FunctionDec & e)
950 {
951     /*
952       function foo
953       endfunction
954     */
955
956     // funcprot(0) : do nothing
957     // funcprot(1) && warning(on) : warning
958     //get input parameters list
959     std::list<symbol::Variable*> *pVarList = new std::list<symbol::Variable*>();
960     const ArrayListVar *pListVar = &e.getArgs();
961     for (std::list<Var *>::const_iterator i = pListVar->getVars().begin(), end = pListVar->getVars().end(); i != end; ++i)
962     {
963         pVarList->push_back(static_cast<SimpleVar*>(*i)->getStack());
964     }
965
966     //get output parameters list
967     std::list<symbol::Variable*> *pRetList = new std::list<symbol::Variable*>();
968     const ArrayListVar *pListRet = &e.getReturns();
969     for (std::list<Var *>::const_iterator i = pListRet->getVars().begin(), end = pListRet->getVars().end(); i != end; ++i)
970     {
971         pRetList->push_back(static_cast<SimpleVar*>(*i)->getStack());
972     }
973
974     types::Macro *pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList,
975                                             const_cast<SeqExp&>(static_cast<const SeqExp&>(e.getBody())), L"script");
976     pMacro->setFirstLine(e.getLocation().first_line);
977
978     bool bEquals = false;
979     int iFuncProt = ConfigVariable::getFuncprot();
980     if (iFuncProt != 0)
981     {
982         types::InternalType* pITFunc = symbol::Context::getInstance()->get(((FunctionDec&)e).getStack());
983         if (pITFunc && pITFunc->isCallable())
984         {
985             if (pITFunc->isMacroFile())
986             {
987                 types::MacroFile* pMF = pITFunc->getAs<types::MacroFile>();
988                 bEquals = *pMF->getMacro() == *pMacro;
989             }
990             else if (pITFunc->isMacro())
991             {
992                 types::Macro* pM = pITFunc->getAs<types::Macro>();
993                 bEquals = *pM == *pMacro;
994             }
995         }
996         else
997         {
998             bEquals = true; //avoid msg but keep assignation
999         }
1000     }
1001
1002     if (bEquals == false && iFuncProt == 1 && ConfigVariable::getWarningMode())
1003     {
1004         wchar_t pwstFuncName[1024];
1005         os_swprintf(pwstFuncName, 1024, L"%-24ls", e.getSymbol().getName().c_str());
1006         char* pstFuncName = wide_string_to_UTF8(pwstFuncName);
1007
1008         sciprint(_("Warning : redefining function: %s. Use funcprot(0) to avoid this message"), pstFuncName);
1009         sciprint("\n");
1010         FREE(pstFuncName);
1011     }
1012     else if (bEquals == false && iFuncProt == 2)
1013     {
1014         char pstError[1024];
1015         char* pstFuncName = wide_string_to_UTF8(e.getSymbol().getName().c_str());
1016         sprintf(pstError, _("It is not possible to redefine the %s primitive this way (see clearfun).\n"), pstFuncName);
1017         wchar_t* pwstError = to_wide_string(pstError);
1018         std::wstring wstError(pwstError);
1019         FREE(pstFuncName);
1020         FREE(pwstError);
1021         throw ScilabError(wstError, 999, e.getLocation());
1022     }
1023
1024     symbol::Context::getInstance()->addMacro(pMacro);
1025
1026 }
1027
1028 template <class T>
1029 void RunVisitorT<T>::visitprivate(const ListExp &e)
1030 {
1031     e.getStart().accept(*this);
1032     GenericType* pITStart = static_cast<GenericType*>(getResult());
1033     if ((pITStart->getSize() != 1 || (pITStart->isDouble() && pITStart->getAs<Double>()->isComplex())) &&
1034             pITStart->isList() == false) // list case => call overload
1035     {
1036         pITStart->killMe();
1037         wchar_t szError[bsiz];
1038         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 1);
1039         throw ScilabError(szError, 999, e.getLocation());
1040     }
1041     InternalType * piStart = pITStart;
1042
1043     e.getStep().accept(*this);
1044     GenericType* pITStep = static_cast<GenericType*>(getResult());
1045     if ((pITStep->getSize() != 1 || (pITStep->isDouble() && pITStep->getAs<Double>()->isComplex())) &&
1046             pITStep->isList() == false) // list case => call overload
1047     {
1048         pITStart->killMe();
1049         pITStep->killMe();
1050         wchar_t szError[bsiz];
1051         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2);
1052         throw ScilabError(szError, 999, e.getLocation());
1053     }
1054     InternalType* piStep = pITStep;
1055
1056     e.getEnd().accept(*this);
1057     GenericType* pITEnd = static_cast<GenericType*>(getResult());
1058     if ((pITEnd->getSize() != 1 || (pITEnd->isDouble() && pITEnd->getAs<Double>()->isComplex())) &&
1059             pITEnd->isList() == false) // list case => call overload
1060     {
1061         pITStart->killMe();
1062         pITStep->killMe();
1063         pITEnd->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"':'", 3);
1066         throw ScilabError(szError, 999, e.getLocation());
1067     }
1068     InternalType* piEnd = pITEnd;
1069
1070     //check compatibility
1071     // double : double : double or poly : poly : poly and mix like double : double : poly
1072     if ((piStart->isPoly() || piStart->isDouble()) &&
1073             (piStep->isPoly()  || piStep->isDouble())  &&
1074             (piEnd->isPoly()   || piEnd->isDouble()))
1075     {
1076         // No need to kill piStart, ... because Implicit list ctor will incref them
1077         setResult(new ImplicitList(piStart, piStep, piEnd));
1078         return;
1079     }
1080
1081     // int : double or int : int
1082     if ( piStart->isInt()   &&
1083             (piStep->isDouble() || piStep->isInt()) &&
1084             piEnd->isInt())
1085     {
1086         // check for same int type int8, int 16 ...
1087         if (piStart->getType() == piEnd->getType()  &&
1088                 (piStart->getType() == piStep->getType() ||
1089                  piStep->isDouble()))
1090         {
1091             // No need to kill piStart, ... because Implicit list ctor will incref them
1092             setResult(new ImplicitList(piStart, piStep, piEnd));
1093             return;
1094         }
1095     }
1096
1097     // Call Overload
1098     Callable::ReturnValue Ret;
1099     types::typed_list in;
1100     types::typed_list out;
1101
1102     piStart->IncreaseRef();
1103     piStep->IncreaseRef();
1104     piEnd->IncreaseRef();
1105
1106     in.push_back(piStart);
1107     if (e.hasExplicitStep())
1108     {
1109         // 1:2:4
1110         //call overload %typeStart_b_typeEnd
1111         in.push_back(piStep);
1112         in.push_back(piEnd);
1113         Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piStep->getShortTypeStr(), in, 1, out, this, true);
1114     }
1115     else
1116     {
1117         // 1:2
1118         //call overload %typeStart_b_typeStep
1119         in.push_back(piEnd);
1120         Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piEnd->getShortTypeStr(), in, 1, out, this, true);
1121     }
1122
1123     if (Ret != Callable::OK)
1124     {
1125         cleanInOut(in, out);
1126         throw ScilabError();
1127     }
1128
1129     setResult(out);
1130     cleanIn(in, out);
1131 }
1132
1133 #include "run_CallExp.cpp"
1134 #include "run_MatrixExp.cpp"
1135 #include "run_OpExp.cpp"
1136 #include "run_AssignExp.cpp"
1137 }
1138
1139 template EXTERN_AST class ast::RunVisitorT<ast::ExecVisitor>;
1140 template EXTERN_AST class ast::RunVisitorT<ast::StepVisitor>;
1141 template EXTERN_AST class ast::RunVisitorT<ast::TimedVisitor>;