65ee037601fb404c319acb4e87cbeae4d0b92ab6
[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 #include "elem_common.h"
39 }
40
41
42
43 namespace ast
44 {
45 template <class T>
46 void RunVisitorT<T>::visitprivate(const CellExp &e)
47 {
48     exps_t::const_iterator row;
49     exps_t::const_iterator col;
50     int iColMax = 0;
51
52     exps_t lines = e.getLines();
53     //check dimmension
54     for (row = lines.begin() ; row != lines.end() ; ++row )
55     {
56         exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
57         if (iColMax == 0)
58         {
59             iColMax = static_cast<int>(cols.size());
60         }
61
62         if (iColMax != static_cast<int>(cols.size()))
63         {
64             std::wostringstream os;
65             os << _W("inconsistent row/column dimensions\n");
66             //os << ((Location)(*row)->getLocation()).getLocationString() << std::endl;
67             throw ScilabError(os.str(), 999, (*row)->getLocation());
68         }
69     }
70
71     //alloc result cell
72     types::Cell *pC = new types::Cell(static_cast<int>(lines.size()), iColMax);
73
74     int i = 0;
75     int j = 0;
76
77     //insert items in cell
78     for (i = 0, row = lines.begin() ; row != lines.end() ; ++row, ++i)
79     {
80         exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
81         for (j = 0, col = cols.begin() ; col != cols.end() ; ++col, ++j)
82         {
83             (*col)->accept(*this);
84             InternalType *pIT = getResult();
85             if (pIT->isImplicitList())
86             {
87                 InternalType * _pIT = pIT->getAs<ImplicitList>()->extractFullMatrix();
88                 pC->set(i, j, _pIT);
89                 _pIT->killMe();
90             }
91             else
92             {
93                 pC->set(i, j, pIT);
94             }
95             clearResult();
96         }
97     }
98
99     //return new cell
100     setResult(pC);
101 }
102
103 template <class T>
104 void RunVisitorT<T>::visitprivate(const FieldExp &e)
105 {
106     /*
107       a.b
108     */
109
110     if (!e.getTail()->isSimpleVar())
111     {
112         wchar_t szError[bsiz];
113         os_swprintf(szError, bsiz, _W("/!\\ Unmanaged FieldExp.\n").c_str());
114         throw ScilabError(szError, 999, e.getLocation());
115     }
116
117     try
118     {
119         e.getHead()->accept(*this);
120     }
121     catch (const ScilabError& error)
122     {
123         throw error;
124     }
125
126     if (getResult() == NULL)
127     {
128         wchar_t szError[bsiz];
129         os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
130         throw ScilabError(szError, 999, e.getLocation());
131     }
132
133     // TODO: handle case where getSize() > 1
134     // l=list(struct("toto","coucou"),struct("toto","hello"),1,2);[a,b]=l(1:2).toto
135     //
136     if (getResultSize() > 1)
137     {
138         clearResult();
139         wchar_t szError[bsiz];
140         os_swprintf(szError, bsiz, _W("Not yet implemented in Scilab.\n").c_str());
141         throw ScilabError(szError, 999, e.getLocation());
142     }
143
144     SimpleVar * psvRightMember = static_cast<SimpleVar *>(const_cast<Exp *>(e.getTail()));
145     std::wstring wstField = psvRightMember->getSymbol().getName();
146     InternalType * pValue = getResult();
147     InternalType * pReturn = NULL;
148     bool ok = false;
149
150     try
151     {
152         if (pValue->isGenericType())
153         {
154             ok = pValue->getAs<GenericType>()->extract(wstField, pReturn);
155         }
156     }
157     catch (std::wstring & err)
158     {
159         pValue->killMe();
160         throw ScilabError(err.c_str(), 999, e.getTail()->getLocation());
161     }
162
163     if (ok)
164     {
165         if (pReturn == NULL)
166         {
167             std::wostringstream os;
168             os << _W("Invalid index.\n");
169             throw ScilabError(os.str(), 999, e.getLocation());
170         }
171
172         setResult(pReturn);
173         pValue->killMe();
174     }
175     else if (pValue->isFieldExtractionOverloadable())
176     {
177         types::typed_list in;
178         types::typed_list out;
179
180         String* pS = new String(wstField.c_str());
181
182         //TODO: in the case where overload is a macro there is no need to incref in
183         // because args will be put in context, removed and killed if required.
184         // But if the overload is a function... it is another story...
185
186         pS->IncreaseRef();
187         pValue->IncreaseRef();
188
189         in.push_back(pS);
190         in.push_back(pValue);
191         Callable::ReturnValue Ret = Callable::Error;
192
193         try
194         {
195             Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_e", in, 1, out, this);
196         }
197         catch (ast::ScilabError & se)
198         {
199             // TList or Mlist
200             if (pValue->isList())
201             {
202                 Ret = Overload::call(L"%l_e", in, 1, out, this);
203             }
204             else
205             {
206                 throw se;
207             }
208         }
209
210         if (Ret != Callable::OK)
211         {
212             cleanInOut(in, out);
213             throw ScilabError();
214         }
215
216         setResult(out);
217         cleanIn(in, out);
218     }
219     else
220     {
221         pValue->killMe();
222         wchar_t szError[bsiz];
223         os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
224         throw ScilabError(szError, 999, e.getLocation());
225     }
226 }
227
228 template <class T>
229 void RunVisitorT<T>::visitprivate(const IfExp  &e)
230 {
231     //Create local exec visitor
232     ShortCutVisitor SCTest;
233     bool bTestStatus = false;
234
235     //condition
236     e.getTest().accept(SCTest);
237     e.getTest().accept(*this);
238
239     bTestStatus = getResult()->isTrue();
240     clearResult();
241     if (bTestStatus == true)
242     {
243         //condition == true
244         if (e.isBreakable())
245         {
246             const_cast<IfExp*>(&e)->resetBreak();
247             const_cast<Exp*>(&e.getThen())->setBreakable();
248         }
249
250         if (e.isContinuable())
251         {
252             const_cast<IfExp*>(&e)->resetContinue();
253             const_cast<Exp*>(&e.getThen())->setContinuable();
254         }
255
256         if (e.isReturnable())
257         {
258             const_cast<IfExp*>(&e)->resetReturn();
259             const_cast<Exp*>(&e.getThen())->setReturnable();
260         }
261
262         e.getThen().accept(*this);
263     }
264     else
265     {
266         //condition == false
267
268         if (e.hasElse())
269         {
270             if (e.isBreakable())
271             {
272                 const_cast<Exp*>(&e.getElse())->setBreakable();
273             }
274
275             if (e.isContinuable())
276             {
277                 const_cast<IfExp*>(&e)->resetContinue();
278                 const_cast<Exp*>(&e.getElse())->setContinuable();
279             }
280
281             if (e.isReturnable())
282             {
283                 const_cast<Exp*>(&e.getElse())->setReturnable();
284             }
285
286             e.getElse().accept(*this);
287         }
288     }
289
290     if (e.isBreakable()
291             && ( (&e.getElse())->isBreak()
292                  || (&e.getThen())->isBreak() ))
293     {
294         const_cast<IfExp*>(&e)->setBreak();
295         const_cast<Exp*>(&e.getElse())->resetBreak();
296         const_cast<Exp*>(&e.getThen())->resetBreak();
297     }
298
299     if (e.isContinuable()
300             && ( (&e.getElse())->isContinue()
301                  || (&e.getThen())->isContinue() ))
302     {
303         const_cast<IfExp*>(&e)->setContinue();
304         const_cast<Exp*>(&e.getElse())->resetContinue();
305         const_cast<Exp*>(&e.getThen())->resetContinue();
306     }
307
308     if (e.isReturnable()
309             && ( (&e.getElse())->isReturn()
310                  || (&e.getThen())->isReturn() ))
311     {
312         const_cast<IfExp*>(&e)->setReturn();
313         const_cast<Exp*>(&e.getElse())->resetReturn();
314         const_cast<Exp*>(&e.getThen())->resetReturn();
315     }
316 }
317
318 template <class T>
319 void RunVisitorT<T>::visitprivate(const WhileExp  &e)
320 {
321     //allow break and continue operations
322     const_cast<Exp*>(&e.getBody())->setBreakable();
323     const_cast<Exp*>(&e.getBody())->setContinuable();
324     //allow return operation
325     if (e.isReturnable())
326     {
327         const_cast<Exp*>(&(e.getBody()))->setReturnable();
328     }
329
330     //condition
331     e.getTest().accept(*this);
332     while (getResult()->isTrue())
333     {
334         e.getBody().accept(*this);
335         if (e.getBody().isBreak())
336         {
337             const_cast<Exp*>(&(e.getBody()))->resetBreak();
338             break;
339         }
340
341         if (e.getBody().isReturn())
342         {
343             const_cast<WhileExp*>(&e)->setReturn();
344             const_cast<Exp*>(&(e.getBody()))->resetReturn();
345             break;
346         }
347
348         if (e.getBody().isContinue())
349         {
350             const_cast<WhileExp*>(&e)->setContinue();
351             const_cast<Exp*>(&(e.getBody()))->resetContinue();
352             e.getTest().accept(*this);
353             continue;
354         }
355
356         //clear old result value before evaluate new one
357         if (getResult() != NULL)
358         {
359             getResult()->killMe();
360         }
361
362         e.getTest().accept(*this);
363     }
364
365     //clear result of condition or result of body
366     clearResult();
367 }
368
369 template <class T>
370 void RunVisitorT<T>::visitprivate(const ForExp  &e)
371 {
372     e.getVardec().accept(*this);
373     InternalType* pIT = getResult();
374     //allow break and continue operations
375     const_cast<Exp&>(e.getBody()).setBreakable();
376     const_cast<Exp&>(e.getBody()).setContinuable();
377
378     //allow return operation
379     if (e.isReturnable())
380     {
381         const_cast<Exp&>(e.getBody()).setReturnable();
382     }
383
384     if (pIT->isImplicitList())
385     {
386         ImplicitList* pVar = pIT->getAs<ImplicitList>();
387         for (int i = 0; i < pVar->getSize(); ++i)
388         {
389             //TODO : maybe it would be interesting here to reuse the same InternalType (to avoid delete/new)
390             InternalType * pIL = pVar->extractValue(i);
391             symbol::Context::getInstance()->put(e.getVardec().getAs<VarDec>()->getStack(), pIL);
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->isList())
414     {
415         List* pL = pIT->getAs<List>();
416         const int size = pL->getSize();
417         for (int i = 0; i < size; ++i)
418         {
419             InternalType* pNew = pL->get(i);
420             symbol::Context::getInstance()->put(e.getVardec().getAs<VarDec>()->getStack(), pNew);
421
422             e.getBody().accept(*this);
423             if (e.getBody().isBreak())
424             {
425                 const_cast<Exp*>(&(e.getBody()))->resetBreak();
426                 break;
427             }
428
429             if (e.getBody().isContinue())
430             {
431                 const_cast<Exp*>(&(e.getBody()))->resetContinue();
432                 continue;
433             }
434
435             if (e.getBody().isReturn())
436             {
437                 const_cast<ForExp*>(&e)->setReturn();
438                 break;
439             }
440         }
441     }
442     else if (pIT->isGenericType())
443     {
444         //Matrix i = [1,3,2,6] or other type
445         GenericType* pVar = pIT->getAs<GenericType>();
446         if (pVar->getDims() > 2)
447         {
448             pIT->DecreaseRef();
449             pIT->killMe();
450             throw ScilabError(_W("for expression can only manage 1 or 2 dimensions variables\n"), 999, e.getVardec().getLocation());
451         }
452
453         for (int i = 0; i < pVar->getCols(); i++)
454         {
455             GenericType* pNew = pVar->getColumnValues(i);
456             if (pNew == NULL)
457             {
458                 pIT->DecreaseRef();
459                 pIT->killMe();
460                 throw ScilabError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
461             }
462
463             symbol::Context::getInstance()->put(e.getVardec().getAs<VarDec>()->getStack(), pNew);
464
465             e.getBody().accept(*this);
466             if (e.getBody().isBreak())
467             {
468                 const_cast<Exp*>(&(e.getBody()))->resetBreak();
469                 break;
470             }
471
472             if (e.getBody().isContinue())
473             {
474                 const_cast<Exp*>(&(e.getBody()))->resetContinue();
475                 continue;
476             }
477
478             if (e.getBody().isReturn())
479             {
480                 const_cast<ForExp*>(&e)->setReturn();
481                 break;
482             }
483         }
484     }
485     else
486     {
487         pIT->DecreaseRef();
488         pIT->killMe();
489         throw ScilabError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
490     }
491
492     pIT->DecreaseRef();
493     pIT->killMe();
494
495     setResult(NULL);
496 }
497
498 template <class T>
499 void RunVisitorT<T>::visitprivate(const ReturnExp &e)
500 {
501     if (e.isGlobal())
502     {
503         if (ConfigVariable::getPauseLevel() != 0 && symbol::Context::getInstance()->getScopeLevel() == ConfigVariable::getActivePauseLevel())
504         {
505             //return or resume
506             ThreadId* pThreadId = ConfigVariable::getLastPausedThread();
507             if (pThreadId == NULL)
508             {
509                 //no paused thread, so just go leave
510                 return;
511             }
512
513             //force exit without prompt of current thread ( via Aborted status )
514             ThreadId* pMe = ConfigVariable::getThread(__GetCurrentThreadKey());
515             pMe->setStatus(ThreadId::Aborted);
516
517             //resume previous execution thread
518             pThreadId->resume();
519
520             return;
521         }
522         else
523         {
524             const_cast<ReturnExp*>(&e)->setReturn();
525         }
526     }
527     else
528     {
529         //return(x)
530
531         //in case of CallExp, we can return only one values
532         int iSaveExpectedSize = getExpectedSize();
533         setExpectedSize(1);
534         e.getExp().accept(*this);
535         setExpectedSize(iSaveExpectedSize);
536         const_cast<ReturnExp*>(&e)->setReturn();
537     }
538 }
539
540 template <class T>
541 void RunVisitorT<T>::visitprivate(const SelectExp &e)
542 {
543     // FIXME : exec select ... case ... else ... end
544     e.getSelect()->accept(*this);
545     bool bCase = false;
546
547
548     InternalType* pIT = getResult();
549     setResult(NULL);
550     if (pIT)
551     {
552         //find good case
553         exps_t::iterator it;
554         exps_t* cases = e.getCases();
555         for (it = cases->begin(); it != cases->end() ; it++)
556         {
557             CaseExp* pCase = (*it)->getAs<CaseExp>();
558             pCase->getTest()->accept(*this);
559             InternalType *pITCase = getResult();
560             setResult(NULL);
561             if (pITCase)
562             {
563                 if (pITCase->isContainer()) //WARNING ONLY FOR CELL
564                 {
565                     //check each item
566                 }
567                 else if (*pITCase == *pIT)
568                 {
569                     if (e.isBreakable())
570                     {
571                         const_cast<SelectExp*>(&e)->resetBreak();
572                         pCase->getBody()->setBreakable();
573                     }
574
575                     if (e.isContinuable())
576                     {
577                         const_cast<SelectExp*>(&e)->resetContinue();
578                         pCase->getBody()->setContinuable();
579                     }
580
581                     if (e.isReturnable())
582                     {
583                         const_cast<SelectExp*>(&e)->resetReturn();
584                         pCase->getBody()->setReturnable();
585                     }
586
587                     //the good one
588                     pCase->getBody()->accept(*this);
589
590                     if (e.isBreakable() && pCase->getBody()->isBreak())
591                     {
592                         const_cast<SelectExp*>(&e)->setBreak();
593                         pCase->getBody()->resetBreak();
594                     }
595
596                     if (e.isContinuable() && pCase->getBody()->isContinue())
597                     {
598                         const_cast<SelectExp*>(&e)->setContinue();
599                         pCase->getBody()->resetContinue();
600                     }
601
602                     if (e.isReturnable() && pCase->getBody()->isReturn())
603                     {
604                         const_cast<SelectExp*>(&e)->setReturn();
605                         pCase->getBody()->resetReturn();
606                     }
607
608                     bCase = true;
609                     break;
610                 }
611             }
612         }
613
614         delete cases;
615     }
616
617     if (bCase == false && e.getDefaultCase() != NULL)
618     {
619         if (e.isBreakable())
620         {
621             const_cast<SelectExp*>(&e)->resetBreak();
622             e.getDefaultCase()->setBreakable();
623         }
624
625         if (e.isContinuable())
626         {
627             const_cast<SelectExp*>(&e)->resetContinue();
628             e.getDefaultCase()->setContinuable();
629         }
630
631         if (e.isReturnable())
632         {
633             const_cast<SelectExp*>(&e)->resetReturn();
634             e.getDefaultCase()->setReturnable();
635         }
636
637         //default case
638         e.getDefaultCase()->accept(*this);
639
640         if (e.isBreakable() && e.getDefaultCase()->isBreak())
641         {
642             const_cast<SelectExp*>(&e)->setBreak();
643             e.getDefaultCase()->resetBreak();
644         }
645
646         if (e.isContinuable() && e.getDefaultCase()->isContinue())
647         {
648             const_cast<SelectExp*>(&e)->setContinue();
649             e.getDefaultCase()->resetContinue();
650         }
651
652         if (e.isReturnable() && e.getDefaultCase()->isReturn())
653         {
654             const_cast<SelectExp*>(&e)->setReturn();
655             e.getDefaultCase()->resetReturn();
656         }
657     }
658
659     clearResult();
660 }
661
662 template <class T>
663 void RunVisitorT<T>::visitprivate(const SeqExp  &e)
664 {
665     //T execMe;
666     exps_t::const_iterator itExp;
667     exps_t exps = e.getExps();
668
669     for (itExp = exps.begin (); itExp != exps.end (); ++itExp)
670     {
671         if (e.isBreakable())
672         {
673             (*itExp)->resetBreak();
674             (*itExp)->setBreakable();
675         }
676
677         if (e.isContinuable())
678         {
679             (*itExp)->resetContinue();
680             (*itExp)->setContinuable();
681         }
682
683         if (e.isReturnable())
684         {
685             (*itExp)->setReturnable();
686         }
687
688         try
689         {
690             //reset default values
691             setResult(NULL);
692             setExpectedSize(-1);
693             (*itExp)->accept(*this);
694             InternalType * pIT = getResult();
695
696             if (pIT != NULL)
697             {
698                 bool bImplicitCall = false;
699                 if (pIT->isCallable()) //to manage call without ()
700                 {
701                     Callable *pCall = pIT->getAs<Callable>();
702                     typed_list out;
703                     typed_list in;
704                     optional_list opt;
705
706                     try
707                     {
708                         //in this case of calling, we can return only one values
709                         int iSaveExpectedSize = getExpectedSize();
710                         setExpectedSize(1);
711                         Function::ReturnValue Ret = pCall->call(in, opt, getExpectedSize(), out, this);
712                         setExpectedSize(iSaveExpectedSize);
713
714                         if (Ret == Callable::OK)
715                         {
716                             if (out.size() == 0)
717                             {
718                                 setResult(NULL);
719                             }
720                             else
721                             {
722                                 setResult(out[0]);
723                             }
724                             bImplicitCall = true;
725                         }
726                         else if (Ret == Callable::Error)
727                         {
728                             if (ConfigVariable::getLastErrorFunction() == L"")
729                             {
730                                 ConfigVariable::setLastErrorFunction(pCall->getName());
731                                 ConfigVariable::setLastErrorLine(e.getLocation().first_line);
732                                 throw ScilabError();
733                             }
734
735                             if (pCall->isMacro() || pCall->isMacroFile())
736                             {
737                                 wchar_t szError[bsiz];
738                                 os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), (*itExp)->getLocation().first_line, pCall->getName().c_str());
739                                 throw ScilabMessage(szError);
740                             }
741                             else
742                             {
743                                 throw ScilabMessage();
744                             }
745                         }
746                     }
747                     catch (ScilabMessage sm)
748                     {
749                         wostringstream os;
750                         PrintVisitor printMe(os);
751                         (*itExp)->accept(printMe);
752                         //os << std::endl << std::endl;
753                         if (ConfigVariable::getLastErrorFunction() == L"")
754                         {
755                             ConfigVariable::setLastErrorFunction(pCall->getName());
756                         }
757
758                         if (pCall->isMacro() || pCall->isMacroFile())
759                         {
760                             wchar_t szError[bsiz];
761                             os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), sm.GetErrorLocation().first_line, pCall->getName().c_str());
762                             throw ScilabMessage(szError + os.str());
763                         }
764                         else
765                         {
766                             sm.SetErrorMessage(sm.GetErrorMessage() + os.str());
767                             throw sm;
768                         }
769                     }
770                 }
771
772                 //don't output Simplevar and empty result
773                 if (getResult() != NULL && (!(*itExp)->isSimpleVar() || bImplicitCall))
774                 {
775                     //symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), *execMe.getResult());
776                     InternalType* pITAns = getResult();
777                     symbol::Context::getInstance()->put(m_pAns, pITAns);
778                     if ((*itExp)->isVerbose() && ConfigVariable::isPromptShow())
779                     {
780                         //TODO manage multiple returns
781                         scilabWriteW(L" ans  =\n\n");
782                         std::wostringstream ostrName;
783                         ostrName << SPACES_LIST << L"ans";
784                         VariableToString(pITAns, ostrName.str().c_str());
785                     }
786                 }
787
788                 pIT->killMe();
789             }
790
791             if ((&e)->isBreakable() && (*itExp)->isBreak())
792             {
793                 const_cast<SeqExp *>(&e)->setBreak();
794                 break;
795             }
796
797             if ((&e)->isContinuable() && (*itExp)->isContinue())
798             {
799                 const_cast<SeqExp *>(&e)->setContinue();
800                 break;
801             }
802
803             if ((&e)->isReturnable() && (*itExp)->isReturn())
804             {
805                 const_cast<SeqExp *>(&e)->setReturn();
806                 (*itExp)->resetReturn();
807                 break;
808             }
809         }
810         catch (const ScilabMessage& sm)
811         {
812             scilabErrorW(sm.GetErrorMessage().c_str());
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                 pCall->getName().accept(*this);
819
820                 if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
821                 {
822                     wostringstream os;
823                     PrintVisitor printMe(os);
824                     pCall->accept(printMe);
825                     //os << std::endl << std::endl;
826                     if (ConfigVariable::getLastErrorFunction() == L"")
827                     {
828                         ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
829                     }
830                     throw ScilabMessage(os.str(), 0, (*itExp)->getLocation());
831                 }
832             }
833
834             throw ScilabMessage((*itExp)->getLocation());
835         }
836         catch (const ScilabError& se)
837         {
838             // check on error number because error message can be empty.
839             if (ConfigVariable::getLastErrorNumber() == 0)
840             {
841                 ConfigVariable::setLastErrorMessage(se.GetErrorMessage());
842                 ConfigVariable::setLastErrorNumber(se.GetErrorNumber());
843                 ConfigVariable::setLastErrorLine(se.GetErrorLocation().first_line);
844                 ConfigVariable::setLastErrorFunction(wstring(L""));
845             }
846
847             CallExp* pCall = dynamic_cast<CallExp*>(*itExp);
848             if (pCall != NULL)
849             {
850                 //to print call expression only of it is a macro
851                 try
852                 {
853                     pCall->getName().accept(*this);
854                     if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
855                     {
856                         wostringstream os;
857                         PrintVisitor printMe(os);
858                         pCall->accept(printMe);
859                         //os << std::endl << std::endl;
860                         ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
861                         scilabErrorW(se.GetErrorMessage().c_str());
862                         throw ScilabMessage(os.str(), 999, (*itExp)->getLocation());
863                     }
864                 }
865                 catch (ScilabError se2)
866                 {
867                     //just to catch exception, do nothing
868                 }
869             }
870
871             scilabErrorW(se.GetErrorMessage().c_str());
872             scilabErrorW(L"\n");
873             throw ScilabMessage((*itExp)->getLocation());
874         }
875
876         // If something other than NULL is given to setResult, then that would imply
877         // to make a cleanup in visit(ForExp) for example (e.getBody().accept(*this);)
878         setResult(NULL);
879     }
880 }
881
882 template <class T>
883 void RunVisitorT<T>::visitprivate(const NotExp &e)
884 {
885     /*
886       @ or ~ !
887     */
888     e.getExp().accept(*this);
889
890     InternalType * pValue = getResult();
891     InternalType * pReturn = NULL;
892     if (pValue->neg(pReturn))
893     {
894         if (pValue != pReturn)
895         {
896             pValue->killMe();
897         }
898
899         setResult(pReturn);
900     }
901     else
902     {
903         // neg returned false so the negation is not possible so we call the overload (%foo_5)
904         types::typed_list in;
905         types::typed_list out;
906
907         pValue->IncreaseRef();
908         in.push_back(pValue);
909
910         Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_5", in, 1, out, this);
911
912         if (Ret != Callable::OK)
913         {
914             cleanInOut(in, out);
915             throw ScilabError();
916         }
917
918         setResult(out);
919         cleanIn(in, out);
920     }
921 }
922
923 template <class T>
924 void RunVisitorT<T>::visitprivate(const TransposeExp &e)
925 {
926     e.getExp().accept(*this);
927
928     if (getResultSize() != 1)
929     {
930         clearResult();
931         wchar_t szError[bsiz];
932         os_swprintf(szError, bsiz, _W("%ls: Can not transpose multiple elements.\n").c_str(), L"Transpose");
933         throw ScilabError(szError, 999, e.getLocation());
934     }
935
936     InternalType * pValue = getResult();
937     InternalType * pReturn = NULL;
938     const bool bConjug = e.getConjugate() == TransposeExp::_Conjugate_;
939
940     if ((bConjug && pValue->adjoint(pReturn)) || (!bConjug && pValue->transpose(pReturn)))
941     {
942         if (pValue != pReturn)
943         {
944             pValue->killMe();
945         }
946
947         setResult(pReturn);
948
949         return;
950     }
951     else
952     {
953         // transpose returned false so the negation is not possible so we call the overload (%foo_t or %foo_0)
954         types::typed_list in;
955         types::typed_list out;
956
957         pValue->IncreaseRef();
958         in.push_back(pValue);
959
960         Callable::ReturnValue Ret;
961         if (bConjug)
962         {
963             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_t", in, 1, out, this);
964         }
965         else
966         {
967             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_0", in, 1, out, this);
968         }
969
970         if (Ret != Callable::OK)
971         {
972             cleanInOut(in, out);
973             throw ScilabError();
974         }
975
976         setResult(out);
977         cleanIn(in, out);
978     }
979 }
980
981 template <class T>
982 void RunVisitorT<T>::visitprivate(const FunctionDec & e)
983 {
984     /*
985       function foo
986       endfunction
987     */
988
989     // funcprot(0) : do nothing
990     // funcprot(1) && warning(on) : warning
991     //get input parameters list
992     std::list<symbol::Variable*> *pVarList = new std::list<symbol::Variable*>();
993     const ArrayListVar* pListVar = e.getArgs().getAs<ArrayListVar>();
994     exps_t vars = pListVar->getVars();
995     for (exps_t::const_iterator it = vars.begin(), end = vars.end(); it != end; ++it)
996     {
997         pVarList->push_back((*it)->getAs<SimpleVar>()->getStack());
998     }
999
1000     //get output parameters list
1001     std::list<symbol::Variable*> *pRetList = new std::list<symbol::Variable*>();
1002     const ArrayListVar *pListRet = e.getReturns().getAs<ArrayListVar>();
1003     exps_t rets = pListRet->getVars();
1004     for (exps_t::const_iterator it = rets.begin(), end = rets.end(); it != end; ++it)
1005     {
1006         pRetList->push_back((*it)->getAs<SimpleVar>()->getStack());
1007     }
1008
1009     types::Macro *pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList,
1010                                             *const_cast<SeqExp&>(static_cast<const SeqExp&>(e.getBody())).clone(), L"script");
1011     pMacro->setFirstLine(e.getLocation().first_line);
1012
1013     bool bEquals = false;
1014     int iFuncProt = ConfigVariable::getFuncprot();
1015     if (iFuncProt != 0)
1016     {
1017         types::InternalType* pITFunc = symbol::Context::getInstance()->get(((FunctionDec&)e).getStack());
1018         if (pITFunc && pITFunc->isCallable())
1019         {
1020             if (pITFunc->isMacroFile())
1021             {
1022                 types::MacroFile* pMF = pITFunc->getAs<types::MacroFile>();
1023                 bEquals = *pMF->getMacro() == *pMacro;
1024             }
1025             else if (pITFunc->isMacro())
1026             {
1027                 types::Macro* pM = pITFunc->getAs<types::Macro>();
1028                 bEquals = *pM == *pMacro;
1029             }
1030         }
1031         else
1032         {
1033             bEquals = true; //avoid msg but keep assignation
1034         }
1035     }
1036
1037     if (bEquals == false && iFuncProt == 1 && ConfigVariable::getWarningMode())
1038     {
1039         wchar_t pwstFuncName[1024];
1040         os_swprintf(pwstFuncName, 1024, L"%-24ls", e.getSymbol().getName().c_str());
1041         char* pstFuncName = wide_string_to_UTF8(pwstFuncName);
1042
1043         sciprint(_("Warning : redefining function: %s. Use funcprot(0) to avoid this message"), pstFuncName);
1044         sciprint("\n");
1045         FREE(pstFuncName);
1046     }
1047     else if (bEquals == false && iFuncProt == 2)
1048     {
1049         char pstError[1024];
1050         char* pstFuncName = wide_string_to_UTF8(e.getSymbol().getName().c_str());
1051         sprintf(pstError, _("It is not possible to redefine the %s primitive this way (see clearfun).\n"), pstFuncName);
1052         wchar_t* pwstError = to_wide_string(pstError);
1053         std::wstring wstError(pwstError);
1054         FREE(pstFuncName);
1055         FREE(pwstError);
1056         throw ScilabError(wstError, 999, e.getLocation());
1057     }
1058
1059     symbol::Context::getInstance()->addMacro(pMacro);
1060
1061 }
1062
1063 template <class T>
1064 void RunVisitorT<T>::visitprivate(const ListExp &e)
1065 {
1066     e.getStart().accept(*this);
1067     GenericType* pITStart = static_cast<GenericType*>(getResult());
1068     if ((pITStart->getSize() != 1 || (pITStart->isDouble() && pITStart->getAs<Double>()->isComplex())) &&
1069             pITStart->isList() == false) // list case => call overload
1070     {
1071         pITStart->killMe();
1072         wchar_t szError[bsiz];
1073         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 1);
1074         throw ScilabError(szError, 999, e.getLocation());
1075     }
1076     InternalType * piStart = pITStart;
1077
1078     e.getStep().accept(*this);
1079     GenericType* pITStep = static_cast<GenericType*>(getResult());
1080     if ((pITStep->getSize() != 1 || (pITStep->isDouble() && pITStep->getAs<Double>()->isComplex())) &&
1081             pITStep->isList() == false) // list case => call overload
1082     {
1083         pITStart->killMe();
1084         pITStep->killMe();
1085         wchar_t szError[bsiz];
1086         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2);
1087         throw ScilabError(szError, 999, e.getLocation());
1088     }
1089     InternalType* piStep = pITStep;
1090
1091     e.getEnd().accept(*this);
1092     GenericType* pITEnd = static_cast<GenericType*>(getResult());
1093     if ((pITEnd->getSize() != 1 || (pITEnd->isDouble() && pITEnd->getAs<Double>()->isComplex())) &&
1094             pITEnd->isList() == false) // list case => call overload
1095     {
1096         pITStart->killMe();
1097         pITStep->killMe();
1098         pITEnd->killMe();
1099         wchar_t szError[bsiz];
1100         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 3);
1101         throw ScilabError(szError, 999, e.getLocation());
1102     }
1103     InternalType* piEnd = pITEnd;
1104
1105     //check compatibility
1106     // double : double : double or poly : poly : poly and mix like double : double : poly
1107     if ((piStart->isPoly() || piStart->isDouble()) &&
1108             (piStep->isPoly()  || piStep->isDouble())  &&
1109             (piEnd->isPoly()   || piEnd->isDouble()))
1110     {
1111         // No need to kill piStart, ... because Implicit list ctor will incref them
1112         setResult(new ImplicitList(piStart, piStep, piEnd));
1113         return;
1114     }
1115
1116     // int : double or int : int
1117     if ( piStart->isInt()   &&
1118             (piStep->isDouble() || piStep->isInt()) &&
1119             piEnd->isInt())
1120     {
1121         // check for same int type int8, int 16 ...
1122         if (piStart->getType() == piEnd->getType()  &&
1123                 (piStart->getType() == piStep->getType() ||
1124                  piStep->isDouble()))
1125         {
1126             // No need to kill piStart, ... because Implicit list ctor will incref them
1127             setResult(new ImplicitList(piStart, piStep, piEnd));
1128             return;
1129         }
1130     }
1131
1132     // Call Overload
1133     Callable::ReturnValue Ret;
1134     types::typed_list in;
1135     types::typed_list out;
1136
1137     piStart->IncreaseRef();
1138     piStep->IncreaseRef();
1139     piEnd->IncreaseRef();
1140
1141     in.push_back(piStart);
1142     if (e.hasExplicitStep())
1143     {
1144         // 1:2:4
1145         //call overload %typeStart_b_typeEnd
1146         in.push_back(piStep);
1147         in.push_back(piEnd);
1148         Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piStep->getShortTypeStr(), in, 1, out, this, true);
1149     }
1150     else
1151     {
1152         // 1:2
1153         //call overload %typeStart_b_typeStep
1154         in.push_back(piEnd);
1155         Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piEnd->getShortTypeStr(), in, 1, out, this, true);
1156     }
1157
1158     if (Ret != Callable::OK)
1159     {
1160         cleanInOut(in, out);
1161         throw ScilabError();
1162     }
1163
1164     setResult(out);
1165     cleanIn(in, out);
1166 }
1167
1168 template <class T>
1169 void RunVisitorT<T>::visitprivate(const OptimizedExp &e)
1170 {
1171 }
1172
1173 template <class T>
1174 void RunVisitorT<T>::visitprivate(const DAXPYExp &e)
1175 {
1176     InternalType* pIT = NULL;
1177     Double* ad = NULL;
1178     int ar = 0;
1179     int ac = 0;
1180
1181     Double* xd = NULL;
1182     int xr = 0;
1183     int xc = 0;
1184
1185     Double* yd = NULL;
1186     int yr = 0;
1187     int yc = 0;
1188
1189     //check types and dimensions
1190
1191     //y must be double
1192     const Exp &ye = e.getY();
1193     ye.accept(*this);
1194     pIT = getResult();
1195     if (pIT->isDouble())
1196     {
1197         yd = pIT->getAs<Double>();
1198         if (yd->getDims() == 2 && yd->isComplex() == false)
1199         {
1200             yr = yd->getRows();
1201             yc = yd->getCols();
1202         }
1203         else
1204         {
1205             yd->killMe();
1206             e.getOriginal()->accept(*this);
1207             return;
1208         }
1209     }
1210     else
1211     {
1212         pIT->killMe();
1213         e.getOriginal()->accept(*this);
1214         return;
1215     }
1216
1217     //x
1218     const Exp &xe = e.getX();
1219     xe.accept(*this);
1220     pIT = getResult();
1221
1222     if (pIT->isDouble())
1223     {
1224         xd = pIT->getAs<Double>();
1225         if (xd->isScalar() && xd->isComplex() == false)
1226         {
1227             // x become a
1228             ad = xd;
1229             ar = 1;
1230             ac = 1;
1231         }
1232         else if (xd->getDims() == 2 && xd->isComplex() == false)
1233         {
1234             xr = xd->getRows();
1235             xc = xd->getCols();
1236         }
1237         else
1238         {
1239             yd->killMe();
1240             xd->killMe();
1241             e.getOriginal()->accept(*this);
1242             return;
1243         }
1244     }
1245     else
1246     {
1247         pIT->killMe();
1248         yd->killMe();
1249         e.getOriginal()->accept(*this);
1250         return;
1251     }
1252
1253     const Exp &ae = e.getA();
1254     ae.accept(*this);
1255     pIT = getResult();
1256
1257     if (pIT->isDouble())
1258     {
1259         if (ad)
1260         {
1261             xd = pIT->getAs<Double>();
1262             //X is scalar it become A
1263             //now use A as X
1264             if (xd->getDims() == 2 && xd->isComplex() == false)
1265             {
1266                 xr = xd->getRows();
1267                 xc = xd->getCols();
1268             }
1269             else
1270             {
1271                 yd->killMe();
1272                 xd->killMe();
1273                 ad->killMe();
1274                 e.getOriginal()->accept(*this);
1275                 return;
1276             }
1277         }
1278         else
1279         {
1280             //a is a and it must be scalar
1281             ad = pIT->getAs<Double>();
1282             if (ad->isScalar() && ad->isComplex() == false)
1283             {
1284                 ar = 1;
1285                 ac = 1;
1286             }
1287             else
1288             {
1289                 yd->killMe();
1290                 xd->killMe();
1291                 ad->killMe();
1292                 e.getOriginal()->accept(*this);
1293                 return;
1294             }
1295         }
1296     }
1297     else
1298     {
1299         pIT->killMe();
1300         yd->killMe();
1301         xd->killMe();
1302         e.getOriginal()->accept(*this);
1303         return;
1304     }
1305
1306     if (ad && xd && yd)
1307     {
1308         if ( ac == 1 &&
1309                 ar == 1 &&
1310                 xr == yr &&
1311                 xc == yc)
1312         {
1313             //go !
1314             int one = 1;
1315             int size = xc * xr;
1316             Double* od = (Double*)yd->clone();
1317             C2F(daxpy)(&size, ad->get(), xd->get(), &one, od->get(), &one);
1318             setResult(od);
1319             yd->killMe();
1320             xd->killMe();
1321             ad->killMe();
1322             return;
1323         }
1324     }
1325
1326     if (yd)
1327     {
1328         yd->killMe();
1329     }
1330
1331     if (xd)
1332     {
1333         xd->killMe();
1334     }
1335
1336     if (ad)
1337     {
1338         ad->killMe();
1339     }
1340
1341     e.getOriginal()->accept(*this);
1342     return;
1343 }
1344
1345 #include "run_CallExp.cpp"
1346 #include "run_MatrixExp.cpp"
1347 #include "run_OpExp.cpp"
1348 #include "run_AssignExp.cpp"
1349 }
1350
1351 template EXTERN_AST class ast::RunVisitorT<ast::ExecVisitor>;
1352 template EXTERN_AST class ast::RunVisitorT<ast::StepVisitor>;
1353 template EXTERN_AST class ast::RunVisitorT<ast::TimedVisitor>;