Refactoring of ScilabException in AST, exec, execstr.
[scilab.git] / scilab / modules / abstractSyntaxTree / includes / runvisitor.hxx
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2010-2010 - DIGITEO - 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 #ifndef AST_RUNVISITOR_HXX
14 #define AST_RUNVISITOR_HXX
15
16 #include <time.h>
17 #include <string>
18 #include <iostream>
19 #include <sstream>
20 #include <cstdio>
21 #include <iostream>
22
23 #include "visitor_common.hxx"
24 //#include "runvisitor.hxx"
25 //#include "execvisitor.hxx"
26 //#include "timedvisitor.hxx"
27 #include "shortcutvisitor.hxx"
28 #include "printvisitor.hxx"
29
30 #include "alltypes.hxx"
31
32 // Needed by visitprivate(const OpExp &)
33 // Needed by visitprivate(const LogicalOpExp &)
34 #include "types_multiplication.hxx"
35 #include "types_addition.hxx"
36 #include "types_substraction.hxx"
37 #include "types_divide.hxx"
38 #include "types_power.hxx"
39 #include "configvariable.hxx"
40 #include "overload.hxx"
41 #include "scilabexception.hxx"
42
43 extern "C" {
44 #include "doublecomplex.h"
45 #include "matrix_transpose.h"
46 #include "os_swprintf.h"
47 }
48
49 #include "timer.hxx"
50 #include "localization.h"
51
52 #include "yaspio.hxx"
53 #include "context.hxx"
54
55 #include "all.hxx"
56 #include "types.hxx"
57
58
59 namespace ast
60 {
61     class RunVisitor : public ConstVisitor
62     {
63     public:
64         RunVisitor()
65         {
66             _excepted_result = -1;
67             _resultVect.push_back(NULL);
68             _result = NULL;
69             m_bSingleResult = true;
70         }
71
72         ~RunVisitor()
73         {
74             result_clear();
75         }
76
77         void result_clear()
78         {
79             if(is_single_result())
80             {
81                 if(_result != NULL && _result->isDeletable() == true)
82                 {
83                     //                                  std::cout << "before single delete : " << _result << std::endl;
84                     delete _result;
85                     _result = NULL;
86                     //                                  std::cout << "after single delete" << std::endl;
87                 }
88             }
89             else
90             {
91                 for(unsigned int i = 0 ; i < _resultVect.size() ; i++)
92                 {
93                     if(_resultVect[i] != NULL && _resultVect[i]->isDeletable() == true)
94                     {
95                         delete _resultVect[i];
96                         _resultVect[i] = NULL;
97                     }
98                 }
99             }
100         }
101
102     public:
103         int expected_getSize(void)
104         {
105             return _excepted_result;
106         }
107
108         int result_getSize(void)
109         {
110             if(is_single_result())
111             {
112                 if(_result == NULL)
113                 {
114                     return 0;
115                 }
116                 else
117                 {
118                     return 1;
119                 }
120             }
121             else
122             {
123                 return static_cast<int>(_resultVect.size());
124             }
125         }
126
127         void expected_size_set(int _iSize)
128         {
129             _excepted_result = _iSize;
130         }
131
132         types::InternalType* result_get(void)
133         {
134             if(is_single_result())
135             {
136                 return _result;
137             }
138             else
139             {
140                 return _resultVect[0];
141             }
142         }
143
144         types::InternalType* result_get(int _iPos)
145         {
146             if(is_single_result() && _iPos == 0)
147             {
148                 return _result;
149             }
150
151             if(_iPos >= static_cast<int>(_resultVect.size()))
152             {
153                 return NULL;
154             }
155             return _resultVect[_iPos];
156         }
157
158         vector<types::InternalType*>* result_list_get()
159         {
160             if(result_getSize() == 1)
161             {
162                 vector<types::InternalType*>* pList = new vector<types::InternalType*>;
163                 pList->push_back(_result);
164                 return pList;
165             }
166             else
167             {
168                 return &_resultVect;
169             }
170         }
171
172         void result_set(int _iPos, const types::InternalType *gtVal)
173         {
174             m_bSingleResult = false;
175             if(_iPos <  static_cast<int>(_resultVect.size()))
176             {
177                 if(_resultVect[_iPos] != NULL && _resultVect[_iPos]->isDeletable())
178                 {
179                     delete _resultVect[_iPos];
180                 }
181             }
182
183             if(_iPos >=  static_cast<int>(_resultVect.size()))
184             {
185                 _resultVect.resize(_iPos + 1, NULL);
186             }
187
188             _resultVect[_iPos] = const_cast<types::InternalType *>(gtVal);
189         }
190
191         void result_set(const types::InternalType *gtVal)
192         {
193             m_bSingleResult = true;
194             _result = const_cast<types::InternalType *>(gtVal);
195         }
196
197         bool is_single_result()
198         {
199             return m_bSingleResult;
200         }
201
202         /*-------------.
203         | Attributes.  |
204         `-------------*/
205     protected:
206         vector<types::InternalType*>    _resultVect;
207         types::InternalType*    _result;
208         bool m_bSingleResult;
209         int _excepted_result;
210     };
211
212     template <class T>
213     class RunVisitorT : public RunVisitor
214     {
215     protected :
216
217         typed_list* GetArgumentList(std::list<ast::Exp *>const& _plstArg)
218         {
219             typed_list* pArgs = new typed_list();
220             std::list<ast::Exp *>::const_iterator it;
221             T *execMeArg  = new T();
222             for(it = _plstArg.begin() ; it != _plstArg.end() ; it++)
223             {
224                 (*it)->accept(*execMeArg);
225                 pArgs->push_back(execMeArg->result_get());
226             }
227             //to be sure, delete operation does not delete result
228             execMeArg->result_set(NULL);
229             delete execMeArg;
230             return pArgs;
231         }
232
233     public :
234         void visitprivate(const MatrixLineExp &e)
235         {
236             /*
237             All processes are done in MatrixExp
238             */
239         }
240
241
242         void visitprivate(const CellExp &e)
243         {
244             std::list<MatrixLineExp *>::const_iterator row;
245             std::list<Exp *>::const_iterator col;
246             int iColMax = 0;
247
248             //check dimmension
249             for (row = e.lines_get().begin() ; row != e.lines_get().end() ; ++row )
250             {
251                 if(iColMax == 0)
252                 {
253                     iColMax = static_cast<int>((*row)->columns_get().size());
254                 }
255
256                 if(iColMax != static_cast<int>((*row)->columns_get().size()))
257                 {
258                     std::wostringstream os;
259                     os << L"inconsistent row/column dimensions\n";
260                     //os << ((Location)(*row)->location_get()).location_getString() << std::endl;
261                     throw ScilabError(os.str(), 999, (*row)->location_get());
262                 }
263             }
264
265             //alloc result cell
266             Cell *pC = new Cell(static_cast<int>(e.lines_get().size()), iColMax);
267
268             int i = 0;
269             int j = 0;
270
271             //insert items in cell
272             for (i = 0, row = e.lines_get().begin() ; row != e.lines_get().end() ; row++, i++ )
273             {
274                 for (j = 0, col = (*row)->columns_get().begin() ; col != (*row)->columns_get().end() ; col++, j++)
275                 {
276                     T execMe;
277                     (*col)->accept(execMe);
278                     pC->set(i,j, execMe.result_get());
279                 }
280             }
281
282             //return new cell
283             result_set(pC);
284         }
285
286         /** \name Visit Constant Expressions nodes.
287         ** \{ */
288
289         void visitprivate(const StringExp &e)
290         {
291             String *psz = new String(e.value_get().c_str());
292             result_set(psz);
293         }
294
295
296         void visitprivate(const CommentExp &e)
297         {
298             /*
299             Nothing to do
300             */
301         }
302
303
304         void visitprivate(const IntExp  &e)
305         {
306             /*
307             Int does not exist, Int8 - 16 - 32 - 64 functions
308             */
309         }
310
311
312         void visitprivate(const FloatExp  &e)
313         {
314             /*
315             Float does not exist, float function
316             */
317         }
318
319
320         void visitprivate(const DoubleExp  &e)
321         {
322             if(e.getBigDouble() == NULL)
323             {
324                 Double *pdbl = new Double(e.value_get());
325                 pdbl->IncreaseRef();
326                 (const_cast<DoubleExp *>(&e))->setBigDouble(pdbl);
327
328             }
329             result_set(e.getBigDouble());
330         }
331
332
333         void visitprivate(const BoolExp  &e)
334         {
335             Bool *pb = new Bool(e.value_get());
336             result_set(pb);
337         }
338
339
340         void visitprivate(const NilExp &e)
341         {
342             /*
343             FIXME :
344             */
345         }
346
347
348         void visitprivate(const SimpleVar &e)
349         {
350             InternalType *pI = symbol::Context::getInstance()->get(e.name_get());
351             if(pI != NULL)
352             {
353                 result_set(pI);
354                 if(pI != NULL && pI->getAsCallable() == false && e.is_verbose())
355                 {
356                     std::wostringstream ostr;
357                     ostr << e.name_get().name_get() << L" = " << L"(" << pI->getRef() << L")"<< std::endl;
358                     ostr << std::endl;
359                     ostr << pI->toString(ConfigVariable::getFormat(), ConfigVariable::getConsoleWidth()) << std::endl;
360                     YaspWriteW(ostr.str().c_str());
361                 }
362             }
363             else
364             {
365                 wchar_t szError[bsiz];
366                 os_swprintf(szError, bsiz, _W("Undefined variable: %ls\n"), e.name_get().name_get().c_str());
367                 throw ScilabError(szError, 999, e.location_get());
368                 //Err, SimpleVar doesn't exist in Scilab scopes.
369             }
370         }
371
372
373         void visitprivate(const ColonVar &e)
374         {
375             //int pRank[1] = {2};
376             //Double dblCoef(1,2);
377             //dblCoef.set(0, 0, 0);
378             //dblCoef.set(0, 1, 1);
379
380             //Polynom *pVar = new Polynom(L"$", 1, 1, pRank);
381             //SinglePoly *poPoly = pVar->get(0,0);
382             //poPoly->setCoef(&dblCoef);
383
384             //ImplicitList *pIL = new ImplicitList();
385             //pIL->setStart(new Double(1));
386             //pIL->setStep(new Double(1));
387             //pIL->setEnd(pVar);
388
389             Colon *pC = new Colon();
390             result_set(pC);
391             /*
392             : = 1:$
393             */
394         }
395
396
397         void visitprivate(const DollarVar &e)
398         {
399             //int pRank[1] = {2};
400             //Double dblCoef(1,2);
401             //dblCoef.set(0, 0, 0);
402             //dblCoef.set(0, 1, 1);
403
404             //Polynom *pVar = new Polynom(L"$", 1, 1, pRank);
405             //SinglePoly *poPoly = pVar->get(0,0);
406             //poPoly->setCoef(&dblCoef);
407
408             Dollar* pVar = new Dollar();
409             result_set(pVar);
410         }
411
412
413         void visitprivate(const ArrayListVar &e)
414         {
415             /*
416
417             */
418         }
419
420
421         void visitprivate(const FieldExp &e)
422         {
423             /*
424             a.b
425             */
426             T execHead;
427             try
428             {
429                 e.head_get()->accept(execHead);
430             }
431             catch(ScilabError error)
432             {
433                 throw error;
434             }
435
436             if(execHead.result_get() != NULL && execHead.result_get()->isStruct())
437             {
438                 SimpleVar *psvRightMember = dynamic_cast<SimpleVar *>(const_cast<Exp *>(e.tail_get()));
439                 if(psvRightMember != NULL)
440                 {
441                     Struct* psValue = execHead.result_get()->getAsStruct();
442                     if(psValue->exists(psvRightMember->name_get().name_get()))
443                     {
444                         InternalType* pIT = psValue->get(psvRightMember->name_get().name_get());
445                         result_set(pIT);
446                     }
447                     else
448                     {
449                         wchar_t szError[bsiz];
450                         os_swprintf(szError, bsiz, _W("Unknown field : %ls.\n"), psvRightMember->name_get().name_get().c_str());
451                         throw ScilabError(szError, 999, psvRightMember->location_get());
452                     }
453                 }
454                 else
455                 {
456                     wchar_t szError[bsiz];
457                     os_swprintf(szError, bsiz, _W("/!\\ Unmanaged FieldExp.\n"));
458                     throw ScilabError(szError, 999, e.location_get());
459                 }
460             }
461             else if(execHead.result_get() != NULL && execHead.result_get()->isTList())
462             {
463                 SimpleVar *psvRightMember = dynamic_cast<SimpleVar *>(const_cast<Exp *>(e.tail_get()));
464                 if(psvRightMember != NULL)
465                 {
466                     TList* psValue = execHead.result_get()->getAsTList();
467                     if(psValue->exists(psvRightMember->name_get().name_get()))
468                     {
469                         InternalType* pIT = psValue->get(psvRightMember->name_get().name_get());
470                         result_set(pIT);
471                     }
472                     else
473                     {
474                         wchar_t szError[bsiz];
475                         os_swprintf(szError, bsiz, _W("Unknown field : %ls.\n"), psvRightMember->name_get().name_get().c_str());
476                         throw ScilabError(szError, 999, psvRightMember->location_get());
477                     }
478                 }
479                 else
480                 {
481                     wchar_t szError[bsiz];
482                     os_swprintf(szError, bsiz, _W("/!\\ Unmanaged FieldExp.\n"));
483                     throw ScilabError(szError, 999, e.location_get());
484                 }
485             }
486             else
487             {
488                 wchar_t szError[bsiz];
489                 os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n"));
490                 throw ScilabError(szError, 999, e.location_get());
491             }
492         }
493
494
495         void visitprivate(const CellCallExp &e)
496         {
497             //get head
498             T execMeCell;
499             e.name_get().accept(execMeCell);
500
501             if(execMeCell.result_get() != NULL)
502             {//a{xxx} with a variable, extraction
503                 InternalType *pIT = NULL;
504
505                 pIT = execMeCell.result_get();
506
507                 if(pIT)
508                 {
509                     //Create list of indexes
510                     typed_list *pArgs = GetArgumentList(e.args_get());
511
512                     List* pList = pIT->getAs<Cell>()->extractCell(pArgs);
513
514                     if(pList == NULL)
515                     {
516                         std::wostringstream os;
517                         os << L"inconsistent row/column dimensions\n";
518                         //os << ((*e.args_get().begin())->location_get()).location_getString() << std::endl;
519                         throw ScilabError(os.str(), 999, (*e.args_get().begin())->location_get());
520                     }
521
522                     if (pList->getSize() == 1)
523                     {
524                         result_set(pList->get(0));
525                     }
526                     else
527                     {
528                         result_set(pList);
529                     }
530                 }
531             }
532             else
533             {
534                 //result == NULL ,variable doesn't exist :(
535                 // Sould never be in this case
536                 // In worst case variable pointing to function does not exists
537                 // visitprivate(SimpleVar) will throw the right exception.
538             }
539         }
540
541         void visitprivate(const IfExp  &e)
542         {
543             //Create local exec visitor
544             T execMeTest;
545             ShortCutVisitor SCTest;
546             T execMeAction;
547             bool bTestStatus                                                    = false;
548
549             //condition
550             e.test_get().accept(SCTest);
551             e.test_get().accept(execMeTest);
552
553             bTestStatus = bConditionState(execMeTest.result_get());
554             if(bTestStatus == true)
555             {//condition == true
556                 if(e.is_breakable())
557                 {
558                     const_cast<Exp*>(&e.then_get())->breakable_set();
559                 }
560
561                 if(e.is_continuable())
562                 {
563                     const_cast<IfExp*>(&e)->continue_reset();
564                     const_cast<Exp*>(&e.then_get())->continuable_set();
565                 }
566
567                 if(e.is_returnable())
568                 {
569                     const_cast<Exp*>(&e.then_get())->returnable_set();
570                 }
571
572                 e.then_get().accept(execMeAction);
573             }
574             else
575             {//condition == false
576
577                 if(e.has_else())
578                 {
579                     if(e.is_breakable())
580                     {
581                         const_cast<Exp*>(&e.else_get())->breakable_set();
582                     }
583
584                     if(e.is_continuable())
585                     {
586                         const_cast<IfExp*>(&e)->continue_reset();
587                         const_cast<Exp*>(&e.else_get())->continuable_set();
588                     }
589
590                     if(e.is_returnable())
591                     {
592                         const_cast<Exp*>(&e.else_get())->returnable_set();
593                     }
594
595                     e.else_get().accept(execMeAction);
596                 }
597             }
598
599             if(e.is_breakable()
600                 && ( (&e.else_get())->is_break()
601                 || (&e.then_get())->is_break() ))
602             {
603                 const_cast<IfExp*>(&e)->break_set();
604                 const_cast<Exp*>(&e.else_get())->break_reset();
605                 const_cast<Exp*>(&e.then_get())->break_reset();
606             }
607
608             if(e.is_continuable()
609                 && ( (&e.else_get())->is_continue()
610                 || (&e.then_get())->is_continue() ))
611             {
612                 const_cast<IfExp*>(&e)->continue_set();
613                 const_cast<Exp*>(&e.else_get())->continue_reset();
614                 const_cast<Exp*>(&e.then_get())->continue_reset();
615             }
616
617             if(e.is_returnable()
618                 && ( (&e.else_get())->is_return()
619                 || (&e.then_get())->is_return() ))
620             {
621                 const_cast<IfExp*>(&e)->return_set();
622                 const_cast<Exp*>(&e.else_get())->return_reset();
623                 const_cast<Exp*>(&e.then_get())->return_reset();
624             }
625         }
626
627
628         void visitprivate(const TryCatchExp  &e)
629         {
630             //save current prompt mode
631             int oldVal = ConfigVariable::getSilentError();
632             //set mode silent for errors
633             ConfigVariable::setSilentError(1);
634             try
635             {
636                 T execMe;
637                 e.try_get().accept(execMe);
638                 //restore previous prompt mode
639                 ConfigVariable::setSilentError(oldVal);
640             }
641             catch(ScilabMessage sm)
642             {
643                 T execMe;
644                 //restore previous prompt mode
645                 ConfigVariable::setSilentError(oldVal);
646                 //to lock lasterror
647                 ConfigVariable::setLastErrorCall();
648                 e.catch_get().accept(execMe);
649             }
650         }
651
652
653         void visitprivate(const WhileExp  &e)
654         {
655             T execMeTest;
656             T execMeAction;
657
658             //allow break and continue operations
659             const_cast<Exp*>(&e.body_get())->breakable_set();
660             const_cast<Exp*>(&e.body_get())->continuable_set();
661             //allow return operation
662             if(e.is_returnable())
663             {
664                 (&e.body_get())->is_returnable();
665             }
666
667             //condition
668             e.test_get().accept(execMeTest);
669             while(bConditionState(execMeTest.result_get()))
670             {
671                 e.body_get().accept(execMeAction);
672                 if(e.body_get().is_break())
673                 {
674                     break;
675                 }
676
677                 if(e.body_get().is_return())
678                 {
679                     const_cast<WhileExp*>(&e)->return_set();
680                     break;
681                 }
682
683                 if(e.body_get().is_continue())
684                 {
685                     const_cast<WhileExp*>(&e)->continue_set();
686                     const_cast<Exp*>(&(e.body_get()))->continue_reset();
687                     e.test_get().accept(execMeTest);
688                     continue;
689                 }
690
691                 //clear old result value before evaluate new one
692                 if(execMeTest.result_get() != NULL)
693                 {
694                     if(execMeTest.result_get()->isDeletable())
695                     {
696                         delete execMeTest.result_get();
697                     }
698                 }
699
700                 e.test_get().accept(execMeTest);
701             }
702         }
703
704
705         void visitprivate(const ForExp  &e)
706         {
707             T execVar;
708             e.vardec_get().accept(execVar);
709
710             //allow break and continue operations
711             const_cast<Exp*>(&e.body_get())->breakable_set();
712             const_cast<Exp*>(&e.body_get())->continuable_set();
713             //allow return operation
714             if(e.is_returnable())
715             {
716                 (&e.body_get())->is_returnable();
717             }
718
719             if(execVar.result_get()->isImplicitList())
720             {
721                 T execBody;
722                 ImplicitList* pVar = execVar.result_get()->getAsImplicitList();
723                 //                      std::cout << "ImplicitList references : " << pVar->getRef() << std::endl;
724
725                 InternalType *pIT = NULL;
726                 pIT = pVar->extractValue(0);
727                 symbol::Symbol varName = e.vardec_get().name_get();
728                 symbol::Context::getInstance()->put(varName, *pIT);
729
730                 Double *pDouble = pIT->getAs<Double>();
731                 for(int i = 0 ; i < pVar->getSize() ; i++)
732                 {
733                     bool bNew = false;
734                     if(pIT->isRef(1))
735                     {
736                         //decrease reference to pIT
737                         //this variable does not push in context 
738                         //so increase and decrease ref are not "automaticly" manage
739                         //std::wcout << varName.name_get() << " : " << pIT->getRef() << std::endl;
740                         //pIT->DecreaseRef();
741                         pIT = pIT->clone();
742                         pDouble = pIT->getAs<Double>();
743                         bNew = true;
744                     }
745
746                     if(pIT->isDouble())
747                     {
748                         pDouble->get()[0] = pVar->extractValueInDouble(i);
749                     }
750                     else if(pIT->isInt())
751                     {
752                         switch(pIT->getType())
753                         {
754                         case InternalType::RealInt8 :
755                             {
756                                 Int8* pI = pIT->getAs<Int8>();
757                                 pI->set(0, (char)pVar->extractValueInInteger(i));
758                                 break;
759                             }
760                         case InternalType::RealUInt8 :
761                             {
762                                 UInt8* pI = pIT->getAs<UInt8>();
763                                 pI->set(0, (unsigned char)pVar->extractValueInInteger(i));
764                                 break;
765                             }
766                         case InternalType::RealInt16 :
767                             {
768                                 Int16* pI = pIT->getAs<Int16>();
769                                 pI->set(0, (short)pVar->extractValueInInteger(i));
770                                 break;
771                             }
772                         case InternalType::RealUInt16 :
773                             {
774                                 UInt16* pI = pIT->getAs<UInt16>();
775                                 pI->set(0, (unsigned short)pVar->extractValueInInteger(i));
776                                 break;
777                             }
778                         case InternalType::RealInt32 :
779                             {
780                                 Int32* pI = pIT->getAs<Int32>();
781                                 pI->set(0, (int)pVar->extractValueInInteger(i));
782                                 break;
783                             }
784                         case InternalType::RealUInt32 :
785                             {
786                                 UInt32* pI = pIT->getAs<UInt32>();
787                                 pI->set(0, (unsigned int)pVar->extractValueInInteger(i));
788                                 break;
789                             }
790                         case InternalType::RealInt64 :
791                             {
792                                 Int64* pI = pIT->getAs<Int64>();
793                                 pI->set(0, (long long)pVar->extractValueInInteger(i));
794                                 break;
795                             }
796                         case InternalType::RealUInt64 :
797                             {
798                                 UInt64* pI = pIT->getAs<UInt64>();
799                                 pI->set(0, (unsigned long long)pVar->extractValueInInteger(i));
800                                 break;
801                             }
802                         }
803                     }
804                     else
805                     {
806                         pIT = pVar->extractValue(i);
807                         symbol::Context::getInstance()->put(varName, *pIT);
808                     }
809
810                     if(bNew)
811                     {
812                         symbol::Context::getInstance()->put(varName, *pIT);
813                     }
814
815                     e.body_get().accept(execBody);
816                     if(e.body_get().is_break())
817                     {
818                         break;
819                     }
820
821                     if(e.body_get().is_continue())
822                     {
823                         const_cast<Exp*>(&(e.body_get()))->continue_reset();
824                         continue;
825                     }
826
827                     if(e.body_get().is_return())
828                     {
829                         const_cast<ForExp*>(&e)->return_set();
830                         break;
831                     }
832                 }
833
834                 pVar->DecreaseRef();
835                 //delete pVar;
836             }
837             else
838             {//Matrix i = [1,3,2,6] or other type
839                 T execBody;
840                 InternalType* pIT = execVar.result_get();
841                 GenericType* pVar = pIT->getAs<GenericType>();
842                 if(pVar->getDims() > 2)
843                 {
844                     throw ScilabError(_W("for expression can only manage 1 or 2 dimensions variables\n"), 999, e.vardec_get().location_get());
845                 }
846
847                 for(int i = 0 ; i < pVar->getCols() ; i++)
848                 {
849                     GenericType* pNew = pVar->getColumnValues(i);
850                     symbol::Context::getInstance()->put(e.vardec_get().name_get(), *pNew);
851                     e.body_get().accept(execBody);
852                     if(e.body_get().is_break())
853                     {
854                         break;
855                     }
856
857                     if(e.body_get().is_continue())
858                     {
859                         continue;
860                     }
861
862                     if(e.body_get().is_return())
863                     {
864                         const_cast<ForExp*>(&e)->return_set();
865                         break;
866                     }
867                 }
868             }
869         }
870
871
872         void visitprivate(const BreakExp &e)
873         {
874             const_cast<BreakExp*>(&e)->break_set();
875         }
876
877         void visitprivate(const ContinueExp &e)
878         {
879             const_cast<ContinueExp*>(&e)->continue_set();
880         }
881
882         void visitprivate(const ReturnExp &e)
883         {
884             if(e.is_global() == false)
885             {//return(x)
886                 T execVar;
887                 e.exp_get().accept(execVar);
888
889                 if(execVar.result_getSize() == 1)
890                 {
891                     //protect variable
892                     InternalType *pIT = execVar.result_get();
893                     pIT->IncreaseRef();
894                     result_set(pIT);
895                 }
896                 else
897                 {
898                     for(int i = 0 ; i < execVar.result_getSize() ; i++)
899                     {
900                         //protect variable
901                         InternalType *pIT = execVar.result_get(i);
902                         pIT->IncreaseRef();
903                         result_set(i, pIT);
904                     }
905                 }
906             }
907
908             if(result_getSize() == 1)
909             {
910                 //unprotect variable
911                 result_get()->DecreaseRef();
912             }
913             else
914             {
915                 for(int i = 0 ; i < result_getSize() ; i++)
916                 {
917                     //unprotect variable
918                     result_get(i)->DecreaseRef();
919                 }
920             }
921             const_cast<ReturnExp*>(&e)->return_set();
922         }
923
924
925         void visitprivate(const SelectExp &e)
926         {
927             // FIXME : exec select ... case ... else ... end
928             T execMe;
929             e.select_get()->accept(execMe);
930             bool bCase = false;
931
932
933             if(execMe.result_get() != NULL)
934             {//find good case
935                 cases_t::iterator it;
936                 for(it = e.cases_get()->begin(); it != e.cases_get()->end() ; it++)
937                 {
938                     T execCase;
939                     CaseExp* pCase = *it;
940                     pCase->test_get()->accept(execCase);
941                     if(execCase.result_get() != NULL)
942                     {
943                         if(execCase.result_get()->isContainer()) //WARNING ONLY FOR CELL
944                         {//check each item
945                         }
946                         else if(*execCase.result_get() == *execMe.result_get())
947                         {//the good one
948                             T execBody;
949                             pCase->body_get()->accept(execBody);
950                             bCase = true;
951                             break;
952                         }
953                     }
954                 }
955             }
956
957             if(bCase == false)
958             {//default case
959                 T execDefault;
960                 e.default_case_get()->accept(execDefault);
961             }
962         }
963
964
965         void visitprivate(const CaseExp &e)
966         {
967         }
968
969
970         void visitprivate(const SeqExp  &e)
971         {
972             std::list<Exp *>::const_iterator    itExp;
973
974             for (itExp = e.exps_get().begin (); itExp != e.exps_get().end (); ++itExp)
975             {
976                 T execMe;
977                 if(e.is_breakable())
978                 {
979                     (*itExp)->breakable_set();
980                 }
981
982                 if(e.is_continuable())
983                 {
984                     (*itExp)->continue_reset();
985                     (*itExp)->continuable_set();
986                 }
987
988                 if(e.is_returnable())
989                 {
990                     (*itExp)->returnable_set();
991                 }
992
993                 try
994                 {
995                     (*itExp)->accept(execMe);
996
997                     if(execMe.result_get() != NULL)
998                     {
999                         bool bImplicitCall = false;
1000                         if(execMe.result_get()->getAsCallable())//to manage call without ()
1001                         {
1002                             Callable *pCall = execMe.result_get()->getAsCallable();
1003                             types::typed_list out;
1004                             types::typed_list in;
1005
1006                             try
1007                             {
1008                                 T execCall;
1009                                 Function::ReturnValue Ret = pCall->call(in, expected_getSize(), out, &execCall);
1010
1011                                 if(Ret == Callable::OK)
1012                                 {
1013                                     if(out.size() == 0)
1014                                     {
1015                                         execMe.result_set(NULL);
1016                                     }
1017                                     else if(out.size() == 1)
1018                                     {
1019                                         out[0]->DecreaseRef();
1020                                         execMe.result_set(out[0]);
1021                                     }
1022                                     else
1023                                     {
1024                                         for(int i = 0 ; i < static_cast<int>(out.size()) ; i++)
1025                                         {
1026                                             out[i]->DecreaseRef();
1027                                             execMe.result_set(i, out[i]);
1028                                         }
1029                                     }
1030
1031                                     bImplicitCall = true;
1032                                 }
1033                                 else if(Ret == Callable::Error)
1034                                 {
1035                                     if(ConfigVariable::getLastErrorFunction() == L"")
1036                                     {
1037                                         ConfigVariable::setLastErrorFunction(pCall->getName());
1038                                         ConfigVariable::setLastErrorLine(e.location_get().first_line);
1039                                     }
1040
1041                                     if(pCall->isMacro() || pCall->isMacroFile())
1042                                     {
1043                                         wchar_t szError[bsiz];
1044                                         os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n"), (*itExp)->location_get().first_line, pCall->getName().c_str());
1045                                         throw ScilabMessage(szError);
1046                                     }
1047                                     else
1048                                     {
1049                                         throw ScilabMessage();
1050                                     }
1051                                 }
1052                             }
1053                             catch(ScilabMessage sm)
1054                             {
1055                                 wostringstream os;
1056                                 PrintVisitor printMe(os);
1057                                 (*itExp)->accept(printMe);
1058                                 os << std::endl << std::endl;
1059                                 if(ConfigVariable::getLastErrorFunction() == L"")
1060                                 {
1061                                     ConfigVariable::setLastErrorFunction(pCall->getName());
1062                                 }
1063
1064                                 if(pCall->isMacro() || pCall->isMacroFile())
1065                                 {
1066                                     wchar_t szError[bsiz];
1067                                     os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n"), sm.GetErrorLocation().first_line, pCall->getName().c_str());
1068                                     throw ScilabMessage(szError + os.str());
1069                                 }
1070                                 else
1071                                 {
1072                                     sm.SetErrorMessage(sm.GetErrorMessage() + os.str());
1073                                     throw sm;
1074                                 }
1075                             }
1076                         }
1077
1078                         SimpleVar* pVar = dynamic_cast<SimpleVar*>(*itExp);
1079                         //don't output Simplevar and empty result
1080                         if(execMe.result_get() != NULL && (pVar == NULL || bImplicitCall))
1081                         {
1082                             symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), *execMe.result_get());
1083                             if((*itExp)->is_verbose())
1084                             {
1085                                 //TODO manage multiple returns
1086                                 std::wostringstream ostr;
1087                                 ostr << L"ans = " << std::endl << std::endl;
1088                                 ostr << execMe.result_get()->toString(ConfigVariable::getFormat(), ConfigVariable::getConsoleWidth()) << std::endl;
1089                                 YaspWriteW(ostr.str().c_str());
1090                             }
1091                         }
1092
1093                     }
1094
1095                     if((&e)->is_breakable() && (*itExp)->is_break())
1096                     {
1097                         const_cast<SeqExp *>(&e)->break_set();
1098                         break;
1099                     }
1100
1101                     if((&e)->is_continuable() && (*itExp)->is_continue())
1102                     {
1103                         const_cast<SeqExp *>(&e)->continue_set();
1104                         break;
1105                     }
1106
1107                     if((&e)->is_returnable() && (*itExp)->is_return())
1108                     {
1109                         const_cast<SeqExp *>(&e)->return_set();
1110                         (*itExp)->return_reset();
1111                         break;
1112                     }
1113                 }
1114                 catch(ScilabMessage sm)
1115                 {
1116                     YaspErrorW(sm.GetErrorMessage().c_str());
1117
1118                     CallExp* pCall = dynamic_cast<CallExp*>(*itExp);
1119                     if(pCall != NULL)
1120                     {//to print call expression only of it is a macro
1121                         T execFunc;
1122                         pCall->name_get().accept(execFunc);
1123
1124                         if(execFunc.result_get() != NULL && execFunc.result_get()->isCallable())
1125                         {
1126                             wostringstream os;
1127                             PrintVisitor printMe(os);
1128                             pCall->accept(printMe);
1129                             os << std::endl << std::endl;
1130                             if(ConfigVariable::getLastErrorFunction() == L"")
1131                             {
1132                                 ConfigVariable::setLastErrorFunction(execFunc.result_get()->getAsCallable()->getName());
1133                             }
1134                             throw ScilabMessage(os.str(), 0, (*itExp)->location_get());
1135                         }
1136                     }
1137
1138                     throw ScilabMessage((*itExp)->location_get());
1139                 }
1140                 catch(ScilabError se)
1141                 {
1142                     if(ConfigVariable::getLastErrorMessage() == L"")
1143                     {
1144                         ConfigVariable::setLastErrorMessage(se.GetErrorMessage());
1145                         ConfigVariable::setLastErrorNumber(se.GetErrorNumber());
1146                         ConfigVariable::setLastErrorLine(se.GetErrorLocation().first_line);
1147                         ConfigVariable::setLastErrorFunction(wstring(L""));
1148                     }
1149
1150                     CallExp* pCall = dynamic_cast<CallExp*>(*itExp);
1151                     if(pCall != NULL)
1152                     {//to print call expression only of it is a macro
1153                         T execFunc;
1154
1155                         try
1156                         {
1157                             pCall->name_get().accept(execFunc);
1158                             if(execFunc.result_get() != NULL &&
1159                                 (execFunc.result_get()->isMacro() || execFunc.result_get()->isMacroFile()))
1160                             {
1161                                 wostringstream os;
1162                                 PrintVisitor printMe(os);
1163                                 pCall->accept(printMe);
1164                                 os << std::endl << std::endl;
1165                                 ConfigVariable::setLastErrorFunction(execFunc.result_get()->getAsCallable()->getName());
1166                                 YaspErrorW(se.GetErrorMessage().c_str());
1167                                 throw ScilabMessage(os.str(), 0, (*itExp)->location_get());
1168                             }
1169                         }
1170                         catch(ScilabError se2)
1171                         {//just to catch exception, do nothing
1172                         }
1173                     }
1174
1175                     YaspErrorW(se.GetErrorMessage().c_str());
1176                     throw ScilabMessage((*itExp)->location_get());
1177                 }
1178             }
1179         }
1180
1181
1182         void visitprivate(const ArrayListExp  &e)
1183         {
1184             std::list<Exp *>::const_iterator it;
1185             int i = 0;
1186             for(it = e.exps_get().begin() ; it != e.exps_get().end() ; it++)
1187             {
1188                 T execArg;
1189                 (*it)->accept(execArg);
1190                 result_set(i, execArg.result_get()->clone());
1191                 i++;
1192             }
1193         }
1194
1195
1196         void visitprivate(const AssignListExp  &e)
1197         {
1198
1199         }
1200         /** \} */
1201
1202         /** \name Visit Single Operation nodes.
1203         ** \{ */
1204
1205         void visitprivate(const NotExp &e)
1206         {
1207             /*
1208             @ or ~= !
1209             */
1210             T execMe;
1211             e.exp_get().accept(execMe);
1212
1213             if(execMe.result_get()->isDouble())
1214             {
1215                 InternalType* pVar  = execMe.result_get();
1216                 Double *pdbl        = pVar->getAs<Double>();
1217                 Bool *pReturn       = new Bool(pdbl->getRows(), pdbl->getCols());
1218                 double *pR                  = pdbl->getReal();
1219                 int *piB            = pReturn->get();
1220                 for(int i = 0 ; i < pdbl->getSize() ; i++)
1221                 {
1222                     piB[i] = pR[i] == 0 ? 1 : 0;
1223                 }
1224                 result_set(pReturn);
1225             }
1226             else if(execMe.result_get()->isBool())
1227             {
1228                 InternalType* pIT       = execMe.result_get();
1229                 Bool *pb                        = pIT->getAs<types::Bool>();
1230                 Bool *pReturn   = new Bool(pb->getRows(), pb->getCols());
1231                 int *piR                        = pb->get();
1232                 int *piB                        = pReturn->get();
1233
1234                 for(int i = 0 ; i < pb->getSize() ; i++)
1235                 {
1236                     piB[i] = piR[i] == 1 ? 0 : 1;
1237                 }
1238                 result_set(pReturn);
1239             }
1240         }
1241
1242
1243         void visitprivate(const TransposeExp &e)
1244         {
1245             /*
1246             '
1247             */
1248             T execMe;
1249             e.exp_get().accept(execMe);
1250
1251             bool bConjug = e.conjugate_get() == TransposeExp::_Conjugate_;
1252
1253             if(execMe.result_get()->isImplicitList())
1254             {
1255                 InternalType *pIT = execMe.result_get()->getAsImplicitList()->extractFullMatrix();
1256                 execMe.result_set(pIT);
1257             }
1258
1259             if(execMe.result_get()->isDouble())
1260             {
1261                 InternalType* pVar  = execMe.result_get();
1262                 Double *pdbl            = pVar->getAs<Double>();
1263                 Double *pReturn     = NULL;
1264
1265                 if(pdbl->isComplex())
1266                 {
1267                     pReturn                             = new Double(pdbl->getCols(), pdbl->getRows(), true);
1268                     double *pInR        =       pdbl->getReal();
1269                     double *pInI        =       pdbl->getImg();
1270                     double *pOutR       =       pReturn->getReal();
1271                     double *pOutI       =       pReturn->getImg();
1272
1273                     vTransposeComplexMatrix(pInR, pInI, pdbl->getRows(), pdbl->getCols(), pOutR, pOutI, bConjug);
1274                 }
1275                 else
1276                 {
1277                     pReturn                             = new Double(pdbl->getCols(), pdbl->getRows(), false);
1278                     double *pInR        =       pdbl->getReal();
1279                     double *pOutR       =       pReturn->getReal();
1280
1281                     vTransposeRealMatrix(pInR, pdbl->getRows(), pdbl->getCols(), pOutR);
1282                 }
1283                 result_set(pReturn);
1284             }
1285             else if(execMe.result_get()->isPoly())
1286             {
1287                 InternalType *pIT           = execMe.result_get();
1288                 Polynom *pMP                    = pIT->getAs<types::Polynom>();
1289                 Polynom *pReturn            = NULL;
1290
1291                 //prepare rank array
1292                 int* piRank = new int[pMP->getSize()];
1293
1294                 for(int i = 0 ; i < pMP->getRows() ; i++)
1295                 {
1296                     for(int j = 0 ; j < pMP->getCols() ; j++)
1297                     {
1298                         piRank[i * pMP->getCols() + j] = pMP->get(i,j)->getRank();
1299                     }
1300                 }
1301
1302                 pReturn = new Polynom(pMP->getVariableName(), pMP->getCols(), pMP->getRows(), piRank);
1303                 pReturn->setComplex(pMP->isComplex());
1304
1305                 if(pMP->isComplex() && bConjug)
1306                 {
1307                     for(int i = 0 ; i < pMP->getRows() ; i++)
1308                     {
1309                         for(int j = 0 ; j < pMP->getCols() ; j++)
1310                         {
1311                             pReturn->setCoef(j, i, pMP->get(i,j)->getCoef());
1312                             double *pdblImg = pReturn->get(j, i)->getCoefImg();
1313                             for(int k = 0 ; k < pReturn->get(j, i)->getRank() ; k++)
1314                             {
1315                                 pdblImg[k] *= -1;
1316                             }
1317                         }
1318                     }
1319                 }
1320                 else
1321                 {
1322                     for(int i = 0 ; i < pMP->getRows() ; i++)
1323                     {
1324                         for(int j = 0 ; j < pMP->getCols() ; j++)
1325                         {
1326                             pReturn->setCoef(j, i, pMP->get(i,j)->getCoef());
1327                         }
1328                     }
1329                 }
1330
1331                 result_set(pReturn);
1332             }
1333             else if(execMe.result_get()->isString())
1334             {
1335                 InternalType* pVar  = execMe.result_get();
1336                 String *pS          = pVar->getAs<types::String>();
1337                 String* pReturn     = new String(pS->getCols(), pS->getRows());
1338
1339                 for(int i = 0 ; i < pS->getRows() ; i++)
1340                 {
1341                     for(int j = 0 ; j < pS->getCols() ; j++)
1342                     {
1343                         pReturn->set(j,i, pS->get(i,j));
1344                     }
1345                 }
1346                 result_set(pReturn);
1347             }
1348         }
1349         /** \} */
1350
1351         /** \name Visit Declaration nodes.
1352         ** \{ */
1353         /** \brief Visit Var declarations. */
1354
1355         void visitprivate(const VarDec  &e)
1356         {
1357             /*Create local exec visitor*/
1358             T execMe;
1359             try
1360             {
1361                 /*getting what to assign*/
1362                 e.init_get().accept(execMe);
1363                 result_set(execMe.result_get());
1364                 result_get()->IncreaseRef();
1365             }
1366             catch(ScilabError error)
1367             {
1368                 throw error;
1369             }
1370         }
1371
1372
1373         void visitprivate(const FunctionDec  &e)
1374         {
1375             /*
1376             function foo
1377             endfunction
1378             */
1379             std::list<ast::Var *>::const_iterator       i;
1380
1381             //get input parameters list
1382             std::list<symbol::Symbol> *pVarList = new std::list<symbol::Symbol>();
1383             const ArrayListVar *pListVar = &e.args_get();
1384             for(i = pListVar->vars_get().begin() ; i != pListVar->vars_get().end() ; i++)
1385             {
1386                 pVarList->push_back(static_cast<SimpleVar*>(*i)->name_get());
1387             }
1388
1389             //get output parameters list
1390             std::list<symbol::Symbol> *pRetList = new std::list<symbol::Symbol>();
1391             const ArrayListVar *pListRet = &e.returns_get();
1392             for(i = pListRet->vars_get().begin() ; i != pListRet->vars_get().end() ; i++)
1393             {
1394                 pRetList->push_back(static_cast<SimpleVar*>(*i)->name_get());
1395             }
1396
1397 //            Location* newloc = const_cast<Location*>(&location_get())->clone();
1398             Exp* exp = const_cast<Exp*>(&e.body_get())->clone();
1399             //types::Macro macro(VarList, RetList, (SeqExp&)e.body_get());
1400             types::Macro *pMacro = new types::Macro(e.name_get().name_get(), *pVarList, *pRetList,
1401                 static_cast<SeqExp&>(*exp), L"script");
1402             symbol::Context::getInstance()->AddMacro(pMacro);
1403         }
1404         /** \} */
1405
1406         /** \name Visit Type dedicated Expressions related node.
1407         ** \{ */
1408
1409         void visitprivate(const ListExp &e)
1410         {
1411             T   execMeStart;
1412             T   execMeStep;
1413             T   execMeEnd;
1414
1415             try
1416             {
1417                 e.start_get().accept(execMeStart);
1418                 GenericType* pITStart = static_cast<GenericType*>(execMeStart.result_get());
1419                 if(pITStart->getRows() != 1 || pITStart->getCols() != 1)
1420                 {
1421                     throw 1;
1422                 }
1423
1424
1425                 e.step_get().accept(execMeStep);
1426                 GenericType* pITStep = static_cast<GenericType*>(execMeStep.result_get());
1427                 if(pITStep->getRows() != 1 || pITStep->getCols() != 1)
1428                 {
1429                     throw 2;
1430                 }
1431
1432                 e.end_get().accept(execMeEnd);
1433                 GenericType* pITEnd = static_cast<GenericType*>(execMeEnd.result_get());
1434                 if(pITEnd->getRows() != 1 || pITEnd->getCols() != 1)
1435                 {
1436                     throw 3;
1437                 }
1438
1439                 //check compatibility
1440
1441                 if(execMeStart.result_get()->isInt())
1442                 {//if Step or End are Int too, they must have the same precision
1443                     if(execMeStep.result_get()->isInt())
1444                     {
1445                         if(execMeStep.result_get()->getType() != execMeStart.result_get()->getType())
1446                         {
1447                             throw ScilabError(_W("Undefined operation for the given operands.\n"), 999, e.step_get().location_get());
1448                         }
1449                     }
1450                     else if(execMeStep.result_get()->isPoly())
1451                     {
1452                         throw ScilabError(_W("Undefined operation for the given operands.\n"), 999, e.step_get().location_get());
1453                     }
1454
1455
1456                     if(execMeEnd.result_get()->isInt())
1457                     {
1458                         if(execMeEnd.result_get()->getType() != execMeStart.result_get()->getType())
1459                         {
1460                             throw ScilabError(_W("Undefined operation for the given operands.\n"), 999, e.end_get().location_get());
1461                         }
1462                     }
1463                     else if(execMeEnd.result_get()->isPoly())
1464                     {
1465                             throw ScilabError(_W("Undefined operation for the given operands.\n"), 999, e.end_get().location_get());
1466                     }
1467                 }
1468                 else if(execMeStart.result_get()->isPoly())
1469                 {
1470                     if(execMeStep.result_get()->isInt())
1471                     {
1472                         throw ScilabError(_W("Undefined operation for the given operands.\n"), 999, e.step_get().location_get());
1473                     }
1474
1475                     if(execMeEnd.result_get()->isInt())
1476                     {
1477                         throw ScilabError(_W("Undefined operation for the given operands.\n"), 999, e.end_get().location_get());
1478                     }
1479                 }
1480                 else if(execMeStep.result_get()->isInt())
1481                 {//if End is Int too, they must have the same precision
1482                     if(execMeEnd.result_get()->isInt())
1483                     {
1484                         if(execMeEnd.result_get()->getType() != execMeStep.result_get()->getType())
1485                         {
1486                             throw ScilabError(_W("Undefined operation for the given operands.\n"), 999, e.end_get().location_get());
1487                         }
1488                     }
1489                 }
1490                 else if(execMeStep.result_get()->isPoly())
1491                 {
1492                     if(execMeEnd.result_get()->isInt())
1493                     {
1494                         throw ScilabError(_W("Undefined operation for the given operands.\n"), 999, e.step_get().location_get());
1495                     }
1496                 }
1497
1498                 ImplicitList *pIL       = new ImplicitList(
1499                     execMeStart.result_get(),
1500                     execMeStep.result_get(),
1501                     execMeEnd.result_get());
1502
1503                 result_set(pIL);
1504             }
1505             catch(int iPos)
1506             {
1507                 wchar_t szError[bsiz];
1508                 os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Scalar expected.\n"), L":", iPos);
1509                 throw ScilabError(szError, 999, e.location_get());
1510             }
1511             catch(ScilabError error)
1512             {
1513                 //TODO YaSp : Overloading
1514                 throw error;
1515             }
1516         }
1517         /** \} */
1518
1519         #include "run_AssignExp.hxx"
1520         // This will define
1521         // void visitprivate(const AssignExp  &e)
1522
1523         #include "run_OpExp.hxx"
1524         // This will define
1525         // void visitprivate(const OpExp &e)
1526         // void visitprivate(const LogicalOpExp &e)
1527
1528         #include "run_MatrixExp.hxx"
1529         // This will define
1530         // void visitprivate(const MatrixExp &e)
1531
1532         #include "run_CallExp.hxx"
1533         // This will define
1534         // void visitprivate(const CallExp &e)
1535     };
1536 }
1537
1538 #endif // !AST_RUNVISITOR_HXX