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