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