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