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