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